@memtensor/memos-local-openclaw-plugin 0.3.20 → 1.0.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 +232 -22
- package/dist/capture/index.d.ts +1 -1
- package/dist/capture/index.d.ts.map +1 -1
- package/dist/capture/index.js +33 -8
- package/dist/capture/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/ingest/providers/anthropic.d.ts.map +1 -1
- package/dist/ingest/providers/anthropic.js +22 -8
- package/dist/ingest/providers/anthropic.js.map +1 -1
- package/dist/ingest/providers/bedrock.d.ts.map +1 -1
- package/dist/ingest/providers/bedrock.js +22 -8
- package/dist/ingest/providers/bedrock.js.map +1 -1
- package/dist/ingest/providers/gemini.d.ts.map +1 -1
- package/dist/ingest/providers/gemini.js +22 -8
- package/dist/ingest/providers/gemini.js.map +1 -1
- package/dist/ingest/providers/index.d.ts +13 -18
- package/dist/ingest/providers/index.d.ts.map +1 -1
- package/dist/ingest/providers/index.js +213 -139
- package/dist/ingest/providers/index.js.map +1 -1
- package/dist/ingest/providers/openai.d.ts +1 -1
- package/dist/ingest/providers/openai.d.ts.map +1 -1
- package/dist/ingest/providers/openai.js +37 -17
- package/dist/ingest/providers/openai.js.map +1 -1
- package/dist/ingest/task-processor.d.ts +28 -3
- package/dist/ingest/task-processor.d.ts.map +1 -1
- package/dist/ingest/task-processor.js +166 -67
- package/dist/ingest/task-processor.js.map +1 -1
- package/dist/ingest/worker.d.ts.map +1 -1
- package/dist/ingest/worker.js +97 -75
- package/dist/ingest/worker.js.map +1 -1
- package/dist/shared/llm-call.d.ts +26 -0
- package/dist/shared/llm-call.d.ts.map +1 -0
- package/dist/shared/llm-call.js +163 -0
- package/dist/shared/llm-call.js.map +1 -0
- package/dist/skill/evaluator.d.ts +0 -3
- package/dist/skill/evaluator.d.ts.map +1 -1
- package/dist/skill/evaluator.js +34 -59
- package/dist/skill/evaluator.js.map +1 -1
- package/dist/skill/evolver.d.ts +22 -1
- package/dist/skill/evolver.d.ts.map +1 -1
- package/dist/skill/evolver.js +191 -32
- package/dist/skill/evolver.js.map +1 -1
- package/dist/skill/generator.d.ts +0 -3
- package/dist/skill/generator.d.ts.map +1 -1
- package/dist/skill/generator.js +15 -50
- package/dist/skill/generator.js.map +1 -1
- package/dist/skill/upgrader.d.ts +0 -2
- package/dist/skill/upgrader.d.ts.map +1 -1
- package/dist/skill/upgrader.js +4 -39
- package/dist/skill/upgrader.js.map +1 -1
- package/dist/skill/validator.d.ts +0 -2
- package/dist/skill/validator.d.ts.map +1 -1
- package/dist/skill/validator.js +14 -44
- package/dist/skill/validator.js.map +1 -1
- package/dist/storage/sqlite.d.ts +13 -2
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +72 -6
- package/dist/storage/sqlite.js.map +1 -1
- package/dist/tools/memory-get.d.ts.map +1 -1
- package/dist/tools/memory-get.js +5 -1
- package/dist/tools/memory-get.js.map +1 -1
- package/dist/tools/memory-search.d.ts.map +1 -1
- package/dist/tools/memory-search.js +5 -0
- package/dist/tools/memory-search.js.map +1 -1
- package/dist/tools/memory-timeline.d.ts.map +1 -1
- package/dist/tools/memory-timeline.js +11 -2
- package/dist/tools/memory-timeline.js.map +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/dist/viewer/html.d.ts +1 -1
- package/dist/viewer/html.d.ts.map +1 -1
- package/dist/viewer/html.js +233 -9
- package/dist/viewer/html.js.map +1 -1
- package/dist/viewer/server.d.ts +5 -0
- package/dist/viewer/server.d.ts.map +1 -1
- package/dist/viewer/server.js +383 -177
- package/dist/viewer/server.js.map +1 -1
- package/index.ts +9 -3
- package/package.json +2 -1
- package/src/capture/index.ts +39 -10
- package/src/index.ts +3 -2
- package/src/ingest/providers/anthropic.ts +22 -8
- package/src/ingest/providers/bedrock.ts +22 -8
- package/src/ingest/providers/gemini.ts +22 -8
- package/src/ingest/providers/index.ts +192 -142
- package/src/ingest/providers/openai.ts +37 -17
- package/src/ingest/task-processor.ts +183 -65
- package/src/ingest/worker.ts +98 -77
- package/src/shared/llm-call.ts +144 -0
- package/src/skill/evaluator.ts +35 -64
- package/src/skill/evolver.ts +201 -33
- package/src/skill/generator.ts +16 -59
- package/src/skill/upgrader.ts +5 -43
- package/src/skill/validator.ts +15 -47
- package/src/storage/sqlite.ts +88 -6
- package/src/tools/memory-get.ts +6 -1
- package/src/tools/memory-search.ts +6 -0
- package/src/tools/memory-timeline.ts +13 -1
- package/src/types.ts +2 -1
- package/src/viewer/html.ts +233 -9
- package/src/viewer/server.ts +368 -187
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ingest/providers/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ingest/providers/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ export declare function filterRelevantOpenAI(query: string, candidates: Array<{
|
|
|
11
11
|
summary: string;
|
|
12
12
|
role: string;
|
|
13
13
|
}>, cfg: SummarizerConfig, log: Logger): Promise<FilterResult>;
|
|
14
|
-
export declare const DEDUP_JUDGE_PROMPT = "You are a memory deduplication system.
|
|
14
|
+
export declare const DEDUP_JUDGE_PROMPT = "You are a memory deduplication system.\n\nLANGUAGE RULE (MUST FOLLOW): You MUST reply in the SAME language as the input memories. \u5982\u679C\u8F93\u5165\u662F\u4E2D\u6587\uFF0Creason \u548C mergedSummary \u5FC5\u987B\u7528\u4E2D\u6587\u3002If input is English, reply in English. This applies to ALL text fields in your JSON output.\n\nGiven a NEW memory summary and several EXISTING memory summaries, determine the relationship.\n\nFor each EXISTING memory, the NEW memory is either:\n- \"DUPLICATE\": NEW conveys the same intent/meaning as an EXISTING memory, even if worded differently. Examples: \"\u8BF7\u544A\u8BC9\u6211\u4F60\u7684\u540D\u5B57\" vs \"\u4F60\u5E0C\u671B\u6211\u600E\u4E48\u79F0\u547C\u4F60\"; \"\u65B0\u4F1A\u8BDD\u5DF2\u5F00\u59CB\" vs \"New session started\"; greetings with minor variations. If the core information/intent is the same, it IS a duplicate.\n- \"UPDATE\": NEW contains meaningful additional information that supplements an EXISTING memory (new data, status change, concrete detail not present before)\n- \"NEW\": NEW covers a genuinely different topic/event with no semantic overlap\n\nIMPORTANT: Lean toward DUPLICATE when memories share the same intent, topic, or factual content. Only choose NEW when the topics are truly unrelated. Repetitive conversational patterns (greetings, session starts, identity questions, capability descriptions) across different sessions should be treated as DUPLICATE.\n\nPick the BEST match among all candidates. If none match well, choose \"NEW\".\n\nOutput a single JSON object (reason and mergedSummary MUST match input language):\n- If DUPLICATE: {\"action\":\"DUPLICATE\",\"targetIndex\":2,\"reason\":\"\u4E0E\u5DF2\u6709\u8BB0\u5FC6\u610F\u56FE\u76F8\u540C\"}\n- If UPDATE: {\"action\":\"UPDATE\",\"targetIndex\":3,\"reason\":\"\u65B0\u8BB0\u5FC6\u8865\u5145\u4E86\u989D\u5916\u7EC6\u8282\",\"mergedSummary\":\"\u5408\u5E76\u540E\u7684\u5B8C\u6574\u6458\u8981\uFF0C\u4FDD\u7559\u65B0\u65E7\u6240\u6709\u4FE1\u606F\"}\n- If NEW: {\"action\":\"NEW\",\"reason\":\"\u4E0D\u540C\u4E3B\u9898\uFF0C\u65E0\u5173\u8054\"}\n\nOutput ONLY the JSON object, no other text.";
|
|
15
15
|
export interface DedupResult {
|
|
16
16
|
action: "DUPLICATE" | "UPDATE" | "NEW";
|
|
17
17
|
targetIndex?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../../src/ingest/providers/openai.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAyC5D,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CA+BjB;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CAgCjB;
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../../src/ingest/providers/openai.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAyC5D,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CA+BjB;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CAgCjB;AA6BD,wBAAsB,mBAAmB,CACvC,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,OAAO,CAAC,CAmClB;AAwBD,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EACnE,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,YAAY,CAAC,CAoCvB;AAqBD,eAAO,MAAM,kBAAkB,imEAoBa,CAAC;AAE7C,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,KAAK,CAAC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,EACtE,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,WAAW,CAAC,CAoCtB;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAiBtE"}
|
|
@@ -101,16 +101,30 @@ async function summarizeOpenAI(text, cfg, log) {
|
|
|
101
101
|
const json = (await resp.json());
|
|
102
102
|
return json.choices[0]?.message?.content?.trim() ?? "";
|
|
103
103
|
}
|
|
104
|
-
const TOPIC_JUDGE_PROMPT = `You are a conversation topic boundary detector. Given
|
|
104
|
+
const TOPIC_JUDGE_PROMPT = `You are a conversation topic boundary detector. Given the CURRENT task context (may include opening topic + recent exchanges) and a single NEW user message, decide if the new message belongs to the SAME task or starts a NEW one.
|
|
105
105
|
|
|
106
106
|
Answer ONLY "NEW" or "SAME".
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
-
|
|
110
|
-
-
|
|
111
|
-
-
|
|
112
|
-
-
|
|
113
|
-
-
|
|
108
|
+
SAME — the new message:
|
|
109
|
+
- Continues, follows up on, refines, or corrects the same subject/project/task
|
|
110
|
+
- Asks a clarification or next-step question about what was just discussed
|
|
111
|
+
- Reports a result, error, or feedback about the current task
|
|
112
|
+
- Discusses different tools, methods, or approaches for the SAME goal (e.g., learning English via BBC → via ChatGPT → via AI tools = all SAME "learning English" task)
|
|
113
|
+
- Mentions a related technology or platform in the context of the current goal
|
|
114
|
+
- Is a short acknowledgment (ok, thanks, 好的, 嗯) in direct response to the current flow
|
|
115
|
+
|
|
116
|
+
NEW — the new message:
|
|
117
|
+
- Introduces a clearly UNRELATED subject with NO logical connection to the current task
|
|
118
|
+
- The topic has ZERO overlap with any aspect of the current conversation (e.g., from "learning English" to "what's the weather tomorrow")
|
|
119
|
+
- Starts a request about a completely different domain or life area
|
|
120
|
+
- Begins with a new greeting/reset followed by a different topic
|
|
121
|
+
|
|
122
|
+
Key principles:
|
|
123
|
+
- STRONGLY lean toward SAME — only mark NEW for obvious, unambiguous topic shifts
|
|
124
|
+
- Different aspects, tools, or methods related to the same overall goal are SAME
|
|
125
|
+
- If the new message could reasonably be interpreted as part of the ongoing discussion, choose SAME
|
|
126
|
+
- Only choose NEW when there is absolutely no thematic connection to the current task
|
|
127
|
+
- Examples: "学英语" → "用AI工具学英语" = SAME; "学英语" → "明天天气" = NEW
|
|
114
128
|
|
|
115
129
|
Output exactly one word: NEW or SAME`;
|
|
116
130
|
async function judgeNewTopicOpenAI(currentContext, newMessage, cfg, log) {
|
|
@@ -121,7 +135,7 @@ async function judgeNewTopicOpenAI(currentContext, newMessage, cfg, log) {
|
|
|
121
135
|
Authorization: `Bearer ${cfg.apiKey}`,
|
|
122
136
|
...cfg.headers,
|
|
123
137
|
};
|
|
124
|
-
const userContent = `CURRENT
|
|
138
|
+
const userContent = `CURRENT TASK CONTEXT:\n${currentContext}\n\n---\n\nNEW USER MESSAGE:\n${newMessage}`;
|
|
125
139
|
const resp = await fetch(endpoint, {
|
|
126
140
|
method: "POST",
|
|
127
141
|
headers,
|
|
@@ -217,21 +231,27 @@ function parseFilterResult(raw, log) {
|
|
|
217
231
|
return { relevant: [], sufficient: false };
|
|
218
232
|
}
|
|
219
233
|
// ─── Smart Dedup: judge whether new memory is DUPLICATE / UPDATE / NEW ───
|
|
220
|
-
exports.DEDUP_JUDGE_PROMPT = `You are a memory deduplication system.
|
|
234
|
+
exports.DEDUP_JUDGE_PROMPT = `You are a memory deduplication system.
|
|
235
|
+
|
|
236
|
+
LANGUAGE RULE (MUST FOLLOW): You MUST reply in the SAME language as the input memories. 如果输入是中文,reason 和 mergedSummary 必须用中文。If input is English, reply in English. This applies to ALL text fields in your JSON output.
|
|
237
|
+
|
|
238
|
+
Given a NEW memory summary and several EXISTING memory summaries, determine the relationship.
|
|
221
239
|
|
|
222
240
|
For each EXISTING memory, the NEW memory is either:
|
|
223
|
-
- "DUPLICATE": NEW
|
|
224
|
-
- "UPDATE": NEW contains information that supplements
|
|
225
|
-
- "NEW": NEW
|
|
241
|
+
- "DUPLICATE": NEW conveys the same intent/meaning as an EXISTING memory, even if worded differently. Examples: "请告诉我你的名字" vs "你希望我怎么称呼你"; "新会话已开始" vs "New session started"; greetings with minor variations. If the core information/intent is the same, it IS a duplicate.
|
|
242
|
+
- "UPDATE": NEW contains meaningful additional information that supplements an EXISTING memory (new data, status change, concrete detail not present before)
|
|
243
|
+
- "NEW": NEW covers a genuinely different topic/event with no semantic overlap
|
|
244
|
+
|
|
245
|
+
IMPORTANT: Lean toward DUPLICATE when memories share the same intent, topic, or factual content. Only choose NEW when the topics are truly unrelated. Repetitive conversational patterns (greetings, session starts, identity questions, capability descriptions) across different sessions should be treated as DUPLICATE.
|
|
226
246
|
|
|
227
247
|
Pick the BEST match among all candidates. If none match well, choose "NEW".
|
|
228
248
|
|
|
229
|
-
Output a single JSON object:
|
|
230
|
-
- If DUPLICATE: {"action":"DUPLICATE","targetIndex":2,"reason":"
|
|
231
|
-
- If UPDATE: {"action":"UPDATE","targetIndex":3,"reason":"
|
|
232
|
-
- If NEW: {"action":"NEW","reason":"
|
|
249
|
+
Output a single JSON object (reason and mergedSummary MUST match input language):
|
|
250
|
+
- If DUPLICATE: {"action":"DUPLICATE","targetIndex":2,"reason":"与已有记忆意图相同"}
|
|
251
|
+
- If UPDATE: {"action":"UPDATE","targetIndex":3,"reason":"新记忆补充了额外细节","mergedSummary":"合并后的完整摘要,保留新旧所有信息"}
|
|
252
|
+
- If NEW: {"action":"NEW","reason":"不同主题,无关联"}
|
|
233
253
|
|
|
234
|
-
|
|
254
|
+
Output ONLY the JSON object, no other text.`;
|
|
235
255
|
async function judgeDedupOpenAI(newSummary, candidates, cfg, log) {
|
|
236
256
|
const endpoint = normalizeChatEndpoint(cfg.endpoint ?? "https://api.openai.com/v1/chat/completions");
|
|
237
257
|
const model = cfg.model ?? "gpt-4o-mini";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/ingest/providers/openai.ts"],"names":[],"mappings":";;;AAyCA,kDAmCC;AAED,0CAoCC;
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/ingest/providers/openai.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,8 @@ export declare class TaskProcessor {
|
|
|
18
18
|
private ctx;
|
|
19
19
|
private summarizer;
|
|
20
20
|
private processing;
|
|
21
|
+
private pendingEvents;
|
|
22
|
+
private drainPromise;
|
|
21
23
|
private onTaskCompletedCallback?;
|
|
22
24
|
constructor(store: SqliteStore, ctx: PluginContext);
|
|
23
25
|
onTaskCompleted(cb: (task: Task) => void): void;
|
|
@@ -26,14 +28,37 @@ export declare class TaskProcessor {
|
|
|
26
28
|
* Determines if a new task boundary was crossed and handles transition.
|
|
27
29
|
*/
|
|
28
30
|
onChunksIngested(sessionKey: string, latestTimestamp: number, owner?: string): Promise<void>;
|
|
31
|
+
private drainPending;
|
|
29
32
|
private detectAndProcess;
|
|
30
|
-
private isTaskBoundary;
|
|
31
33
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
+
* Process unassigned chunks one user-turn at a time.
|
|
35
|
+
*
|
|
36
|
+
* Strategy:
|
|
37
|
+
* - Need at least 1 user turn in the current task before starting LLM judgment
|
|
38
|
+
* (0 turns = no reference point for comparison).
|
|
39
|
+
* - Each subsequent user turn is individually checked against the full task context.
|
|
40
|
+
* - Time gap > 2h always triggers a split regardless of topic.
|
|
41
|
+
*/
|
|
42
|
+
private processChunksIncrementally;
|
|
43
|
+
/**
|
|
44
|
+
* Group chunks into user-turns: each turn starts with a user message
|
|
45
|
+
* and includes all subsequent non-user messages until the next user message.
|
|
46
|
+
*/
|
|
47
|
+
private groupIntoTurns;
|
|
48
|
+
/**
|
|
49
|
+
* Build context from existing task chunks for the LLM topic judge.
|
|
50
|
+
* Includes both the task's opening topic and recent exchanges,
|
|
51
|
+
* so the LLM understands both what the task was originally about
|
|
52
|
+
* and where the conversation currently is.
|
|
53
|
+
*
|
|
54
|
+
* For user messages, include full content (up to 500 chars) since
|
|
55
|
+
* they carry the topic signal. For assistant messages, use summary
|
|
56
|
+
* or truncated content since they mostly elaborate.
|
|
34
57
|
*/
|
|
35
58
|
private buildContextSummary;
|
|
59
|
+
private createNewTaskReturn;
|
|
36
60
|
private createNewTask;
|
|
61
|
+
private assignChunksToTask;
|
|
37
62
|
private assignUnassignedChunks;
|
|
38
63
|
finalizeTask(task: Task): Promise<void>;
|
|
39
64
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-processor.d.ts","sourceRoot":"","sources":["../../src/ingest/task-processor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,IAAI,EAAS,MAAM,UAAU,CAAC;AAc3D;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAa;
|
|
1
|
+
{"version":3,"file":"task-processor.d.ts","sourceRoot":"","sources":["../../src/ingest/task-processor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,IAAI,EAAS,MAAM,UAAU,CAAC;AAc3D;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAa;IAQtB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,GAAG;IARb,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAA6E;IAClG,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,uBAAuB,CAAC,CAAuB;gBAG7C,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,aAAa;IAM5B,eAAe,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI;IAI/C;;;OAGG;IACG,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAYpF,YAAY;YAiBZ,gBAAgB;IAuB9B;;;;;;;;OAQG;YACW,0BAA0B;IA+FxC;;;OAGG;IACH,OAAO,CAAC,cAAc;IAetB;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB;YAyBb,mBAAmB;YAkBnB,aAAa;IAK3B,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,sBAAsB;IAKxB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAsD7C;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,iBAAiB;IA6DzB,OAAO,CAAC,uBAAuB;IAa/B,OAAO,CAAC,qBAAqB;IAS7B;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAU7B,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,uBAAuB;IA4B/B,OAAO,CAAC,eAAe;CAcxB"}
|
|
@@ -30,11 +30,14 @@ class TaskProcessor {
|
|
|
30
30
|
ctx;
|
|
31
31
|
summarizer;
|
|
32
32
|
processing = false;
|
|
33
|
+
pendingEvents = [];
|
|
34
|
+
drainPromise = null;
|
|
33
35
|
onTaskCompletedCallback;
|
|
34
36
|
constructor(store, ctx) {
|
|
35
37
|
this.store = store;
|
|
36
38
|
this.ctx = ctx;
|
|
37
|
-
|
|
39
|
+
const strongCfg = ctx.config.skillEvolution?.summarizer;
|
|
40
|
+
this.summarizer = new providers_1.Summarizer(ctx.config.summarizer, ctx.log, strongCfg);
|
|
38
41
|
}
|
|
39
42
|
onTaskCompleted(cb) {
|
|
40
43
|
this.onTaskCompletedCallback = cb;
|
|
@@ -44,25 +47,34 @@ class TaskProcessor {
|
|
|
44
47
|
* Determines if a new task boundary was crossed and handles transition.
|
|
45
48
|
*/
|
|
46
49
|
async onChunksIngested(sessionKey, latestTimestamp, owner) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
const resolvedOwner = owner ?? "agent:main";
|
|
51
|
+
this.ctx.log.debug(`TaskProcessor.onChunksIngested called session=${sessionKey} ts=${latestTimestamp} owner=${resolvedOwner} processing=${this.processing}`);
|
|
52
|
+
this.pendingEvents.push({ sessionKey, latestTimestamp, owner: resolvedOwner });
|
|
53
|
+
if (!this.drainPromise) {
|
|
54
|
+
this.drainPromise = this.drainPending();
|
|
51
55
|
}
|
|
56
|
+
await this.drainPromise;
|
|
57
|
+
}
|
|
58
|
+
async drainPending() {
|
|
52
59
|
this.processing = true;
|
|
53
60
|
try {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
while (this.pendingEvents.length > 0) {
|
|
62
|
+
const next = this.pendingEvents.shift();
|
|
63
|
+
try {
|
|
64
|
+
await this.detectAndProcess(next.sessionKey, next.latestTimestamp, next.owner);
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
this.ctx.log.error(`TaskProcessor error: ${err}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
58
70
|
}
|
|
59
71
|
finally {
|
|
60
72
|
this.processing = false;
|
|
73
|
+
this.drainPromise = null;
|
|
61
74
|
}
|
|
62
75
|
}
|
|
63
76
|
async detectAndProcess(sessionKey, latestTimestamp, owner) {
|
|
64
77
|
this.ctx.log.debug(`TaskProcessor.detectAndProcess session=${sessionKey} owner=${owner}`);
|
|
65
|
-
// Finalize any active tasks from OTHER sessions for the SAME owner (session change = task boundary)
|
|
66
78
|
const allActive = this.store.getAllActiveTasks(owner);
|
|
67
79
|
for (const t of allActive) {
|
|
68
80
|
if (t.sessionKey !== sessionKey) {
|
|
@@ -70,70 +82,150 @@ class TaskProcessor {
|
|
|
70
82
|
await this.finalizeTask(t);
|
|
71
83
|
}
|
|
72
84
|
}
|
|
73
|
-
|
|
85
|
+
let activeTask = this.store.getActiveTask(sessionKey, owner);
|
|
74
86
|
this.ctx.log.debug(`TaskProcessor.detectAndProcess activeTask=${activeTask?.id ?? "none"} owner=${owner}`);
|
|
75
87
|
if (!activeTask) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const isNewTask = await this.isTaskBoundary(activeTask, sessionKey, latestTimestamp);
|
|
80
|
-
if (isNewTask) {
|
|
81
|
-
await this.finalizeTask(activeTask);
|
|
82
|
-
await this.createNewTask(sessionKey, latestTimestamp, owner);
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
this.assignUnassignedChunks(sessionKey, activeTask.id);
|
|
86
|
-
this.store.updateTask(activeTask.id, { endedAt: undefined });
|
|
88
|
+
// Create a new empty task — do NOT assign all chunks yet.
|
|
89
|
+
// processChunksIncrementally will assign them one turn at a time with boundary checks.
|
|
90
|
+
activeTask = await this.createNewTaskReturn(sessionKey, latestTimestamp, owner);
|
|
87
91
|
}
|
|
92
|
+
await this.processChunksIncrementally(activeTask, sessionKey, latestTimestamp, owner);
|
|
88
93
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
94
|
+
/**
|
|
95
|
+
* Process unassigned chunks one user-turn at a time.
|
|
96
|
+
*
|
|
97
|
+
* Strategy:
|
|
98
|
+
* - Need at least 1 user turn in the current task before starting LLM judgment
|
|
99
|
+
* (0 turns = no reference point for comparison).
|
|
100
|
+
* - Each subsequent user turn is individually checked against the full task context.
|
|
101
|
+
* - Time gap > 2h always triggers a split regardless of topic.
|
|
102
|
+
*/
|
|
103
|
+
async processChunksIncrementally(activeTask, sessionKey, latestTimestamp, owner) {
|
|
104
|
+
const unassigned = this.store.getUnassignedChunks(sessionKey);
|
|
105
|
+
if (unassigned.length === 0)
|
|
106
|
+
return;
|
|
107
|
+
const taskChunks = this.store.getChunksByTask(activeTask.id);
|
|
108
|
+
// Time gap check against the earliest unassigned chunk
|
|
109
|
+
if (taskChunks.length > 0) {
|
|
110
|
+
const lastTaskTs = Math.max(...taskChunks.map((c) => c.createdAt));
|
|
111
|
+
const firstUnassignedTs = Math.min(...unassigned.map((c) => c.createdAt));
|
|
112
|
+
const gap = firstUnassignedTs - lastTaskTs;
|
|
113
|
+
if (gap > types_1.DEFAULTS.taskIdleTimeoutMs) {
|
|
114
|
+
this.ctx.log.info(`Task boundary: time gap ${Math.round(gap / 60000)}min > ${Math.round(types_1.DEFAULTS.taskIdleTimeoutMs / 60000)}min`);
|
|
115
|
+
await this.finalizeTask(activeTask);
|
|
116
|
+
const newTask = await this.createNewTaskReturn(sessionKey, latestTimestamp, owner);
|
|
117
|
+
// Recurse with the new empty task so remaining unassigned chunks get boundary-checked too
|
|
118
|
+
return this.processChunksIncrementally(newTask, sessionKey, latestTimestamp, owner);
|
|
119
|
+
}
|
|
101
120
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
return
|
|
106
|
-
const existingUserChunks = chunks.filter((c) => c.role === "user");
|
|
107
|
-
if (existingUserChunks.length === 0)
|
|
108
|
-
return false;
|
|
109
|
-
const currentContext = this.buildContextSummary(chunks);
|
|
110
|
-
const newMessage = newUserChunks.map((c) => c.content).join("\n");
|
|
111
|
-
const isNew = await this.summarizer.judgeNewTopic(currentContext, newMessage);
|
|
112
|
-
if (isNew === null) {
|
|
113
|
-
this.ctx.log.debug("Topic judge unavailable (no LLM configured), keeping current task");
|
|
114
|
-
return false;
|
|
121
|
+
const turns = this.groupIntoTurns(unassigned);
|
|
122
|
+
if (turns.length === 0) {
|
|
123
|
+
this.assignChunksToTask(unassigned, activeTask.id);
|
|
124
|
+
return;
|
|
115
125
|
}
|
|
116
|
-
|
|
117
|
-
|
|
126
|
+
let currentTask = activeTask;
|
|
127
|
+
let currentTaskChunks = [...taskChunks];
|
|
128
|
+
for (let i = 0; i < turns.length; i++) {
|
|
129
|
+
const turn = turns[i];
|
|
130
|
+
const userChunk = turn.find((c) => c.role === "user");
|
|
131
|
+
if (!userChunk) {
|
|
132
|
+
this.assignChunksToTask(turn, currentTask.id);
|
|
133
|
+
currentTaskChunks = currentTaskChunks.concat(turn);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
// Time gap check per turn
|
|
137
|
+
if (currentTaskChunks.length > 0) {
|
|
138
|
+
const lastTs = Math.max(...currentTaskChunks.map((c) => c.createdAt));
|
|
139
|
+
if (userChunk.createdAt - lastTs > types_1.DEFAULTS.taskIdleTimeoutMs) {
|
|
140
|
+
this.ctx.log.info(`Task boundary at turn ${i}: time gap ${Math.round((userChunk.createdAt - lastTs) / 60000)}min`);
|
|
141
|
+
await this.finalizeTask(currentTask);
|
|
142
|
+
currentTask = await this.createNewTaskReturn(sessionKey, userChunk.createdAt, owner);
|
|
143
|
+
currentTaskChunks = [];
|
|
144
|
+
this.assignChunksToTask(turn, currentTask.id);
|
|
145
|
+
currentTaskChunks = currentTaskChunks.concat(turn);
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// Need at least 1 user turn before we can meaningfully judge topic shifts
|
|
150
|
+
const existingUserCount = currentTaskChunks.filter((c) => c.role === "user").length;
|
|
151
|
+
if (existingUserCount < 1) {
|
|
152
|
+
this.assignChunksToTask(turn, currentTask.id);
|
|
153
|
+
currentTaskChunks = currentTaskChunks.concat(turn);
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
// LLM topic judgment — check this single user message against full task context
|
|
157
|
+
const context = this.buildContextSummary(currentTaskChunks);
|
|
158
|
+
const newMsg = userChunk.content.slice(0, 500);
|
|
159
|
+
this.ctx.log.info(`Topic judge: "${newMsg.slice(0, 60)}" vs ${existingUserCount} user turns`);
|
|
160
|
+
const isNew = await this.summarizer.judgeNewTopic(context, newMsg);
|
|
161
|
+
this.ctx.log.info(`Topic judge result: ${isNew === null ? "null(fallback)" : isNew ? "NEW" : "SAME"}`);
|
|
162
|
+
if (isNew === null) {
|
|
163
|
+
this.assignChunksToTask(turn, currentTask.id);
|
|
164
|
+
currentTaskChunks = currentTaskChunks.concat(turn);
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (isNew) {
|
|
168
|
+
this.ctx.log.info(`Task boundary at turn ${i}: LLM judged new topic. Msg: "${newMsg.slice(0, 80)}..."`);
|
|
169
|
+
await this.finalizeTask(currentTask);
|
|
170
|
+
currentTask = await this.createNewTaskReturn(sessionKey, userChunk.createdAt, owner);
|
|
171
|
+
currentTaskChunks = [];
|
|
172
|
+
}
|
|
173
|
+
this.assignChunksToTask(turn, currentTask.id);
|
|
174
|
+
currentTaskChunks = currentTaskChunks.concat(turn);
|
|
118
175
|
}
|
|
119
|
-
|
|
120
|
-
|
|
176
|
+
this.store.updateTask(currentTask.id, { endedAt: undefined });
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Group chunks into user-turns: each turn starts with a user message
|
|
180
|
+
* and includes all subsequent non-user messages until the next user message.
|
|
181
|
+
*/
|
|
182
|
+
groupIntoTurns(chunks) {
|
|
183
|
+
const turns = [];
|
|
184
|
+
let current = [];
|
|
185
|
+
for (const c of chunks) {
|
|
186
|
+
if (c.role === "user" && current.length > 0) {
|
|
187
|
+
turns.push(current);
|
|
188
|
+
current = [];
|
|
189
|
+
}
|
|
190
|
+
current.push(c);
|
|
121
191
|
}
|
|
122
|
-
|
|
192
|
+
if (current.length > 0)
|
|
193
|
+
turns.push(current);
|
|
194
|
+
return turns;
|
|
123
195
|
}
|
|
124
196
|
/**
|
|
125
|
-
* Build
|
|
126
|
-
*
|
|
197
|
+
* Build context from existing task chunks for the LLM topic judge.
|
|
198
|
+
* Includes both the task's opening topic and recent exchanges,
|
|
199
|
+
* so the LLM understands both what the task was originally about
|
|
200
|
+
* and where the conversation currently is.
|
|
201
|
+
*
|
|
202
|
+
* For user messages, include full content (up to 500 chars) since
|
|
203
|
+
* they carry the topic signal. For assistant messages, use summary
|
|
204
|
+
* or truncated content since they mostly elaborate.
|
|
127
205
|
*/
|
|
128
206
|
buildContextSummary(chunks) {
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
.
|
|
207
|
+
const conversational = chunks.filter((c) => c.role === "user" || c.role === "assistant");
|
|
208
|
+
if (conversational.length === 0)
|
|
209
|
+
return "";
|
|
210
|
+
const formatChunk = (c) => {
|
|
211
|
+
const label = c.role === "user" ? "User" : "Assistant";
|
|
212
|
+
const maxLen = c.role === "user" ? 500 : 200;
|
|
213
|
+
const text = c.summary || c.content.slice(0, maxLen);
|
|
214
|
+
return `[${label}]: ${text}`;
|
|
215
|
+
};
|
|
216
|
+
if (conversational.length <= 10) {
|
|
217
|
+
return conversational.map(formatChunk).join("\n");
|
|
218
|
+
}
|
|
219
|
+
const opening = conversational.slice(0, 6).map(formatChunk);
|
|
220
|
+
const recent = conversational.slice(-4).map(formatChunk);
|
|
221
|
+
return [
|
|
222
|
+
"--- Task opening ---",
|
|
223
|
+
...opening,
|
|
224
|
+
"--- Recent exchanges ---",
|
|
225
|
+
...recent,
|
|
226
|
+
].join("\n");
|
|
135
227
|
}
|
|
136
|
-
async
|
|
228
|
+
async createNewTaskReturn(sessionKey, timestamp, owner = "agent:main") {
|
|
137
229
|
const taskId = (0, uuid_1.v4)();
|
|
138
230
|
const task = {
|
|
139
231
|
id: taskId,
|
|
@@ -147,18 +239,25 @@ class TaskProcessor {
|
|
|
147
239
|
updatedAt: timestamp,
|
|
148
240
|
};
|
|
149
241
|
this.store.insertTask(task);
|
|
150
|
-
this.assignUnassignedChunks(sessionKey, taskId);
|
|
151
242
|
this.ctx.log.info(`Created new task=${taskId} session=${sessionKey}`);
|
|
243
|
+
return task;
|
|
152
244
|
}
|
|
153
|
-
|
|
154
|
-
const
|
|
155
|
-
|
|
245
|
+
async createNewTask(sessionKey, timestamp, owner = "agent:main") {
|
|
246
|
+
const task = await this.createNewTaskReturn(sessionKey, timestamp, owner);
|
|
247
|
+
this.assignUnassignedChunks(sessionKey, task.id);
|
|
248
|
+
}
|
|
249
|
+
assignChunksToTask(chunks, taskId) {
|
|
250
|
+
for (const chunk of chunks) {
|
|
156
251
|
this.store.setChunkTaskId(chunk.id, taskId);
|
|
157
252
|
}
|
|
158
|
-
if (
|
|
159
|
-
this.ctx.log.debug(`Assigned ${
|
|
253
|
+
if (chunks.length > 0) {
|
|
254
|
+
this.ctx.log.debug(`Assigned ${chunks.length} chunks to task=${taskId}`);
|
|
160
255
|
}
|
|
161
256
|
}
|
|
257
|
+
assignUnassignedChunks(sessionKey, taskId) {
|
|
258
|
+
const unassigned = this.store.getUnassignedChunks(sessionKey);
|
|
259
|
+
this.assignChunksToTask(unassigned, taskId);
|
|
260
|
+
}
|
|
162
261
|
async finalizeTask(task) {
|
|
163
262
|
const chunks = this.store.getChunksByTask(task.id);
|
|
164
263
|
const fallbackTitle = chunks.length > 0 ? this.extractTitle(chunks) : "";
|