noterai 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +368 -0
- package/bin/noter.js +218 -0
- package/bin/noter.js.map +1 -0
- package/package.json +73 -0
- package/packages/client/dist/assets/geist-mono-latin-400-normal-CoULgQGM.woff +0 -0
- package/packages/client/dist/assets/geist-mono-latin-400-normal-LC9RFr9I.woff2 +0 -0
- package/packages/client/dist/assets/index-CBiNAMaA.js +264 -0
- package/packages/client/dist/assets/index-u7i5Fle2.css +1 -0
- package/packages/client/dist/assets/space-grotesk-latin-500-normal-CNSSEhBt.woff +0 -0
- package/packages/client/dist/assets/space-grotesk-latin-500-normal-lFbtlQH6.woff2 +0 -0
- package/packages/client/dist/assets/space-grotesk-latin-600-normal-BflQw4A9.woff +0 -0
- package/packages/client/dist/assets/space-grotesk-latin-600-normal-DjKNqYRj.woff2 +0 -0
- package/packages/client/dist/assets/vendor-react-DHeZC_T5.js +17 -0
- package/packages/client/dist/index.html +14 -0
- package/packages/server/dist/adapters/claudeAdapter.d.ts +34 -0
- package/packages/server/dist/adapters/claudeAdapter.d.ts.map +1 -0
- package/packages/server/dist/adapters/claudeAdapter.js +281 -0
- package/packages/server/dist/adapters/claudeAdapter.js.map +1 -0
- package/packages/server/dist/adapters/codexAdapter.d.ts +39 -0
- package/packages/server/dist/adapters/codexAdapter.d.ts.map +1 -0
- package/packages/server/dist/adapters/codexAdapter.js +347 -0
- package/packages/server/dist/adapters/codexAdapter.js.map +1 -0
- package/packages/server/dist/adapters/droidAdapter.d.ts +34 -0
- package/packages/server/dist/adapters/droidAdapter.d.ts.map +1 -0
- package/packages/server/dist/adapters/droidAdapter.js +109 -0
- package/packages/server/dist/adapters/droidAdapter.js.map +1 -0
- package/packages/server/dist/adapters/genericAdapter.d.ts +50 -0
- package/packages/server/dist/adapters/genericAdapter.d.ts.map +1 -0
- package/packages/server/dist/adapters/genericAdapter.js +203 -0
- package/packages/server/dist/adapters/genericAdapter.js.map +1 -0
- package/packages/server/dist/adapters/index.d.ts +7 -0
- package/packages/server/dist/adapters/index.d.ts.map +1 -0
- package/packages/server/dist/adapters/index.js +7 -0
- package/packages/server/dist/adapters/index.js.map +1 -0
- package/packages/server/dist/adapters/opencodeAdapter.d.ts +28 -0
- package/packages/server/dist/adapters/opencodeAdapter.d.ts.map +1 -0
- package/packages/server/dist/adapters/opencodeAdapter.js +265 -0
- package/packages/server/dist/adapters/opencodeAdapter.js.map +1 -0
- package/packages/server/dist/adapters/opencodeSessionManager.d.ts +13 -0
- package/packages/server/dist/adapters/opencodeSessionManager.d.ts.map +1 -0
- package/packages/server/dist/adapters/opencodeSessionManager.js +230 -0
- package/packages/server/dist/adapters/opencodeSessionManager.js.map +1 -0
- package/packages/server/dist/adapters/pathUtils.d.ts +54 -0
- package/packages/server/dist/adapters/pathUtils.d.ts.map +1 -0
- package/packages/server/dist/adapters/pathUtils.js +86 -0
- package/packages/server/dist/adapters/pathUtils.js.map +1 -0
- package/packages/server/dist/adapters/piAdapter.d.ts +34 -0
- package/packages/server/dist/adapters/piAdapter.d.ts.map +1 -0
- package/packages/server/dist/adapters/piAdapter.js +307 -0
- package/packages/server/dist/adapters/piAdapter.js.map +1 -0
- package/packages/server/dist/autoDetect.d.ts +15 -0
- package/packages/server/dist/autoDetect.d.ts.map +1 -0
- package/packages/server/dist/autoDetect.js +102 -0
- package/packages/server/dist/autoDetect.js.map +1 -0
- package/packages/server/dist/config.d.ts +29 -0
- package/packages/server/dist/config.d.ts.map +1 -0
- package/packages/server/dist/config.js +96 -0
- package/packages/server/dist/config.js.map +1 -0
- package/packages/server/dist/eventStore.d.ts +14 -0
- package/packages/server/dist/eventStore.d.ts.map +1 -0
- package/packages/server/dist/eventStore.js +35 -0
- package/packages/server/dist/eventStore.js.map +1 -0
- package/packages/server/dist/hookWatcher.d.ts +24 -0
- package/packages/server/dist/hookWatcher.d.ts.map +1 -0
- package/packages/server/dist/hookWatcher.js +152 -0
- package/packages/server/dist/hookWatcher.js.map +1 -0
- package/packages/server/dist/index.d.ts +58 -0
- package/packages/server/dist/index.d.ts.map +1 -0
- package/packages/server/dist/index.js +527 -0
- package/packages/server/dist/index.js.map +1 -0
- package/packages/server/dist/llm/jsonExtractor.d.ts +39 -0
- package/packages/server/dist/llm/jsonExtractor.d.ts.map +1 -0
- package/packages/server/dist/llm/jsonExtractor.js +83 -0
- package/packages/server/dist/llm/jsonExtractor.js.map +1 -0
- package/packages/server/dist/llm/ollamaCache.d.ts +19 -0
- package/packages/server/dist/llm/ollamaCache.d.ts.map +1 -0
- package/packages/server/dist/llm/ollamaCache.js +31 -0
- package/packages/server/dist/llm/ollamaCache.js.map +1 -0
- package/packages/server/dist/llm/ollamaClient.d.ts +29 -0
- package/packages/server/dist/llm/ollamaClient.d.ts.map +1 -0
- package/packages/server/dist/llm/ollamaClient.js +117 -0
- package/packages/server/dist/llm/ollamaClient.js.map +1 -0
- package/packages/server/dist/llm/ollamaQueue.d.ts +7 -0
- package/packages/server/dist/llm/ollamaQueue.d.ts.map +1 -0
- package/packages/server/dist/llm/ollamaQueue.js +28 -0
- package/packages/server/dist/llm/ollamaQueue.js.map +1 -0
- package/packages/server/dist/llm/promptBuilder.d.ts +8 -0
- package/packages/server/dist/llm/promptBuilder.d.ts.map +1 -0
- package/packages/server/dist/llm/promptBuilder.js +85 -0
- package/packages/server/dist/llm/promptBuilder.js.map +1 -0
- package/packages/server/dist/llm/promptSections.d.ts +64 -0
- package/packages/server/dist/llm/promptSections.d.ts.map +1 -0
- package/packages/server/dist/llm/promptSections.js +128 -0
- package/packages/server/dist/llm/promptSections.js.map +1 -0
- package/packages/server/dist/llm/providerModels.d.ts +14 -0
- package/packages/server/dist/llm/providerModels.d.ts.map +1 -0
- package/packages/server/dist/llm/providerModels.js +67 -0
- package/packages/server/dist/llm/providerModels.js.map +1 -0
- package/packages/server/dist/llm/suggester.d.ts +12 -0
- package/packages/server/dist/llm/suggester.d.ts.map +1 -0
- package/packages/server/dist/llm/suggester.js +263 -0
- package/packages/server/dist/llm/suggester.js.map +1 -0
- package/packages/server/dist/llm/summarizer.d.ts +53 -0
- package/packages/server/dist/llm/summarizer.d.ts.map +1 -0
- package/packages/server/dist/llm/summarizer.js +174 -0
- package/packages/server/dist/llm/summarizer.js.map +1 -0
- package/packages/server/dist/persistence.d.ts +42 -0
- package/packages/server/dist/persistence.d.ts.map +1 -0
- package/packages/server/dist/persistence.js +103 -0
- package/packages/server/dist/persistence.js.map +1 -0
- package/packages/server/dist/repoContext.d.ts +60 -0
- package/packages/server/dist/repoContext.d.ts.map +1 -0
- package/packages/server/dist/repoContext.js +197 -0
- package/packages/server/dist/repoContext.js.map +1 -0
- package/packages/server/dist/routes/blueprint.d.ts +7 -0
- package/packages/server/dist/routes/blueprint.d.ts.map +1 -0
- package/packages/server/dist/routes/blueprint.js +529 -0
- package/packages/server/dist/routes/blueprint.js.map +1 -0
- package/packages/server/dist/routes/config.d.ts +17 -0
- package/packages/server/dist/routes/config.d.ts.map +1 -0
- package/packages/server/dist/routes/config.js +282 -0
- package/packages/server/dist/routes/config.js.map +1 -0
- package/packages/server/dist/routes/lmstudio.d.ts +4 -0
- package/packages/server/dist/routes/lmstudio.d.ts.map +1 -0
- package/packages/server/dist/routes/lmstudio.js +67 -0
- package/packages/server/dist/routes/lmstudio.js.map +1 -0
- package/packages/server/dist/routes/notes.d.ts +5 -0
- package/packages/server/dist/routes/notes.d.ts.map +1 -0
- package/packages/server/dist/routes/notes.js +60 -0
- package/packages/server/dist/routes/notes.js.map +1 -0
- package/packages/server/dist/routes/ollama.d.ts +4 -0
- package/packages/server/dist/routes/ollama.d.ts.map +1 -0
- package/packages/server/dist/routes/ollama.js +207 -0
- package/packages/server/dist/routes/ollama.js.map +1 -0
- package/packages/server/dist/routes/prompt.d.ts +4 -0
- package/packages/server/dist/routes/prompt.d.ts.map +1 -0
- package/packages/server/dist/routes/prompt.js +75 -0
- package/packages/server/dist/routes/prompt.js.map +1 -0
- package/packages/server/dist/routes/refineNotes.d.ts +4 -0
- package/packages/server/dist/routes/refineNotes.d.ts.map +1 -0
- package/packages/server/dist/routes/refineNotes.js +87 -0
- package/packages/server/dist/routes/refineNotes.js.map +1 -0
- package/packages/server/dist/routes/repoContext.d.ts +3 -0
- package/packages/server/dist/routes/repoContext.d.ts.map +1 -0
- package/packages/server/dist/routes/repoContext.js +15 -0
- package/packages/server/dist/routes/repoContext.js.map +1 -0
- package/packages/server/dist/routes/sessions.d.ts +15 -0
- package/packages/server/dist/routes/sessions.d.ts.map +1 -0
- package/packages/server/dist/routes/sessions.js +420 -0
- package/packages/server/dist/routes/sessions.js.map +1 -0
- package/packages/server/dist/routes/summarize.d.ts +6 -0
- package/packages/server/dist/routes/summarize.d.ts.map +1 -0
- package/packages/server/dist/routes/summarize.js +85 -0
- package/packages/server/dist/routes/summarize.js.map +1 -0
- package/packages/server/dist/server.d.ts +2 -0
- package/packages/server/dist/server.d.ts.map +1 -0
- package/packages/server/dist/server.js +6 -0
- package/packages/server/dist/server.js.map +1 -0
- package/packages/server/dist/sessionManager.d.ts +41 -0
- package/packages/server/dist/sessionManager.d.ts.map +1 -0
- package/packages/server/dist/sessionManager.js +493 -0
- package/packages/server/dist/sessionManager.js.map +1 -0
- package/packages/server/dist/sessionScanner.d.ts +22 -0
- package/packages/server/dist/sessionScanner.d.ts.map +1 -0
- package/packages/server/dist/sessionScanner.js +165 -0
- package/packages/server/dist/sessionScanner.js.map +1 -0
- package/packages/server/dist/sessionTitle.d.ts +17 -0
- package/packages/server/dist/sessionTitle.d.ts.map +1 -0
- package/packages/server/dist/sessionTitle.js +321 -0
- package/packages/server/dist/sessionTitle.js.map +1 -0
- package/packages/server/dist/stateManager.d.ts +38 -0
- package/packages/server/dist/stateManager.d.ts.map +1 -0
- package/packages/server/dist/stateManager.js +83 -0
- package/packages/server/dist/stateManager.js.map +1 -0
- package/packages/server/dist/wsServer.d.ts +27 -0
- package/packages/server/dist/wsServer.d.ts.map +1 -0
- package/packages/server/dist/wsServer.js +144 -0
- package/packages/server/dist/wsServer.js.map +1 -0
- package/packages/shared/dist/index.d.ts +3 -0
- package/packages/shared/dist/index.d.ts.map +1 -0
- package/packages/shared/dist/index.js +3 -0
- package/packages/shared/dist/index.js.map +1 -0
- package/packages/shared/dist/llm/mambaDetect.d.ts +84 -0
- package/packages/shared/dist/llm/mambaDetect.d.ts.map +1 -0
- package/packages/shared/dist/llm/mambaDetect.js +205 -0
- package/packages/shared/dist/llm/mambaDetect.js.map +1 -0
- package/packages/shared/dist/types.d.ts +184 -0
- package/packages/shared/dist/types.d.ts.map +1 -0
- package/packages/shared/dist/types.js +2 -0
- package/packages/shared/dist/types.js.map +1 -0
- package/scripts/postbuild.js +70 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promptSections.js","sourceRoot":"","sources":["../../src/llm/promptSections.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared provider model registry and model resolution.
|
|
3
|
+
* Eliminates duplication between promptBuilder.ts and blueprint.ts.
|
|
4
|
+
*/
|
|
5
|
+
import type { LanguageModel } from 'ai';
|
|
6
|
+
import type { AppConfig } from '../config.js';
|
|
7
|
+
export declare const PROVIDER_MODELS: Record<string, {
|
|
8
|
+
modelId: string;
|
|
9
|
+
requiresKey: boolean;
|
|
10
|
+
envKey: string;
|
|
11
|
+
}>;
|
|
12
|
+
export declare function getModel(provider: string, config: AppConfig): LanguageModel;
|
|
13
|
+
export declare function getModelName(provider: string, config: AppConfig): string;
|
|
14
|
+
//# sourceMappingURL=providerModels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providerModels.d.ts","sourceRoot":"","sources":["../../src/llm/providerModels.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG9C,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAOrG,CAAC;AAEF,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,aAAa,CAmC3E;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,MAAM,CAQxE"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared provider model registry and model resolution.
|
|
3
|
+
* Eliminates duplication between promptBuilder.ts and blueprint.ts.
|
|
4
|
+
*/
|
|
5
|
+
import { anthropic } from '@ai-sdk/anthropic';
|
|
6
|
+
import { openai, createOpenAI } from '@ai-sdk/openai';
|
|
7
|
+
import { google } from '@ai-sdk/google';
|
|
8
|
+
import { getOllamaProvider } from './ollamaCache.js';
|
|
9
|
+
import { MissingApiKeyError } from './promptBuilder.js';
|
|
10
|
+
export const PROVIDER_MODELS = {
|
|
11
|
+
anthropic: { modelId: 'claude-sonnet-4-20250514', requiresKey: true, envKey: 'ANTHROPIC_API_KEY' },
|
|
12
|
+
openai: { modelId: 'gpt-4o', requiresKey: true, envKey: 'OPENAI_API_KEY' },
|
|
13
|
+
gemini: { modelId: 'gemini-2.5-flash', requiresKey: true, envKey: 'GEMINI_API_KEY' },
|
|
14
|
+
ollama: { modelId: '', requiresKey: false, envKey: '' },
|
|
15
|
+
'lm-studio': { modelId: '', requiresKey: false, envKey: '' },
|
|
16
|
+
custom: { modelId: '', requiresKey: false, envKey: '' },
|
|
17
|
+
};
|
|
18
|
+
export function getModel(provider, config) {
|
|
19
|
+
switch (provider) {
|
|
20
|
+
case 'anthropic': {
|
|
21
|
+
if (!config.anthropicApiKey)
|
|
22
|
+
throw new MissingApiKeyError('Anthropic');
|
|
23
|
+
return anthropic(PROVIDER_MODELS.anthropic.modelId);
|
|
24
|
+
}
|
|
25
|
+
case 'openai': {
|
|
26
|
+
if (!config.openaiApiKey)
|
|
27
|
+
throw new MissingApiKeyError('OpenAI');
|
|
28
|
+
return openai(PROVIDER_MODELS.openai.modelId);
|
|
29
|
+
}
|
|
30
|
+
case 'gemini': {
|
|
31
|
+
if (!config.geminiApiKey)
|
|
32
|
+
throw new MissingApiKeyError('Gemini');
|
|
33
|
+
return google(PROVIDER_MODELS.gemini.modelId);
|
|
34
|
+
}
|
|
35
|
+
case 'lm-studio': {
|
|
36
|
+
const lmStudio = createOpenAI({
|
|
37
|
+
baseURL: config.lmStudioBaseUrl || 'http://localhost:1234/v1',
|
|
38
|
+
apiKey: 'lm-studio',
|
|
39
|
+
});
|
|
40
|
+
return lmStudio(config.lmStudioModel || 'default');
|
|
41
|
+
}
|
|
42
|
+
case 'custom': {
|
|
43
|
+
if (!config.customProviderBaseUrl)
|
|
44
|
+
throw new MissingApiKeyError('Custom Provider');
|
|
45
|
+
const customProvider = createOpenAI({
|
|
46
|
+
baseURL: config.customProviderBaseUrl,
|
|
47
|
+
apiKey: config.customProviderApiKey || 'none',
|
|
48
|
+
});
|
|
49
|
+
return customProvider(config.customProviderModel || 'default');
|
|
50
|
+
}
|
|
51
|
+
case 'ollama':
|
|
52
|
+
default: {
|
|
53
|
+
const ollamaProvider = getOllamaProvider({ baseURL: config.ollamaBaseUrl });
|
|
54
|
+
return ollamaProvider(config.ollamaModel);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export function getModelName(provider, config) {
|
|
59
|
+
switch (provider) {
|
|
60
|
+
case 'anthropic': return PROVIDER_MODELS.anthropic.modelId;
|
|
61
|
+
case 'openai': return PROVIDER_MODELS.openai.modelId;
|
|
62
|
+
case 'gemini': return PROVIDER_MODELS.gemini.modelId;
|
|
63
|
+
case 'ollama': return config.ollamaModel || '';
|
|
64
|
+
default: return config.ollamaModel || '';
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=providerModels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providerModels.js","sourceRoot":"","sources":["../../src/llm/providerModels.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AppConfig } from '../config.js';
|
|
2
|
+
import type { ContextSummary, HumanNotes, TaskOrigin, TaskSuggestion } from '../../../shared/dist/index.js';
|
|
3
|
+
/** Deterministic ID from title — same title always produces same ID */
|
|
4
|
+
export declare function stableTaskId(title: string): string;
|
|
5
|
+
export declare function suggest(summary: ContextSummary | null, notes: HumanNotes, config: AppConfig, origin?: TaskOrigin): Promise<TaskSuggestion[]>;
|
|
6
|
+
/** Merge newly generated suggestions into existing list.
|
|
7
|
+
* - Context-generated tasks always preserved
|
|
8
|
+
* - Pinned tasks always preserved (checked via pinnedIds set)
|
|
9
|
+
* - Unpinned notes-origin tasks replaced by new notes-origin suggestions
|
|
10
|
+
* - Deduplication by stable task ID */
|
|
11
|
+
export declare function mergeSuggestions(existing: TaskSuggestion[], incoming: TaskSuggestion[], pinnedIds: Set<string>): TaskSuggestion[];
|
|
12
|
+
//# sourceMappingURL=suggester.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggester.d.ts","sourceRoot":"","sources":["../../src/llm/suggester.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAiH5F,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED,wBAAsB,OAAO,CAC3B,OAAO,EAAE,cAAc,GAAG,IAAI,EAC9B,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,SAAS,EACjB,MAAM,CAAC,EAAE,UAAU,GAClB,OAAO,CAAC,cAAc,EAAE,CAAC,CA+I3B;AAED;;;;wCAIwC;AACxC,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,cAAc,EAAE,EAC1B,QAAQ,EAAE,cAAc,EAAE,EAC1B,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,GACrB,cAAc,EAAE,CAsBlB"}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { SUGGESTER_QUEUE } from './ollamaQueue.js';
|
|
3
|
+
import { ollamaClient } from './ollamaClient.js';
|
|
4
|
+
import { buildRepoPromptSections, PLACEHOLDER_PATTERNS } from './promptSections.js';
|
|
5
|
+
const TaskSuggestionSchema = z.object({
|
|
6
|
+
suggestions: z.array(z.object({
|
|
7
|
+
id: z.string(),
|
|
8
|
+
title: z.string(),
|
|
9
|
+
rationale: z.string(),
|
|
10
|
+
priority: z.enum(['high', 'medium', 'low']),
|
|
11
|
+
conflictsWithNotes: z.boolean(),
|
|
12
|
+
conflictExplanation: z.string().optional(),
|
|
13
|
+
affectedFiles: z.array(z.string()).optional(),
|
|
14
|
+
suggestedToolCalls: z.array(z.string()).optional(),
|
|
15
|
+
})),
|
|
16
|
+
});
|
|
17
|
+
/** Minimal JSON schema — Ollama format param carries the full schema already */
|
|
18
|
+
const TASK_SUGGESTION_JSON_FORMAT = {
|
|
19
|
+
type: 'object',
|
|
20
|
+
properties: {
|
|
21
|
+
suggestions: {
|
|
22
|
+
type: 'array',
|
|
23
|
+
items: {
|
|
24
|
+
type: 'object',
|
|
25
|
+
properties: {
|
|
26
|
+
id: { type: 'string', description: 'Deterministic hash — will be replaced by server. Send any string.' },
|
|
27
|
+
title: { type: 'string', description: 'Human-readable action sentence. e.g. "Fix auth timeout in auth.ts". Must start with a verb and contain spaces. NOT an ID, NOT gibberish.' },
|
|
28
|
+
rationale: { type: 'string', description: 'WHY this task matters given the context. At least 20 characters.' },
|
|
29
|
+
priority: { type: 'string', enum: ['high', 'medium', 'low'] },
|
|
30
|
+
conflictsWithNotes: { type: 'boolean' },
|
|
31
|
+
conflictExplanation: { type: 'string' },
|
|
32
|
+
affectedFiles: { type: 'array', items: { type: 'string' } },
|
|
33
|
+
suggestedToolCalls: { type: 'array', items: { type: 'string' } },
|
|
34
|
+
},
|
|
35
|
+
required: ['id', 'title', 'rationale', 'priority', 'conflictsWithNotes'],
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
required: ['suggestions'],
|
|
40
|
+
};
|
|
41
|
+
/** Shared suggestion rules — compact, no duplication */
|
|
42
|
+
const SUGGESTION_RULES = `Rules:
|
|
43
|
+
1. Ground every task in specific notes/context details. Generic tasks rejected.
|
|
44
|
+
2. Most relevant task first.
|
|
45
|
+
3. Title = specific action sentence starting with a verb (e.g. "Fix auth timeout in auth.ts", "Add rate limiting to API endpoints"). NOT an ID, NOT a slug, NOT gibberish like "task5ktv9f".
|
|
46
|
+
4. Rationale = WHY this matters given context. At least 20 characters.
|
|
47
|
+
5. Include affectedFiles array with specific files
|
|
48
|
+
6. May include suggestedToolCalls (e.g., ["edit_file", "run_tests"])
|
|
49
|
+
7. No generic placeholders. No ALL_CAPS titles. No ID-like strings.
|
|
50
|
+
8. Prefer fewer high-confidence tasks over many generic ones
|
|
51
|
+
9. If tests failing → prioritize fixing
|
|
52
|
+
10. If errors → prioritize root cause
|
|
53
|
+
11. Use field "rationale" (NOT "description")
|
|
54
|
+
12. Set conflictsWithNotes=true + conflictExplanation if task conflicts with notes
|
|
55
|
+
13. Title must be a human-readable sentence with spaces and at least one verb. Reject gibberish, IDs, slugs, camelCase identifiers.
|
|
56
|
+
|
|
57
|
+
Output: ONLY valid JSON. No markdown, no code blocks.`;
|
|
58
|
+
function buildSuggestionPrompt(summary, notes) {
|
|
59
|
+
const repo = buildRepoPromptSections();
|
|
60
|
+
const toolsUsed = summary.toolsUsed;
|
|
61
|
+
const errorCount = summary.errorCount;
|
|
62
|
+
const testStatus = summary.testStatus;
|
|
63
|
+
return `Analyze dev notes + agent context → generate task suggestions.
|
|
64
|
+
|
|
65
|
+
## Dev Notes (HIGHEST PRIORITY)
|
|
66
|
+
${notes.content}
|
|
67
|
+
${repo.instructions}
|
|
68
|
+
## Agent Context
|
|
69
|
+
- Activity: ${summary.whatIsHappening}
|
|
70
|
+
- Files: ${summary.filesChanged.join(', ')}
|
|
71
|
+
- Goal: ${summary.currentGoal}
|
|
72
|
+
- Blockers: ${summary.blockers.join(', ') || 'None'}
|
|
73
|
+
- Events: ${summary.rawEventCount}
|
|
74
|
+
${repo.root}
|
|
75
|
+
${toolsUsed ? `- Tools: ${toolsUsed.join(', ')}` : ''}
|
|
76
|
+
${errorCount !== undefined ? `- Errors: ${errorCount}` : ''}
|
|
77
|
+
${testStatus ? `- Tests: ${testStatus}` : ''}
|
|
78
|
+
|
|
79
|
+
${SUGGESTION_RULES}`;
|
|
80
|
+
}
|
|
81
|
+
function buildSuggestionPromptFromNotes(notes) {
|
|
82
|
+
const repo = buildRepoPromptSections();
|
|
83
|
+
return `Generate task suggestions from dev notes.
|
|
84
|
+
|
|
85
|
+
## Dev Notes
|
|
86
|
+
${notes.content || '(No notes)'}
|
|
87
|
+
${repo.instructions}
|
|
88
|
+
${repo.root}
|
|
89
|
+
|
|
90
|
+
Rules:
|
|
91
|
+
1. Ground every task in specific notes details. Generic tasks rejected.
|
|
92
|
+
2. Most relevant task first.
|
|
93
|
+
3. Title = specific action sentence starting with a verb from notes (e.g. "Add input validation to login form"). NOT an ID or gibberish like "task5ktv9f".
|
|
94
|
+
4. Rationale = why it matters per notes. At least 20 characters.
|
|
95
|
+
5. No generic placeholders. No ALL_CAPS titles. No ID-like strings.
|
|
96
|
+
6. Use field "rationale" (NOT "description")
|
|
97
|
+
7. Include files/components from notes in affectedFiles
|
|
98
|
+
8. Title must contain spaces and at least one verb.
|
|
99
|
+
|
|
100
|
+
Output: ONLY valid JSON. No markdown, no code blocks.`;
|
|
101
|
+
}
|
|
102
|
+
/** Deterministic ID from title — same title always produces same ID */
|
|
103
|
+
export function stableTaskId(title) {
|
|
104
|
+
let hash = 0;
|
|
105
|
+
for (let i = 0; i < title.length; i++) {
|
|
106
|
+
hash = ((hash << 5) - hash + title.charCodeAt(i)) | 0;
|
|
107
|
+
}
|
|
108
|
+
return `task-${Math.abs(hash).toString(36)}`;
|
|
109
|
+
}
|
|
110
|
+
export async function suggest(summary, notes, config, origin) {
|
|
111
|
+
const promptText = summary
|
|
112
|
+
? buildSuggestionPrompt(summary, notes)
|
|
113
|
+
: buildSuggestionPromptFromNotes(notes);
|
|
114
|
+
const response = await SUGGESTER_QUEUE.enqueue('suggester', async () => {
|
|
115
|
+
return await ollamaClient(promptText, TASK_SUGGESTION_JSON_FORMAT, config);
|
|
116
|
+
});
|
|
117
|
+
// FIX: Handle models that return raw array instead of {suggestions: [...]}
|
|
118
|
+
// Also handle models that wrap in {output: {suggestions: [...]}} or other shapes
|
|
119
|
+
let suggestionsArray;
|
|
120
|
+
if (Array.isArray(response)) {
|
|
121
|
+
suggestionsArray = response;
|
|
122
|
+
}
|
|
123
|
+
else if (response && Array.isArray(response.suggestions)) {
|
|
124
|
+
suggestionsArray = response.suggestions;
|
|
125
|
+
}
|
|
126
|
+
else if (response && typeof response === 'object') {
|
|
127
|
+
// Defensive: search for the first array-valued key in the response
|
|
128
|
+
const obj = response;
|
|
129
|
+
const arrayKey = Object.keys(obj).find(k => Array.isArray(obj[k]));
|
|
130
|
+
if (arrayKey) {
|
|
131
|
+
suggestionsArray = obj[arrayKey];
|
|
132
|
+
console.error(`[suggester] LLM returned unexpected shape, extracted array from key "${arrayKey}"`);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
console.error('[suggester] LLM response shape unexpected:', JSON.stringify(response).slice(0, 200));
|
|
136
|
+
throw new Error('Invalid response from LLM: suggestions must be an array');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
throw new Error('Invalid response from LLM: suggestions must be an array');
|
|
141
|
+
}
|
|
142
|
+
// FIX: Validation gate - filter malformed or placeholder tasks
|
|
143
|
+
const VALIDATED_SUGGESTIONS = [];
|
|
144
|
+
for (const rawSuggestion of suggestionsArray) {
|
|
145
|
+
// FIX: Normalize common schema mismatches from LLM output
|
|
146
|
+
const suggestion = typeof rawSuggestion === 'object' && rawSuggestion !== null
|
|
147
|
+
? { ...rawSuggestion }
|
|
148
|
+
: {};
|
|
149
|
+
// FIX: Normalize 'description' → 'rationale' for models that return the wrong field name
|
|
150
|
+
if (typeof suggestion.description === 'string' && !suggestion.rationale) {
|
|
151
|
+
suggestion.rationale = suggestion.description;
|
|
152
|
+
delete suggestion.description;
|
|
153
|
+
}
|
|
154
|
+
// Normalize id to string
|
|
155
|
+
if (typeof suggestion.id === 'number') {
|
|
156
|
+
suggestion.id = String(suggestion.id);
|
|
157
|
+
}
|
|
158
|
+
// FIX: Default priority to 'medium' when missing, normalize to lowercase enum
|
|
159
|
+
if (typeof suggestion.priority !== 'string' || !suggestion.priority) {
|
|
160
|
+
suggestion.priority = 'medium';
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
const normalizedPriority = suggestion.priority.toLowerCase().trim();
|
|
164
|
+
if (['high', 'medium', 'low'].includes(normalizedPriority)) {
|
|
165
|
+
suggestion.priority = normalizedPriority;
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
suggestion.priority = 'medium';
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// Normalize conflictsWithNotes to boolean
|
|
172
|
+
if (typeof suggestion.conflictsWithNotes !== 'boolean') {
|
|
173
|
+
const conflictsValue = String(suggestion.conflictsWithNotes).toLowerCase().trim();
|
|
174
|
+
suggestion.conflictsWithNotes = conflictsValue === 'true' || conflictsValue === 'yes' || conflictsValue === '1';
|
|
175
|
+
}
|
|
176
|
+
// FIX: Check required fields exist and are correct types
|
|
177
|
+
// Generate deterministic ID from title so tasks keep same ID across regenerations
|
|
178
|
+
const title = String(suggestion.title ?? '');
|
|
179
|
+
let id = String(suggestion.id ?? '');
|
|
180
|
+
if (!title) {
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
// Always derive ID from title for stability — ignore LLM-provided IDs
|
|
184
|
+
id = stableTaskId(title);
|
|
185
|
+
const rationale = String(suggestion.rationale ?? '');
|
|
186
|
+
const priority = String(suggestion.priority ?? '');
|
|
187
|
+
const conflictsWithNotes = Boolean(suggestion.conflictsWithNotes);
|
|
188
|
+
if (!title || !rationale || !priority) {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (title.length < 10) {
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
if (rationale.length < 20) {
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
const IS_PLACEHOLDER = PLACEHOLDER_PATTERNS.some(pattern => pattern.test(title));
|
|
198
|
+
if (IS_PLACEHOLDER) {
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
// Title must contain at least one space — single-word titles are IDs/slugs/gibberish
|
|
202
|
+
if (!title.includes(' ')) {
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
// Build normalized TaskSuggestion
|
|
206
|
+
const normalizedSuggestion = {
|
|
207
|
+
id,
|
|
208
|
+
title,
|
|
209
|
+
rationale,
|
|
210
|
+
priority: priority,
|
|
211
|
+
conflictsWithNotes,
|
|
212
|
+
origin: origin ?? (summary ? 'context' : 'notes'),
|
|
213
|
+
};
|
|
214
|
+
// FIX: Auto-fill conflictExplanation if missing
|
|
215
|
+
if (conflictsWithNotes && !suggestion.conflictExplanation) {
|
|
216
|
+
normalizedSuggestion.conflictExplanation = 'Task conflicts with developer notes';
|
|
217
|
+
}
|
|
218
|
+
else if (suggestion.conflictExplanation) {
|
|
219
|
+
normalizedSuggestion.conflictExplanation = String(suggestion.conflictExplanation);
|
|
220
|
+
}
|
|
221
|
+
// Normalize optional fields
|
|
222
|
+
if (suggestion.affectedFiles) {
|
|
223
|
+
if (Array.isArray(suggestion.affectedFiles)) {
|
|
224
|
+
normalizedSuggestion.affectedFiles = suggestion.affectedFiles
|
|
225
|
+
.filter((f) => typeof f === 'string');
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (suggestion.suggestedToolCalls) {
|
|
229
|
+
if (Array.isArray(suggestion.suggestedToolCalls)) {
|
|
230
|
+
normalizedSuggestion.suggestedToolCalls = suggestion.suggestedToolCalls
|
|
231
|
+
.filter((t) => typeof t === 'string');
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
VALIDATED_SUGGESTIONS.push(normalizedSuggestion);
|
|
235
|
+
}
|
|
236
|
+
return VALIDATED_SUGGESTIONS;
|
|
237
|
+
}
|
|
238
|
+
/** Merge newly generated suggestions into existing list.
|
|
239
|
+
* - Context-generated tasks always preserved
|
|
240
|
+
* - Pinned tasks always preserved (checked via pinnedIds set)
|
|
241
|
+
* - Unpinned notes-origin tasks replaced by new notes-origin suggestions
|
|
242
|
+
* - Deduplication by stable task ID */
|
|
243
|
+
export function mergeSuggestions(existing, incoming, pinnedIds) {
|
|
244
|
+
// 1. Preserve all context-origin tasks from existing
|
|
245
|
+
const preserved = existing.filter(s => s.origin === 'context');
|
|
246
|
+
// 2. Preserve pinned tasks from existing (regardless of origin)
|
|
247
|
+
const preservedIds = new Set(preserved.map(s => s.id));
|
|
248
|
+
for (const s of existing) {
|
|
249
|
+
if (pinnedIds.has(s.id) && !preservedIds.has(s.id)) {
|
|
250
|
+
preserved.push(s);
|
|
251
|
+
preservedIds.add(s.id);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// 3. Add incoming tasks, skipping duplicates by ID
|
|
255
|
+
for (const s of incoming) {
|
|
256
|
+
if (!preservedIds.has(s.id)) {
|
|
257
|
+
preserved.push(s);
|
|
258
|
+
preservedIds.add(s.id);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return preserved;
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=suggester.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggester.js","sourceRoot":"","sources":["../../src/llm/suggester.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { AppConfig } from '../config.js';
|
|
2
|
+
import type { ContextSummary as ContextSummaryType } from '../../../shared/dist/index.js';
|
|
3
|
+
import type { AgentEvent } from '../../../shared/dist/index.js';
|
|
4
|
+
import type { WsServerManager } from '../wsServer.js';
|
|
5
|
+
import type { EventStore } from '../eventStore.js';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
export declare const ContextSummarySchema: z.ZodObject<{
|
|
8
|
+
id: z.ZodString;
|
|
9
|
+
generatedAt: z.ZodNumber;
|
|
10
|
+
whatIsHappening: z.ZodString;
|
|
11
|
+
filesChanged: z.ZodArray<z.ZodString, "many">;
|
|
12
|
+
currentGoal: z.ZodString;
|
|
13
|
+
blockers: z.ZodArray<z.ZodString, "many">;
|
|
14
|
+
rawEventCount: z.ZodNumber;
|
|
15
|
+
toolsUsed: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
16
|
+
errorCount: z.ZodOptional<z.ZodNumber>;
|
|
17
|
+
testStatus: z.ZodOptional<z.ZodEnum<["passing", "failing", "unknown"]>>;
|
|
18
|
+
lastActivityAt: z.ZodOptional<z.ZodNumber>;
|
|
19
|
+
}, "strip", z.ZodTypeAny, {
|
|
20
|
+
id: string;
|
|
21
|
+
generatedAt: number;
|
|
22
|
+
whatIsHappening: string;
|
|
23
|
+
filesChanged: string[];
|
|
24
|
+
currentGoal: string;
|
|
25
|
+
blockers: string[];
|
|
26
|
+
rawEventCount: number;
|
|
27
|
+
toolsUsed?: string[] | undefined;
|
|
28
|
+
errorCount?: number | undefined;
|
|
29
|
+
testStatus?: "unknown" | "passing" | "failing" | undefined;
|
|
30
|
+
lastActivityAt?: number | undefined;
|
|
31
|
+
}, {
|
|
32
|
+
id: string;
|
|
33
|
+
generatedAt: number;
|
|
34
|
+
whatIsHappening: string;
|
|
35
|
+
filesChanged: string[];
|
|
36
|
+
currentGoal: string;
|
|
37
|
+
blockers: string[];
|
|
38
|
+
rawEventCount: number;
|
|
39
|
+
toolsUsed?: string[] | undefined;
|
|
40
|
+
errorCount?: number | undefined;
|
|
41
|
+
testStatus?: "unknown" | "passing" | "failing" | undefined;
|
|
42
|
+
lastActivityAt?: number | undefined;
|
|
43
|
+
}>;
|
|
44
|
+
export interface Summarizer {
|
|
45
|
+
handleEvent(event: AgentEvent): void;
|
|
46
|
+
triggerSummarization(): Promise<ContextSummaryType | null>;
|
|
47
|
+
/** Reset internal counters/flags when switching sessions so stale state
|
|
48
|
+
* from the previous session does not leak into the new one. */
|
|
49
|
+
resetForSessionSwitch(): void;
|
|
50
|
+
}
|
|
51
|
+
export declare function createSummarizer(config: AppConfig, ws: WsServerManager, eventStore: EventStore): Summarizer;
|
|
52
|
+
export declare function buildSummarizationPrompt(events: AgentEvent[]): string;
|
|
53
|
+
//# sourceMappingURL=summarizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summarizer.d.ts","sourceRoot":"","sources":["../../src/llm/summarizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,IAAI,kBAAkB,EAAc,MAAM,eAAe,CAAC;AACtF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAY/B,CAAC;AAqBH,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACrC,oBAAoB,IAAI,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAC3D;oEACgE;IAChE,qBAAqB,IAAI,IAAI,CAAC;CAC/B;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,GAAG,UAAU,CA6G3G;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAuCrE"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { stateManager } from '../stateManager.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { INFERENCE_QUEUE } from './ollamaQueue.js';
|
|
4
|
+
import { ollamaClient } from './ollamaClient.js';
|
|
5
|
+
import { buildRepoPromptSections, formatEventCompact, TOKEN_BUDGETS, estimateTokens, hasMeaningfulSummaryContent } from './promptSections.js';
|
|
6
|
+
import { suggest } from './suggester.js';
|
|
7
|
+
import { mergeSuggestions } from './suggester.js';
|
|
8
|
+
import { loadPinnedTaskIds, saveSuggestions } from '../persistence.js';
|
|
9
|
+
export const ContextSummarySchema = z.object({
|
|
10
|
+
id: z.string(),
|
|
11
|
+
generatedAt: z.number(),
|
|
12
|
+
whatIsHappening: z.string(),
|
|
13
|
+
filesChanged: z.array(z.string()),
|
|
14
|
+
currentGoal: z.string(),
|
|
15
|
+
blockers: z.array(z.string()),
|
|
16
|
+
rawEventCount: z.number(),
|
|
17
|
+
toolsUsed: z.array(z.string()).optional(),
|
|
18
|
+
errorCount: z.number().optional(),
|
|
19
|
+
testStatus: z.enum(['passing', 'failing', 'unknown']).optional(),
|
|
20
|
+
lastActivityAt: z.number().optional(),
|
|
21
|
+
});
|
|
22
|
+
/** Minimal JSON schema for format param — no need to duplicate in prompt */
|
|
23
|
+
const CONTEXT_SUMMARY_JSON_FORMAT = {
|
|
24
|
+
type: 'object',
|
|
25
|
+
properties: {
|
|
26
|
+
id: { type: 'string' },
|
|
27
|
+
generatedAt: { type: 'number' },
|
|
28
|
+
whatIsHappening: { type: 'string' },
|
|
29
|
+
filesChanged: { type: 'array', items: { type: 'string' } },
|
|
30
|
+
currentGoal: { type: 'string' },
|
|
31
|
+
blockers: { type: 'array', items: { type: 'string' } },
|
|
32
|
+
rawEventCount: { type: 'number' },
|
|
33
|
+
toolsUsed: { type: 'array', items: { type: 'string' } },
|
|
34
|
+
errorCount: { type: 'number' },
|
|
35
|
+
testStatus: { type: 'string', enum: ['passing', 'failing', 'unknown'] },
|
|
36
|
+
lastActivityAt: { type: 'number' },
|
|
37
|
+
},
|
|
38
|
+
required: ['id', 'generatedAt', 'whatIsHappening', 'filesChanged', 'currentGoal', 'blockers', 'rawEventCount'],
|
|
39
|
+
};
|
|
40
|
+
export function createSummarizer(config, ws, eventStore) {
|
|
41
|
+
let eventsSinceLastSummary = 0;
|
|
42
|
+
const EVENT_THRESHOLD = 10;
|
|
43
|
+
/**
|
|
44
|
+
* Run context-based task generation as a result of a newly committed summary.
|
|
45
|
+
* - Only triggers when this is the FIRST real summary in the session.
|
|
46
|
+
* - Reuses the existing merge logic so context-generated tasks persist on later regeneration.
|
|
47
|
+
* - Replay-safe: if the first-summary task trigger already ran in this process, it does not re-run.
|
|
48
|
+
*/
|
|
49
|
+
let firstSummaryContextTaskGenTriggered = false;
|
|
50
|
+
async function runFirstSummaryContextTaskGen(summary) {
|
|
51
|
+
if (firstSummaryContextTaskGenTriggered)
|
|
52
|
+
return;
|
|
53
|
+
firstSummaryContextTaskGenTriggered = true;
|
|
54
|
+
try {
|
|
55
|
+
const notes = stateManager.getNotes() ?? { content: '', updatedAt: Date.now() };
|
|
56
|
+
// FIX: Broadcast start indicator so SUGGESTED_TASK panel can show GENERATING TASK…
|
|
57
|
+
ws.broadcast({ type: 'suggestions-status', payload: { generating: true, reason: 'first-summary' } });
|
|
58
|
+
const fresh = await suggest(summary, notes, config, 'context');
|
|
59
|
+
const existing = stateManager.getSuggestions();
|
|
60
|
+
const pinnedIds = new Set(loadPinnedTaskIds());
|
|
61
|
+
const merged = mergeSuggestions(existing, fresh, pinnedIds);
|
|
62
|
+
stateManager.setSuggestions(merged);
|
|
63
|
+
saveSuggestions(merged);
|
|
64
|
+
ws.broadcast({ type: 'suggestions', payload: merged });
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
// FIX: Errors are logged but never propagate — first-summary task gen is opportunistic
|
|
68
|
+
console.error('[Summarizer] First-summary context task generation failed:', error instanceof Error ? error.message : error);
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
ws.broadcast({ type: 'suggestions-status', payload: { generating: false, reason: 'first-summary' } });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async function runSummarization() {
|
|
75
|
+
try {
|
|
76
|
+
const budget = TOKEN_BUDGETS.summarizer;
|
|
77
|
+
const events = eventStore.getLast(budget.maxEvents);
|
|
78
|
+
const promptText = buildSummarizationPrompt(events);
|
|
79
|
+
// Token budget check — log warning if prompt exceeds budget
|
|
80
|
+
const estTokens = estimateTokens(promptText);
|
|
81
|
+
if (estTokens > budget.maxTotalChars / 3.5) {
|
|
82
|
+
console.error(`[Summarizer] Prompt ~${estTokens} tokens exceeds budget. Consider reducing event count.`);
|
|
83
|
+
}
|
|
84
|
+
const summary = await INFERENCE_QUEUE.enqueue('summarizer', async () => {
|
|
85
|
+
return await ollamaClient(promptText, CONTEXT_SUMMARY_JSON_FORMAT, config);
|
|
86
|
+
});
|
|
87
|
+
// FIX: Gate summary-state replacement on meaningful content.
|
|
88
|
+
// Preserve previous summary/status if the LLM produced a placeholder
|
|
89
|
+
// or empty payload — never let streamed transient/empty content wipe
|
|
90
|
+
// a valid existing summary.
|
|
91
|
+
if (!hasMeaningfulSummaryContent(summary)) {
|
|
92
|
+
console.error('[Summarizer] Discarding placeholder/empty summary — keeping previous state');
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
const previousSummary = stateManager.getSummary();
|
|
96
|
+
const isFirstSummary = previousSummary === null;
|
|
97
|
+
stateManager.setSummary(summary);
|
|
98
|
+
ws.broadcast({ type: 'summary', payload: summary });
|
|
99
|
+
eventsSinceLastSummary = 0;
|
|
100
|
+
// FIX: On the first real summary, kick off context-based task generation
|
|
101
|
+
// so the SUGGESTED_TASK panel is populated without requiring a notes save.
|
|
102
|
+
if (isFirstSummary) {
|
|
103
|
+
void runFirstSummaryContextTaskGen(summary);
|
|
104
|
+
}
|
|
105
|
+
return summary;
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
console.error('[Summarizer] Error during summarization:', error);
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function shouldTriggerSummarization(eventType) {
|
|
113
|
+
return eventType === 'session.idle' || eventType === 'stop';
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
handleEvent(event) {
|
|
117
|
+
if (shouldTriggerSummarization(event.type)) {
|
|
118
|
+
runSummarization();
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (event.type === 'tool.after' || event.type === 'tool.before') {
|
|
122
|
+
eventsSinceLastSummary++;
|
|
123
|
+
if (eventsSinceLastSummary >= EVENT_THRESHOLD) {
|
|
124
|
+
runSummarization();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
triggerSummarization() {
|
|
129
|
+
return runSummarization();
|
|
130
|
+
},
|
|
131
|
+
resetForSessionSwitch() {
|
|
132
|
+
eventsSinceLastSummary = 0;
|
|
133
|
+
firstSummaryContextTaskGenTriggered = false;
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
export function buildSummarizationPrompt(events) {
|
|
138
|
+
const budget = TOKEN_BUDGETS.summarizer;
|
|
139
|
+
const repo = buildRepoPromptSections();
|
|
140
|
+
// Compact event formatting with total cap
|
|
141
|
+
let eventDescriptions = events
|
|
142
|
+
.map(e => formatEventCompact(e))
|
|
143
|
+
.join('\n');
|
|
144
|
+
// Enforce total character cap
|
|
145
|
+
if (eventDescriptions.length > budget.maxTotalChars) {
|
|
146
|
+
// Truncate from the beginning (keep most recent events)
|
|
147
|
+
eventDescriptions = eventDescriptions.slice(eventDescriptions.length - budget.maxTotalChars);
|
|
148
|
+
// Find first newline to avoid splitting mid-event
|
|
149
|
+
const firstNl = eventDescriptions.indexOf('\n');
|
|
150
|
+
if (firstNl > 0)
|
|
151
|
+
eventDescriptions = eventDescriptions.slice(firstNl + 1);
|
|
152
|
+
}
|
|
153
|
+
// Compute metadata inline from events (no separate "Session Metadata" section)
|
|
154
|
+
const uniqueTools = [...new Set(events.filter(e => e.type === 'tool.before' || e.type === 'tool.after').map(e => e.tool).filter(Boolean))];
|
|
155
|
+
const errorCount = events.filter(e => e.type === 'error' || e.status === 'failure').length;
|
|
156
|
+
const lastTimestamp = events.length > 0 ? events[events.length - 1].timestamp : Date.now();
|
|
157
|
+
return `Analyze session events → generate code-aware context summary.
|
|
158
|
+
${repo.root}${repo.instructions}
|
|
159
|
+
## Events (${events.length} total, tools: ${uniqueTools.join(',') || 'none'}, errors: ${errorCount})
|
|
160
|
+
${eventDescriptions || 'No events yet.'}
|
|
161
|
+
|
|
162
|
+
## Analyze (step by step)
|
|
163
|
+
1. Current activity: what operation RIGHT NOW?
|
|
164
|
+
2. Files touched/read/modified (full paths)
|
|
165
|
+
3. Current goal (infer from event sequence)
|
|
166
|
+
4. Blockers: compile errors, test failures, missing deps, stuck loops (3+ calls same file)
|
|
167
|
+
5. Tools used: distinct tool names
|
|
168
|
+
6. Error count
|
|
169
|
+
7. Test status: passing/failing/unknown
|
|
170
|
+
|
|
171
|
+
Return ONLY valid JSON (no markdown):
|
|
172
|
+
{"id":"summary-${Date.now()}","generatedAt":${Date.now()},"whatIsHappening":"...","filesChanged":["..."],"currentGoal":"...","blockers":["..."],"rawEventCount":${events.length},"toolsUsed":["..."],"errorCount":${errorCount},"testStatus":"passing|failing|unknown","lastActivityAt":${lastTimestamp}}`;
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=summarizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summarizer.js","sourceRoot":"","sources":["../../src/llm/summarizer.ts"],"names":[],"mappings":"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"}
|