@memtensor/memos-local-openclaw-plugin 0.1.3 → 0.1.5
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/.env.example +13 -5
- package/README.md +283 -91
- package/dist/capture/index.d.ts +5 -7
- package/dist/capture/index.d.ts.map +1 -1
- package/dist/capture/index.js +72 -43
- package/dist/capture/index.js.map +1 -1
- package/dist/ingest/dedup.d.ts +8 -0
- package/dist/ingest/dedup.d.ts.map +1 -1
- package/dist/ingest/dedup.js +21 -0
- package/dist/ingest/dedup.js.map +1 -1
- package/dist/ingest/providers/anthropic.d.ts +16 -0
- package/dist/ingest/providers/anthropic.d.ts.map +1 -1
- package/dist/ingest/providers/anthropic.js +214 -1
- package/dist/ingest/providers/anthropic.js.map +1 -1
- package/dist/ingest/providers/bedrock.d.ts +16 -5
- package/dist/ingest/providers/bedrock.d.ts.map +1 -1
- package/dist/ingest/providers/bedrock.js +210 -6
- package/dist/ingest/providers/bedrock.js.map +1 -1
- package/dist/ingest/providers/gemini.d.ts +16 -0
- package/dist/ingest/providers/gemini.d.ts.map +1 -1
- package/dist/ingest/providers/gemini.js +202 -1
- package/dist/ingest/providers/gemini.js.map +1 -1
- package/dist/ingest/providers/index.d.ts +31 -0
- package/dist/ingest/providers/index.d.ts.map +1 -1
- package/dist/ingest/providers/index.js +134 -4
- package/dist/ingest/providers/index.js.map +1 -1
- package/dist/ingest/providers/openai.d.ts +24 -0
- package/dist/ingest/providers/openai.d.ts.map +1 -1
- package/dist/ingest/providers/openai.js +255 -1
- package/dist/ingest/providers/openai.js.map +1 -1
- package/dist/ingest/task-processor.d.ts +65 -0
- package/dist/ingest/task-processor.d.ts.map +1 -0
- package/dist/ingest/task-processor.js +354 -0
- package/dist/ingest/task-processor.js.map +1 -0
- package/dist/ingest/worker.d.ts +3 -1
- package/dist/ingest/worker.d.ts.map +1 -1
- package/dist/ingest/worker.js +131 -23
- package/dist/ingest/worker.js.map +1 -1
- package/dist/recall/engine.d.ts +1 -0
- package/dist/recall/engine.d.ts.map +1 -1
- package/dist/recall/engine.js +22 -11
- package/dist/recall/engine.js.map +1 -1
- package/dist/recall/mmr.d.ts.map +1 -1
- package/dist/recall/mmr.js +3 -1
- package/dist/recall/mmr.js.map +1 -1
- package/dist/skill/bundled-memory-guide.d.ts +6 -0
- package/dist/skill/bundled-memory-guide.d.ts.map +1 -0
- package/dist/skill/bundled-memory-guide.js +95 -0
- package/dist/skill/bundled-memory-guide.js.map +1 -0
- package/dist/skill/evaluator.d.ts +31 -0
- package/dist/skill/evaluator.d.ts.map +1 -0
- package/dist/skill/evaluator.js +194 -0
- package/dist/skill/evaluator.js.map +1 -0
- package/dist/skill/evolver.d.ts +22 -0
- package/dist/skill/evolver.d.ts.map +1 -0
- package/dist/skill/evolver.js +193 -0
- package/dist/skill/evolver.js.map +1 -0
- package/dist/skill/generator.d.ts +25 -0
- package/dist/skill/generator.d.ts.map +1 -0
- package/dist/skill/generator.js +477 -0
- package/dist/skill/generator.js.map +1 -0
- package/dist/skill/installer.d.ts +16 -0
- package/dist/skill/installer.d.ts.map +1 -0
- package/dist/skill/installer.js +89 -0
- package/dist/skill/installer.js.map +1 -0
- package/dist/skill/upgrader.d.ts +19 -0
- package/dist/skill/upgrader.d.ts.map +1 -0
- package/dist/skill/upgrader.js +263 -0
- package/dist/skill/upgrader.js.map +1 -0
- package/dist/skill/validator.d.ts +29 -0
- package/dist/skill/validator.d.ts.map +1 -0
- package/dist/skill/validator.js +227 -0
- package/dist/skill/validator.js.map +1 -0
- package/dist/storage/sqlite.d.ts +141 -1
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +664 -7
- package/dist/storage/sqlite.js.map +1 -1
- package/dist/types.d.ts +93 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +8 -0
- 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 +2391 -159
- package/dist/viewer/html.js.map +1 -1
- package/dist/viewer/server.d.ts +16 -0
- package/dist/viewer/server.d.ts.map +1 -1
- package/dist/viewer/server.js +346 -3
- package/dist/viewer/server.js.map +1 -1
- package/index.ts +572 -89
- package/openclaw.plugin.json +20 -45
- package/package.json +3 -4
- package/skill/memos-memory-guide/SKILL.md +86 -0
- package/src/capture/index.ts +85 -45
- package/src/ingest/dedup.ts +29 -0
- package/src/ingest/providers/anthropic.ts +258 -1
- package/src/ingest/providers/bedrock.ts +256 -6
- package/src/ingest/providers/gemini.ts +252 -1
- package/src/ingest/providers/index.ts +156 -8
- package/src/ingest/providers/openai.ts +304 -1
- package/src/ingest/task-processor.ts +396 -0
- package/src/ingest/worker.ts +145 -34
- package/src/recall/engine.ts +23 -12
- package/src/recall/mmr.ts +3 -1
- package/src/skill/bundled-memory-guide.ts +91 -0
- package/src/skill/evaluator.ts +220 -0
- package/src/skill/evolver.ts +169 -0
- package/src/skill/generator.ts +506 -0
- package/src/skill/installer.ts +59 -0
- package/src/skill/upgrader.ts +257 -0
- package/src/skill/validator.ts +227 -0
- package/src/storage/sqlite.ts +802 -7
- package/src/types.ts +96 -0
- package/src/viewer/html.ts +2391 -159
- package/src/viewer/server.ts +346 -3
- package/SKILL.md +0 -43
- package/www/index.html +0 -632
|
@@ -1,12 +1,188 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.summarizeTaskBedrock = summarizeTaskBedrock;
|
|
4
|
+
exports.judgeNewTopicBedrock = judgeNewTopicBedrock;
|
|
5
|
+
exports.filterRelevantBedrock = filterRelevantBedrock;
|
|
3
6
|
exports.summarizeBedrock = summarizeBedrock;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
exports.judgeDedupBedrock = judgeDedupBedrock;
|
|
8
|
+
const SYSTEM_PROMPT = `Summarize the text in ONE concise sentence (max 120 characters). IMPORTANT: Use the SAME language as the input text — if the input is Chinese, write Chinese; if English, write English. Preserve exact names, commands, error codes. No bullet points, no preamble — output only the sentence.`;
|
|
9
|
+
const TASK_SUMMARY_PROMPT = `You create a DETAILED task summary from a multi-turn conversation. This summary will be the ONLY record of this conversation, so it must preserve ALL important information.
|
|
10
|
+
|
|
11
|
+
CRITICAL LANGUAGE RULE: You MUST write in the SAME language as the user's messages. Chinese input → Chinese output. English input → English output. NEVER mix languages.
|
|
12
|
+
|
|
13
|
+
Output EXACTLY this structure:
|
|
14
|
+
|
|
15
|
+
📌 Title
|
|
16
|
+
A short, descriptive title (10-30 characters). Like a chat group name.
|
|
17
|
+
|
|
18
|
+
🎯 Goal
|
|
19
|
+
One sentence: what the user wanted to accomplish.
|
|
20
|
+
|
|
21
|
+
📋 Key Steps
|
|
22
|
+
- Describe each meaningful step in detail
|
|
23
|
+
- Include the ACTUAL content produced: code snippets, commands, config blocks, formulas, key paragraphs
|
|
24
|
+
- For code: include the function signature and core logic (up to ~30 lines per block), use fenced code blocks
|
|
25
|
+
- For configs: include the actual config values and structure
|
|
26
|
+
- For lists/instructions: include the actual items, not just "provided a list"
|
|
27
|
+
- Merge only truly trivial back-and-forth (like "ok" / "sure")
|
|
28
|
+
- Do NOT over-summarize: "provided a function" is BAD; show the actual function
|
|
29
|
+
|
|
30
|
+
✅ Result
|
|
31
|
+
What was the final outcome? Include the final version of any code/config/content produced.
|
|
32
|
+
|
|
33
|
+
💡 Key Details
|
|
34
|
+
- Decisions made, trade-offs discussed, caveats noted, alternative approaches mentioned
|
|
35
|
+
- Specific values: numbers, versions, thresholds, URLs, file paths, model names
|
|
36
|
+
- Omit this section only if there truly are no noteworthy details
|
|
37
|
+
|
|
38
|
+
RULES:
|
|
39
|
+
- This summary is a KNOWLEDGE BASE ENTRY, not a brief note. Be thorough.
|
|
40
|
+
- PRESERVE verbatim: code, commands, URLs, file paths, error messages, config values, version numbers, names, amounts
|
|
41
|
+
- DISCARD only: greetings, filler, the assistant explaining what it will do before doing it
|
|
42
|
+
- Replace secrets (API keys, tokens, passwords) with [REDACTED]
|
|
43
|
+
- Target length: 30-50% of the original conversation length. Longer conversations need longer summaries.
|
|
44
|
+
- Output summary only, no preamble.`;
|
|
45
|
+
async function summarizeTaskBedrock(text, cfg, log) {
|
|
46
|
+
const model = cfg.model ?? "anthropic.claude-3-haiku-20240307-v1:0";
|
|
47
|
+
const endpoint = cfg.endpoint;
|
|
48
|
+
if (!endpoint) {
|
|
49
|
+
throw new Error("Bedrock task-summarizer requires 'endpoint'");
|
|
50
|
+
}
|
|
51
|
+
const url = `${endpoint}/model/${model}/converse`;
|
|
52
|
+
const headers = {
|
|
53
|
+
"Content-Type": "application/json",
|
|
54
|
+
...cfg.headers,
|
|
55
|
+
};
|
|
56
|
+
const resp = await fetch(url, {
|
|
57
|
+
method: "POST",
|
|
58
|
+
headers,
|
|
59
|
+
body: JSON.stringify({
|
|
60
|
+
system: [{ text: TASK_SUMMARY_PROMPT }],
|
|
61
|
+
messages: [{ role: "user", content: [{ text }] }],
|
|
62
|
+
inferenceConfig: { temperature: cfg.temperature ?? 0.1, maxTokens: 4096 },
|
|
63
|
+
}),
|
|
64
|
+
signal: AbortSignal.timeout(cfg.timeoutMs ?? 60_000),
|
|
65
|
+
});
|
|
66
|
+
if (!resp.ok) {
|
|
67
|
+
const body = await resp.text();
|
|
68
|
+
throw new Error(`Bedrock task-summarize failed (${resp.status}): ${body}`);
|
|
69
|
+
}
|
|
70
|
+
const json = (await resp.json());
|
|
71
|
+
return json.output?.message?.content?.[0]?.text?.trim() ?? "";
|
|
72
|
+
}
|
|
73
|
+
const TOPIC_JUDGE_PROMPT = `You are a conversation topic boundary detector. Given a summary of the CURRENT conversation and a NEW user message, determine if the new message starts a DIFFERENT topic/task.
|
|
74
|
+
|
|
75
|
+
Answer ONLY "NEW" or "SAME".
|
|
76
|
+
|
|
77
|
+
Rules:
|
|
78
|
+
- "NEW" = the new message is about a completely different subject, project, or task
|
|
79
|
+
- "SAME" = the new message continues, follows up on, or is closely related to the current topic
|
|
80
|
+
- Follow-up questions, clarifications, refinements, bug fixes, or next steps on the same task = SAME
|
|
81
|
+
- Greetings or meta-questions like "你好" or "谢谢" without new substance = SAME
|
|
82
|
+
- A clearly unrelated request (e.g., current topic is deployment, new message asks about cooking) = NEW
|
|
83
|
+
|
|
84
|
+
Output exactly one word: NEW or SAME`;
|
|
85
|
+
async function judgeNewTopicBedrock(currentContext, newMessage, cfg, log) {
|
|
86
|
+
const model = cfg.model ?? "anthropic.claude-3-haiku-20240307-v1:0";
|
|
87
|
+
const endpoint = cfg.endpoint;
|
|
88
|
+
if (!endpoint) {
|
|
89
|
+
throw new Error("Bedrock topic-judge requires 'endpoint'");
|
|
90
|
+
}
|
|
91
|
+
const url = `${endpoint}/model/${model}/converse`;
|
|
92
|
+
const headers = {
|
|
93
|
+
"Content-Type": "application/json",
|
|
94
|
+
...cfg.headers,
|
|
95
|
+
};
|
|
96
|
+
const userContent = `CURRENT CONVERSATION SUMMARY:\n${currentContext}\n\nNEW USER MESSAGE:\n${newMessage}`;
|
|
97
|
+
const resp = await fetch(url, {
|
|
98
|
+
method: "POST",
|
|
99
|
+
headers,
|
|
100
|
+
body: JSON.stringify({
|
|
101
|
+
system: [{ text: TOPIC_JUDGE_PROMPT }],
|
|
102
|
+
messages: [{ role: "user", content: [{ text: userContent }] }],
|
|
103
|
+
inferenceConfig: { temperature: 0, maxTokens: 10 },
|
|
104
|
+
}),
|
|
105
|
+
signal: AbortSignal.timeout(cfg.timeoutMs ?? 15_000),
|
|
106
|
+
});
|
|
107
|
+
if (!resp.ok) {
|
|
108
|
+
const body = await resp.text();
|
|
109
|
+
throw new Error(`Bedrock topic-judge failed (${resp.status}): ${body}`);
|
|
110
|
+
}
|
|
111
|
+
const json = (await resp.json());
|
|
112
|
+
const answer = json.output?.message?.content?.[0]?.text?.trim().toUpperCase() ?? "";
|
|
113
|
+
log.debug(`Topic judge result: "${answer}"`);
|
|
114
|
+
return answer.startsWith("NEW");
|
|
115
|
+
}
|
|
116
|
+
const FILTER_RELEVANT_PROMPT = `You are a memory relevance judge. Given a user's QUERY and a list of CANDIDATE memory summaries, do two things:
|
|
117
|
+
|
|
118
|
+
1. Select ALL candidates that could be useful for answering the query. When in doubt, INCLUDE the candidate.
|
|
119
|
+
- For questions about lists, history, or "what/where/who" across multiple items (e.g. "which companies did I work at"), include ALL matching items — do NOT stop at the first match.
|
|
120
|
+
- For factual lookups (e.g. "what is the SSH port"), a single direct answer is enough.
|
|
121
|
+
2. Judge whether the selected memories are SUFFICIENT to fully answer the query WITHOUT fetching additional context.
|
|
122
|
+
|
|
123
|
+
IMPORTANT for "sufficient" judgment:
|
|
124
|
+
- sufficient=true ONLY when the memories contain a concrete ANSWER, fact, decision, or actionable information that directly addresses the query.
|
|
125
|
+
- sufficient=false when:
|
|
126
|
+
- The memories only repeat the same question the user asked before (echo, not answer).
|
|
127
|
+
- The memories show related topics but lack the specific detail needed.
|
|
128
|
+
- The memories contain partial information that would benefit from full task context, timeline, or related skills.
|
|
129
|
+
|
|
130
|
+
Output a JSON object with exactly two fields:
|
|
131
|
+
{"relevant":[1,3,5],"sufficient":true}
|
|
132
|
+
|
|
133
|
+
- "relevant": array of candidate numbers that are useful. Empty array [] if none are relevant.
|
|
134
|
+
- "sufficient": true ONLY if the memories contain a direct answer; false otherwise.
|
|
135
|
+
|
|
136
|
+
Output ONLY the JSON object, nothing else.`;
|
|
137
|
+
async function filterRelevantBedrock(query, candidates, cfg, log) {
|
|
138
|
+
const model = cfg.model ?? "anthropic.claude-3-haiku-20240307-v1:0";
|
|
139
|
+
const endpoint = cfg.endpoint;
|
|
140
|
+
if (!endpoint) {
|
|
141
|
+
throw new Error("Bedrock filter-relevant requires 'endpoint'");
|
|
142
|
+
}
|
|
143
|
+
const url = `${endpoint}/model/${model}/converse`;
|
|
144
|
+
const headers = {
|
|
145
|
+
"Content-Type": "application/json",
|
|
146
|
+
...cfg.headers,
|
|
147
|
+
};
|
|
148
|
+
const candidateText = candidates
|
|
149
|
+
.map((c) => `${c.index}. [${c.role}] ${c.summary}`)
|
|
150
|
+
.join("\n");
|
|
151
|
+
const resp = await fetch(url, {
|
|
152
|
+
method: "POST",
|
|
153
|
+
headers,
|
|
154
|
+
body: JSON.stringify({
|
|
155
|
+
system: [{ text: FILTER_RELEVANT_PROMPT }],
|
|
156
|
+
messages: [{ role: "user", content: [{ text: `QUERY: ${query}\n\nCANDIDATES:\n${candidateText}` }] }],
|
|
157
|
+
inferenceConfig: { temperature: 0, maxTokens: 200 },
|
|
158
|
+
}),
|
|
159
|
+
signal: AbortSignal.timeout(cfg.timeoutMs ?? 15_000),
|
|
160
|
+
});
|
|
161
|
+
if (!resp.ok) {
|
|
162
|
+
const body = await resp.text();
|
|
163
|
+
throw new Error(`Bedrock filter-relevant failed (${resp.status}): ${body}`);
|
|
164
|
+
}
|
|
165
|
+
const json = (await resp.json());
|
|
166
|
+
const raw = json.output?.message?.content?.[0]?.text?.trim() ?? "{}";
|
|
167
|
+
return parseFilterResult(raw, log);
|
|
168
|
+
}
|
|
169
|
+
function parseFilterResult(raw, log) {
|
|
170
|
+
try {
|
|
171
|
+
const match = raw.match(/\{[\s\S]*\}/);
|
|
172
|
+
if (match) {
|
|
173
|
+
const obj = JSON.parse(match[0]);
|
|
174
|
+
if (obj && Array.isArray(obj.relevant)) {
|
|
175
|
+
return {
|
|
176
|
+
relevant: obj.relevant.filter((n) => typeof n === "number"),
|
|
177
|
+
sufficient: obj.sufficient === true,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch { }
|
|
183
|
+
log.warn(`filterRelevant: failed to parse LLM output: "${raw}", fallback to all+insufficient`);
|
|
184
|
+
return { relevant: [], sufficient: false };
|
|
185
|
+
}
|
|
10
186
|
async function summarizeBedrock(text, cfg, log) {
|
|
11
187
|
const model = cfg.model ?? "anthropic.claude-3-haiku-20240307-v1:0";
|
|
12
188
|
const endpoint = cfg.endpoint;
|
|
@@ -38,4 +214,32 @@ async function summarizeBedrock(text, cfg, log) {
|
|
|
38
214
|
const json = (await resp.json());
|
|
39
215
|
return json.output?.message?.content?.[0]?.text?.trim() ?? "";
|
|
40
216
|
}
|
|
217
|
+
// ─── Smart Dedup ───
|
|
218
|
+
const openai_1 = require("./openai");
|
|
219
|
+
async function judgeDedupBedrock(newSummary, candidates, cfg, log) {
|
|
220
|
+
const model = cfg.model ?? "anthropic.claude-3-haiku-20240307-v1:0";
|
|
221
|
+
const endpoint = cfg.endpoint;
|
|
222
|
+
if (!endpoint)
|
|
223
|
+
throw new Error("Bedrock dedup-judge requires 'endpoint'");
|
|
224
|
+
const url = `${endpoint}/model/${model}/converse`;
|
|
225
|
+
const headers = { "Content-Type": "application/json", ...cfg.headers };
|
|
226
|
+
const candidateText = candidates.map((c) => `${c.index}. ${c.summary}`).join("\n");
|
|
227
|
+
const resp = await fetch(url, {
|
|
228
|
+
method: "POST",
|
|
229
|
+
headers,
|
|
230
|
+
body: JSON.stringify({
|
|
231
|
+
system: [{ text: openai_1.DEDUP_JUDGE_PROMPT }],
|
|
232
|
+
messages: [{ role: "user", content: [{ text: `NEW MEMORY:\n${newSummary}\n\nEXISTING MEMORIES:\n${candidateText}` }] }],
|
|
233
|
+
inferenceConfig: { temperature: 0, maxTokens: 300 },
|
|
234
|
+
}),
|
|
235
|
+
signal: AbortSignal.timeout(cfg.timeoutMs ?? 15_000),
|
|
236
|
+
});
|
|
237
|
+
if (!resp.ok) {
|
|
238
|
+
const body = await resp.text();
|
|
239
|
+
throw new Error(`Bedrock dedup-judge failed (${resp.status}): ${body}`);
|
|
240
|
+
}
|
|
241
|
+
const json = (await resp.json());
|
|
242
|
+
const raw = json.output?.message?.content?.[0]?.text?.trim() ?? "{}";
|
|
243
|
+
return (0, openai_1.parseDedupResult)(raw, log);
|
|
244
|
+
}
|
|
41
245
|
//# sourceMappingURL=bedrock.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bedrock.js","sourceRoot":"","sources":["../../../src/ingest/providers/bedrock.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"bedrock.js","sourceRoot":"","sources":["../../../src/ingest/providers/bedrock.ts"],"names":[],"mappings":";;AAyCA,oDAmCC;AAeD,oDAwCC;AA2BD,sDAyCC;AAmBD,4CAwCC;AAQD,8CAiCC;AAzSD,MAAM,aAAa,GAAG,iSAAiS,CAAC;AAExT,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oCAmCQ,CAAC;AAE9B,KAAK,UAAU,oBAAoB,CACxC,IAAY,EACZ,GAAqB,EACrB,GAAW;IAEX,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,wCAAwC,CAAC;IACpE,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC9B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,QAAQ,UAAU,KAAK,WAAW,CAAC;IAClD,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,kBAAkB;QAClC,GAAG,GAAG,CAAC,OAAO;KACf,CAAC;IAEF,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC5B,MAAM,EAAE,MAAM;QACd,OAAO;QACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC;YACvC,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YACjD,eAAe,EAAE,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE;SAC1E,CAAC;QACF,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,CAAC;KACrD,CAAC,CAAC;IAEH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,kCAAkC,IAAI,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAkE,CAAC;IAClG,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAChE,CAAC;AAED,MAAM,kBAAkB,GAAG;;;;;;;;;;;qCAWU,CAAC;AAE/B,KAAK,UAAU,oBAAoB,CACxC,cAAsB,EACtB,UAAkB,EAClB,GAAqB,EACrB,GAAW;IAEX,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,wCAAwC,CAAC;IACpE,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC9B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,QAAQ,UAAU,KAAK,WAAW,CAAC;IAClD,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,kBAAkB;QAClC,GAAG,GAAG,CAAC,OAAO;KACf,CAAC;IAEF,MAAM,WAAW,GAAG,kCAAkC,cAAc,0BAA0B,UAAU,EAAE,CAAC;IAE3G,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC5B,MAAM,EAAE,MAAM;QACd,OAAO;QACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC;YACtC,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;YAC9D,eAAe,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE;SACnD,CAAC;QACF,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,CAAC;KACrD,CAAC,CAAC;IAEH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAkE,CAAC;IAClG,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;IACpF,GAAG,CAAC,KAAK,CAAC,wBAAwB,MAAM,GAAG,CAAC,CAAC;IAC7C,OAAO,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;2CAoBY,CAAC;AAKrC,KAAK,UAAU,qBAAqB,CACzC,KAAa,EACb,UAAmE,EACnE,GAAqB,EACrB,GAAW;IAEX,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,wCAAwC,CAAC;IACpE,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC9B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,QAAQ,UAAU,KAAK,WAAW,CAAC;IAClD,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,kBAAkB;QAClC,GAAG,GAAG,CAAC,OAAO;KACf,CAAC;IAEF,MAAM,aAAa,GAAG,UAAU;SAC7B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;SAClD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC5B,MAAM,EAAE,MAAM;QACd,OAAO;QACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,CAAC;YAC1C,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,KAAK,oBAAoB,aAAa,EAAE,EAAE,CAAC,EAAE,CAAC;YACrG,eAAe,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE;SACpD,CAAC;QACF,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,CAAC;KACrD,CAAC,CAAC;IAEH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,mCAAmC,IAAI,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAkE,CAAC;IAClG,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;IACrE,OAAO,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAW,EAAE,GAAW;IACjD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACvC,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACjC,IAAI,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACvC,OAAO;oBACL,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;oBAChE,UAAU,EAAE,GAAG,CAAC,UAAU,KAAK,IAAI;iBACpC,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,GAAG,CAAC,IAAI,CAAC,gDAAgD,GAAG,iCAAiC,CAAC,CAAC;IAC/F,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AAC7C,CAAC;AAEM,KAAK,UAAU,gBAAgB,CACpC,IAAY,EACZ,GAAqB,EACrB,GAAW;IAEX,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,wCAAwC,CAAC;IACpE,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC9B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,yGAAyG,CAAC,CAAC;IAC7H,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,QAAQ,UAAU,KAAK,WAAW,CAAC;IAClD,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,kBAAkB;QAClC,GAAG,GAAG,CAAC,OAAO;KACf,CAAC;IAEF,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC5B,MAAM,EAAE,MAAM;QACd,OAAO;QACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;YACjC,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YACjD,eAAe,EAAE;gBACf,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,CAAC;gBACjC,SAAS,EAAE,GAAG;aACf;SACF,CAAC;QACF,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,CAAC;KACrD,CAAC,CAAC;IAEH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAE9B,CAAC;IACF,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAChE,CAAC;AAED,sBAAsB;AAEtB,qCAAgE;AAIzD,KAAK,UAAU,iBAAiB,CACrC,UAAkB,EAClB,UAAsE,EACtE,GAAqB,EACrB,GAAW;IAEX,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,wCAAwC,CAAC;IACpE,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC9B,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAE1E,MAAM,GAAG,GAAG,GAAG,QAAQ,UAAU,KAAK,WAAW,CAAC;IAClD,MAAM,OAAO,GAA2B,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;IAC/F,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEnF,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC5B,MAAM,EAAE,MAAM;QACd,OAAO;QACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,2BAAkB,EAAE,CAAC;YACtC,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,gBAAgB,UAAU,2BAA2B,aAAa,EAAE,EAAE,CAAC,EAAE,CAAC;YACvH,eAAe,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE;SACpD,CAAC;QACF,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,CAAC;KACrD,CAAC,CAAC;IAEH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAkE,CAAC;IAClG,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;IACrE,OAAO,IAAA,yBAAgB,EAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -1,3 +1,19 @@
|
|
|
1
1
|
import type { SummarizerConfig, Logger } from "../../types";
|
|
2
|
+
export declare function summarizeTaskGemini(text: string, cfg: SummarizerConfig, log: Logger): Promise<string>;
|
|
3
|
+
export declare function judgeNewTopicGemini(currentContext: string, newMessage: string, cfg: SummarizerConfig, log: Logger): Promise<boolean>;
|
|
4
|
+
import type { FilterResult } from "./openai";
|
|
5
|
+
export type { FilterResult } from "./openai";
|
|
6
|
+
export declare function filterRelevantGemini(query: string, candidates: Array<{
|
|
7
|
+
index: number;
|
|
8
|
+
summary: string;
|
|
9
|
+
role: string;
|
|
10
|
+
}>, cfg: SummarizerConfig, log: Logger): Promise<FilterResult>;
|
|
2
11
|
export declare function summarizeGemini(text: string, cfg: SummarizerConfig, log: Logger): Promise<string>;
|
|
12
|
+
import type { DedupResult } from "./openai";
|
|
13
|
+
export type { DedupResult } from "./openai";
|
|
14
|
+
export declare function judgeDedupGemini(newSummary: string, candidates: Array<{
|
|
15
|
+
index: number;
|
|
16
|
+
summary: string;
|
|
17
|
+
chunkId: string;
|
|
18
|
+
}>, cfg: SummarizerConfig, log: Logger): Promise<DedupResult>;
|
|
3
19
|
//# sourceMappingURL=gemini.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../../src/ingest/providers/gemini.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../../src/ingest/providers/gemini.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,CA8BjB;AAeD,wBAAsB,mBAAmB,CACvC,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,OAAO,CAAC,CAkClB;AAwBD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,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,CAmCvB;AAmBD,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CAgCjB;AAKD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,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,CA2BtB"}
|
|
@@ -1,7 +1,182 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.summarizeTaskGemini = summarizeTaskGemini;
|
|
4
|
+
exports.judgeNewTopicGemini = judgeNewTopicGemini;
|
|
5
|
+
exports.filterRelevantGemini = filterRelevantGemini;
|
|
3
6
|
exports.summarizeGemini = summarizeGemini;
|
|
4
|
-
|
|
7
|
+
exports.judgeDedupGemini = judgeDedupGemini;
|
|
8
|
+
const SYSTEM_PROMPT = `Summarize the text in ONE concise sentence (max 120 characters). IMPORTANT: Use the SAME language as the input text — if the input is Chinese, write Chinese; if English, write English. Preserve exact names, commands, error codes. No bullet points, no preamble — output only the sentence.`;
|
|
9
|
+
const TASK_SUMMARY_PROMPT = `You create a DETAILED task summary from a multi-turn conversation. This summary will be the ONLY record of this conversation, so it must preserve ALL important information.
|
|
10
|
+
|
|
11
|
+
CRITICAL LANGUAGE RULE: You MUST write in the SAME language as the user's messages. Chinese input → Chinese output. English input → English output. NEVER mix languages.
|
|
12
|
+
|
|
13
|
+
Output EXACTLY this structure:
|
|
14
|
+
|
|
15
|
+
📌 Title
|
|
16
|
+
A short, descriptive title (10-30 characters). Like a chat group name.
|
|
17
|
+
|
|
18
|
+
🎯 Goal
|
|
19
|
+
One sentence: what the user wanted to accomplish.
|
|
20
|
+
|
|
21
|
+
📋 Key Steps
|
|
22
|
+
- Describe each meaningful step in detail
|
|
23
|
+
- Include the ACTUAL content produced: code snippets, commands, config blocks, formulas, key paragraphs
|
|
24
|
+
- For code: include the function signature and core logic (up to ~30 lines per block), use fenced code blocks
|
|
25
|
+
- For configs: include the actual config values and structure
|
|
26
|
+
- For lists/instructions: include the actual items, not just "provided a list"
|
|
27
|
+
- Merge only truly trivial back-and-forth (like "ok" / "sure")
|
|
28
|
+
- Do NOT over-summarize: "provided a function" is BAD; show the actual function
|
|
29
|
+
|
|
30
|
+
✅ Result
|
|
31
|
+
What was the final outcome? Include the final version of any code/config/content produced.
|
|
32
|
+
|
|
33
|
+
💡 Key Details
|
|
34
|
+
- Decisions made, trade-offs discussed, caveats noted, alternative approaches mentioned
|
|
35
|
+
- Specific values: numbers, versions, thresholds, URLs, file paths, model names
|
|
36
|
+
- Omit this section only if there truly are no noteworthy details
|
|
37
|
+
|
|
38
|
+
RULES:
|
|
39
|
+
- This summary is a KNOWLEDGE BASE ENTRY, not a brief note. Be thorough.
|
|
40
|
+
- PRESERVE verbatim: code, commands, URLs, file paths, error messages, config values, version numbers, names, amounts
|
|
41
|
+
- DISCARD only: greetings, filler, the assistant explaining what it will do before doing it
|
|
42
|
+
- Replace secrets (API keys, tokens, passwords) with [REDACTED]
|
|
43
|
+
- Target length: 30-50% of the original conversation length. Longer conversations need longer summaries.
|
|
44
|
+
- Output summary only, no preamble.`;
|
|
45
|
+
async function summarizeTaskGemini(text, cfg, log) {
|
|
46
|
+
const model = cfg.model ?? "gemini-1.5-flash";
|
|
47
|
+
const endpoint = cfg.endpoint ??
|
|
48
|
+
`https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent`;
|
|
49
|
+
const url = `${endpoint}?key=${cfg.apiKey}`;
|
|
50
|
+
const headers = {
|
|
51
|
+
"Content-Type": "application/json",
|
|
52
|
+
...cfg.headers,
|
|
53
|
+
};
|
|
54
|
+
const resp = await fetch(url, {
|
|
55
|
+
method: "POST",
|
|
56
|
+
headers,
|
|
57
|
+
body: JSON.stringify({
|
|
58
|
+
systemInstruction: { parts: [{ text: TASK_SUMMARY_PROMPT }] },
|
|
59
|
+
contents: [{ parts: [{ text }] }],
|
|
60
|
+
generationConfig: { temperature: cfg.temperature ?? 0.1, maxOutputTokens: 4096 },
|
|
61
|
+
}),
|
|
62
|
+
signal: AbortSignal.timeout(cfg.timeoutMs ?? 60_000),
|
|
63
|
+
});
|
|
64
|
+
if (!resp.ok) {
|
|
65
|
+
const body = await resp.text();
|
|
66
|
+
throw new Error(`Gemini task-summarize failed (${resp.status}): ${body}`);
|
|
67
|
+
}
|
|
68
|
+
const json = (await resp.json());
|
|
69
|
+
return json.candidates?.[0]?.content?.parts?.[0]?.text?.trim() ?? "";
|
|
70
|
+
}
|
|
71
|
+
const TOPIC_JUDGE_PROMPT = `You are a conversation topic boundary detector. Given a summary of the CURRENT conversation and a NEW user message, determine if the new message starts a DIFFERENT topic/task.
|
|
72
|
+
|
|
73
|
+
Answer ONLY "NEW" or "SAME".
|
|
74
|
+
|
|
75
|
+
Rules:
|
|
76
|
+
- "NEW" = the new message is about a completely different subject, project, or task
|
|
77
|
+
- "SAME" = the new message continues, follows up on, or is closely related to the current topic
|
|
78
|
+
- Follow-up questions, clarifications, refinements, bug fixes, or next steps on the same task = SAME
|
|
79
|
+
- Greetings or meta-questions like "你好" or "谢谢" without new substance = SAME
|
|
80
|
+
- A clearly unrelated request (e.g., current topic is deployment, new message asks about cooking) = NEW
|
|
81
|
+
|
|
82
|
+
Output exactly one word: NEW or SAME`;
|
|
83
|
+
async function judgeNewTopicGemini(currentContext, newMessage, cfg, log) {
|
|
84
|
+
const model = cfg.model ?? "gemini-1.5-flash";
|
|
85
|
+
const endpoint = cfg.endpoint ??
|
|
86
|
+
`https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent`;
|
|
87
|
+
const url = `${endpoint}?key=${cfg.apiKey}`;
|
|
88
|
+
const headers = {
|
|
89
|
+
"Content-Type": "application/json",
|
|
90
|
+
...cfg.headers,
|
|
91
|
+
};
|
|
92
|
+
const userContent = `CURRENT CONVERSATION SUMMARY:\n${currentContext}\n\nNEW USER MESSAGE:\n${newMessage}`;
|
|
93
|
+
const resp = await fetch(url, {
|
|
94
|
+
method: "POST",
|
|
95
|
+
headers,
|
|
96
|
+
body: JSON.stringify({
|
|
97
|
+
systemInstruction: { parts: [{ text: TOPIC_JUDGE_PROMPT }] },
|
|
98
|
+
contents: [{ parts: [{ text: userContent }] }],
|
|
99
|
+
generationConfig: { temperature: 0, maxOutputTokens: 10 },
|
|
100
|
+
}),
|
|
101
|
+
signal: AbortSignal.timeout(cfg.timeoutMs ?? 15_000),
|
|
102
|
+
});
|
|
103
|
+
if (!resp.ok) {
|
|
104
|
+
const body = await resp.text();
|
|
105
|
+
throw new Error(`Gemini topic-judge failed (${resp.status}): ${body}`);
|
|
106
|
+
}
|
|
107
|
+
const json = (await resp.json());
|
|
108
|
+
const answer = json.candidates?.[0]?.content?.parts?.[0]?.text?.trim().toUpperCase() ?? "";
|
|
109
|
+
log.debug(`Topic judge result: "${answer}"`);
|
|
110
|
+
return answer.startsWith("NEW");
|
|
111
|
+
}
|
|
112
|
+
const FILTER_RELEVANT_PROMPT = `You are a memory relevance judge. Given a user's QUERY and a list of CANDIDATE memory summaries, do two things:
|
|
113
|
+
|
|
114
|
+
1. Select ALL candidates that could be useful for answering the query. When in doubt, INCLUDE the candidate.
|
|
115
|
+
- For questions about lists, history, or "what/where/who" across multiple items (e.g. "which companies did I work at"), include ALL matching items — do NOT stop at the first match.
|
|
116
|
+
- For factual lookups (e.g. "what is the SSH port"), a single direct answer is enough.
|
|
117
|
+
2. Judge whether the selected memories are SUFFICIENT to fully answer the query WITHOUT fetching additional context.
|
|
118
|
+
|
|
119
|
+
IMPORTANT for "sufficient" judgment:
|
|
120
|
+
- sufficient=true ONLY when the memories contain a concrete ANSWER, fact, decision, or actionable information that directly addresses the query.
|
|
121
|
+
- sufficient=false when:
|
|
122
|
+
- The memories only repeat the same question the user asked before (echo, not answer).
|
|
123
|
+
- The memories show related topics but lack the specific detail needed.
|
|
124
|
+
- The memories contain partial information that would benefit from full task context, timeline, or related skills.
|
|
125
|
+
|
|
126
|
+
Output a JSON object with exactly two fields:
|
|
127
|
+
{"relevant":[1,3,5],"sufficient":true}
|
|
128
|
+
|
|
129
|
+
- "relevant": array of candidate numbers that are useful. Empty array [] if none are relevant.
|
|
130
|
+
- "sufficient": true ONLY if the memories contain a direct answer; false otherwise.
|
|
131
|
+
|
|
132
|
+
Output ONLY the JSON object, nothing else.`;
|
|
133
|
+
async function filterRelevantGemini(query, candidates, cfg, log) {
|
|
134
|
+
const model = cfg.model ?? "gemini-1.5-flash";
|
|
135
|
+
const endpoint = cfg.endpoint ??
|
|
136
|
+
`https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent`;
|
|
137
|
+
const url = `${endpoint}?key=${cfg.apiKey}`;
|
|
138
|
+
const headers = {
|
|
139
|
+
"Content-Type": "application/json",
|
|
140
|
+
...cfg.headers,
|
|
141
|
+
};
|
|
142
|
+
const candidateText = candidates
|
|
143
|
+
.map((c) => `${c.index}. [${c.role}] ${c.summary}`)
|
|
144
|
+
.join("\n");
|
|
145
|
+
const resp = await fetch(url, {
|
|
146
|
+
method: "POST",
|
|
147
|
+
headers,
|
|
148
|
+
body: JSON.stringify({
|
|
149
|
+
systemInstruction: { parts: [{ text: FILTER_RELEVANT_PROMPT }] },
|
|
150
|
+
contents: [{ parts: [{ text: `QUERY: ${query}\n\nCANDIDATES:\n${candidateText}` }] }],
|
|
151
|
+
generationConfig: { temperature: 0, maxOutputTokens: 200 },
|
|
152
|
+
}),
|
|
153
|
+
signal: AbortSignal.timeout(cfg.timeoutMs ?? 15_000),
|
|
154
|
+
});
|
|
155
|
+
if (!resp.ok) {
|
|
156
|
+
const body = await resp.text();
|
|
157
|
+
throw new Error(`Gemini filter-relevant failed (${resp.status}): ${body}`);
|
|
158
|
+
}
|
|
159
|
+
const json = (await resp.json());
|
|
160
|
+
const raw = json.candidates?.[0]?.content?.parts?.[0]?.text?.trim() ?? "{}";
|
|
161
|
+
return parseFilterResult(raw, log);
|
|
162
|
+
}
|
|
163
|
+
function parseFilterResult(raw, log) {
|
|
164
|
+
try {
|
|
165
|
+
const match = raw.match(/\{[\s\S]*\}/);
|
|
166
|
+
if (match) {
|
|
167
|
+
const obj = JSON.parse(match[0]);
|
|
168
|
+
if (obj && Array.isArray(obj.relevant)) {
|
|
169
|
+
return {
|
|
170
|
+
relevant: obj.relevant.filter((n) => typeof n === "number"),
|
|
171
|
+
sufficient: obj.sufficient === true,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
catch { }
|
|
177
|
+
log.warn(`filterRelevant: failed to parse LLM output: "${raw}", fallback to all+insufficient`);
|
|
178
|
+
return { relevant: [], sufficient: false };
|
|
179
|
+
}
|
|
5
180
|
async function summarizeGemini(text, cfg, log) {
|
|
6
181
|
const model = cfg.model ?? "gemini-1.5-flash";
|
|
7
182
|
const endpoint = cfg.endpoint ??
|
|
@@ -28,4 +203,30 @@ async function summarizeGemini(text, cfg, log) {
|
|
|
28
203
|
const json = (await resp.json());
|
|
29
204
|
return json.candidates?.[0]?.content?.parts?.[0]?.text?.trim() ?? "";
|
|
30
205
|
}
|
|
206
|
+
// ─── Smart Dedup ───
|
|
207
|
+
const openai_1 = require("./openai");
|
|
208
|
+
async function judgeDedupGemini(newSummary, candidates, cfg, log) {
|
|
209
|
+
const model = cfg.model ?? "gemini-1.5-flash";
|
|
210
|
+
const endpoint = cfg.endpoint ?? `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent`;
|
|
211
|
+
const url = `${endpoint}?key=${cfg.apiKey}`;
|
|
212
|
+
const headers = { "Content-Type": "application/json", ...cfg.headers };
|
|
213
|
+
const candidateText = candidates.map((c) => `${c.index}. ${c.summary}`).join("\n");
|
|
214
|
+
const resp = await fetch(url, {
|
|
215
|
+
method: "POST",
|
|
216
|
+
headers,
|
|
217
|
+
body: JSON.stringify({
|
|
218
|
+
systemInstruction: { parts: [{ text: openai_1.DEDUP_JUDGE_PROMPT }] },
|
|
219
|
+
contents: [{ parts: [{ text: `NEW MEMORY:\n${newSummary}\n\nEXISTING MEMORIES:\n${candidateText}` }] }],
|
|
220
|
+
generationConfig: { temperature: 0, maxOutputTokens: 300 },
|
|
221
|
+
}),
|
|
222
|
+
signal: AbortSignal.timeout(cfg.timeoutMs ?? 15_000),
|
|
223
|
+
});
|
|
224
|
+
if (!resp.ok) {
|
|
225
|
+
const body = await resp.text();
|
|
226
|
+
throw new Error(`Gemini dedup-judge failed (${resp.status}): ${body}`);
|
|
227
|
+
}
|
|
228
|
+
const json = (await resp.json());
|
|
229
|
+
const raw = json.candidates?.[0]?.content?.parts?.[0]?.text?.trim() ?? "{}";
|
|
230
|
+
return (0, openai_1.parseDedupResult)(raw, log);
|
|
231
|
+
}
|
|
31
232
|
//# sourceMappingURL=gemini.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../../src/ingest/providers/gemini.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../../src/ingest/providers/gemini.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,40 @@
|
|
|
1
1
|
import type { SummarizerConfig, Logger } from "../../types";
|
|
2
|
+
import type { FilterResult, DedupResult } from "./openai";
|
|
3
|
+
export type { FilterResult, DedupResult } from "./openai";
|
|
2
4
|
export declare class Summarizer {
|
|
3
5
|
private cfg;
|
|
4
6
|
private log;
|
|
5
7
|
constructor(cfg: SummarizerConfig | undefined, log: Logger);
|
|
6
8
|
summarize(text: string): Promise<string>;
|
|
9
|
+
summarizeTask(text: string): Promise<string>;
|
|
7
10
|
private callProvider;
|
|
11
|
+
/**
|
|
12
|
+
* Ask the LLM whether the new message starts a different topic from the current conversation.
|
|
13
|
+
* Returns true if it's a new topic, false if it continues the current one.
|
|
14
|
+
* Returns null if no summarizer is configured (caller should fall back to heuristic).
|
|
15
|
+
*/
|
|
16
|
+
judgeNewTopic(currentContext: string, newMessage: string): Promise<boolean | null>;
|
|
17
|
+
private callTopicJudge;
|
|
18
|
+
/**
|
|
19
|
+
* Filter search results by LLM relevance judgment.
|
|
20
|
+
* Returns { relevant: number[], sufficient: boolean } or null if no summarizer configured.
|
|
21
|
+
*/
|
|
22
|
+
filterRelevant(query: string, candidates: Array<{
|
|
23
|
+
index: number;
|
|
24
|
+
summary: string;
|
|
25
|
+
role: string;
|
|
26
|
+
}>): Promise<FilterResult | null>;
|
|
27
|
+
private callFilterRelevant;
|
|
28
|
+
/**
|
|
29
|
+
* Judge whether a new memory is DUPLICATE / UPDATE / NEW relative to similar existing memories.
|
|
30
|
+
* Returns null if no summarizer configured (caller should treat as NEW).
|
|
31
|
+
*/
|
|
32
|
+
judgeDedup(newSummary: string, candidates: Array<{
|
|
33
|
+
index: number;
|
|
34
|
+
summary: string;
|
|
35
|
+
chunkId: string;
|
|
36
|
+
}>): Promise<DedupResult | null>;
|
|
37
|
+
private callJudgeDedup;
|
|
38
|
+
private callTaskProvider;
|
|
8
39
|
}
|
|
9
40
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ingest/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ingest/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE5D,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC1D,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAK1D,qBAAa,UAAU;IAEnB,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,GAAG;gBADH,GAAG,EAAE,gBAAgB,GAAG,SAAS,EACjC,GAAG,EAAE,MAAM;IAGf,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAaxC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAapC,YAAY;IAmB1B;;;;OAIG;IACG,aAAa,CAAC,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;YAW1E,cAAc;IAkB5B;;;OAGG;IACG,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,GAClE,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;YAYjB,kBAAkB;IAqBhC;;;OAGG;IACG,UAAU,CACd,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,GACrE,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;YAYhB,cAAc;YAqBd,gBAAgB;CAiB/B"}
|