agentx-sdk 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 +561 -0
- package/dist/agent.d.ts +105 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +690 -0
- package/dist/agent.js.map +1 -0
- package/dist/config/config.d.ts +346 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +93 -0
- package/dist/config/config.js.map +1 -0
- package/dist/contracts/entities/agent-event.d.ts +97 -0
- package/dist/contracts/entities/agent-event.d.ts.map +1 -0
- package/dist/contracts/entities/agent-event.js +2 -0
- package/dist/contracts/entities/agent-event.js.map +1 -0
- package/dist/contracts/entities/agent-skill.d.ts +59 -0
- package/dist/contracts/entities/agent-skill.d.ts.map +1 -0
- package/dist/contracts/entities/agent-skill.js +2 -0
- package/dist/contracts/entities/agent-skill.js.map +1 -0
- package/dist/contracts/entities/agent-tool.d.ts +42 -0
- package/dist/contracts/entities/agent-tool.d.ts.map +1 -0
- package/dist/contracts/entities/agent-tool.js +2 -0
- package/dist/contracts/entities/agent-tool.js.map +1 -0
- package/dist/contracts/entities/chat-message.d.ts +13 -0
- package/dist/contracts/entities/chat-message.d.ts.map +1 -0
- package/dist/contracts/entities/chat-message.js +2 -0
- package/dist/contracts/entities/chat-message.js.map +1 -0
- package/dist/contracts/entities/content-part.d.ts +16 -0
- package/dist/contracts/entities/content-part.d.ts.map +1 -0
- package/dist/contracts/entities/content-part.js +2 -0
- package/dist/contracts/entities/content-part.js.map +1 -0
- package/dist/contracts/entities/execution-context.d.ts +9 -0
- package/dist/contracts/entities/execution-context.d.ts.map +1 -0
- package/dist/contracts/entities/execution-context.js +2 -0
- package/dist/contracts/entities/execution-context.js.map +1 -0
- package/dist/contracts/entities/index.d.ts +11 -0
- package/dist/contracts/entities/index.d.ts.map +1 -0
- package/dist/contracts/entities/index.js +2 -0
- package/dist/contracts/entities/index.js.map +1 -0
- package/dist/contracts/entities/knowledge.d.ts +21 -0
- package/dist/contracts/entities/knowledge.d.ts.map +1 -0
- package/dist/contracts/entities/knowledge.js +2 -0
- package/dist/contracts/entities/knowledge.js.map +1 -0
- package/dist/contracts/entities/stores.d.ts +18 -0
- package/dist/contracts/entities/stores.d.ts.map +1 -0
- package/dist/contracts/entities/stores.js +2 -0
- package/dist/contracts/entities/stores.js.map +1 -0
- package/dist/contracts/entities/token-usage.d.ts +7 -0
- package/dist/contracts/entities/token-usage.d.ts.map +1 -0
- package/dist/contracts/entities/token-usage.js +2 -0
- package/dist/contracts/entities/token-usage.js.map +1 -0
- package/dist/contracts/entities/tool-call.d.ts +16 -0
- package/dist/contracts/entities/tool-call.d.ts.map +1 -0
- package/dist/contracts/entities/tool-call.js +2 -0
- package/dist/contracts/entities/tool-call.js.map +1 -0
- package/dist/contracts/enums/index.d.ts +21 -0
- package/dist/contracts/enums/index.d.ts.map +1 -0
- package/dist/contracts/enums/index.js +8 -0
- package/dist/contracts/enums/index.js.map +1 -0
- package/dist/contracts/index.d.ts +3 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +3 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/core/compaction/autocompact.d.ts +18 -0
- package/dist/core/compaction/autocompact.d.ts.map +1 -0
- package/dist/core/compaction/autocompact.js +68 -0
- package/dist/core/compaction/autocompact.js.map +1 -0
- package/dist/core/compaction/microcompact.d.ts +20 -0
- package/dist/core/compaction/microcompact.d.ts.map +1 -0
- package/dist/core/compaction/microcompact.js +38 -0
- package/dist/core/compaction/microcompact.js.map +1 -0
- package/dist/core/compaction/snip-compact.d.ts +22 -0
- package/dist/core/compaction/snip-compact.d.ts.map +1 -0
- package/dist/core/compaction/snip-compact.js +61 -0
- package/dist/core/compaction/snip-compact.js.map +1 -0
- package/dist/core/compaction/tool-result-budget.d.ts +24 -0
- package/dist/core/compaction/tool-result-budget.d.ts.map +1 -0
- package/dist/core/compaction/tool-result-budget.js +67 -0
- package/dist/core/compaction/tool-result-budget.js.map +1 -0
- package/dist/core/context-analysis.d.ts +24 -0
- package/dist/core/context-analysis.d.ts.map +1 -0
- package/dist/core/context-analysis.js +37 -0
- package/dist/core/context-analysis.js.map +1 -0
- package/dist/core/context-builder.d.ts +25 -0
- package/dist/core/context-builder.d.ts.map +1 -0
- package/dist/core/context-builder.js +108 -0
- package/dist/core/context-builder.js.map +1 -0
- package/dist/core/conversation-manager.d.ts +19 -0
- package/dist/core/conversation-manager.d.ts.map +1 -0
- package/dist/core/conversation-manager.js +62 -0
- package/dist/core/conversation-manager.js.map +1 -0
- package/dist/core/execution-context.d.ts +6 -0
- package/dist/core/execution-context.d.ts.map +1 -0
- package/dist/core/execution-context.js +14 -0
- package/dist/core/execution-context.js.map +1 -0
- package/dist/core/loop-deps.d.ts +15 -0
- package/dist/core/loop-deps.d.ts.map +1 -0
- package/dist/core/loop-deps.js +8 -0
- package/dist/core/loop-deps.js.map +1 -0
- package/dist/core/loop-types.d.ts +34 -0
- package/dist/core/loop-types.d.ts.map +1 -0
- package/dist/core/loop-types.js +15 -0
- package/dist/core/loop-types.js.map +1 -0
- package/dist/core/message-normalize.d.ts +18 -0
- package/dist/core/message-normalize.d.ts.map +1 -0
- package/dist/core/message-normalize.js +69 -0
- package/dist/core/message-normalize.js.map +1 -0
- package/dist/core/prompt-builders.d.ts +36 -0
- package/dist/core/prompt-builders.d.ts.map +1 -0
- package/dist/core/prompt-builders.js +89 -0
- package/dist/core/prompt-builders.js.map +1 -0
- package/dist/core/prompt-cache.d.ts +25 -0
- package/dist/core/prompt-cache.d.ts.map +1 -0
- package/dist/core/prompt-cache.js +34 -0
- package/dist/core/prompt-cache.js.map +1 -0
- package/dist/core/react-loop.d.ts +43 -0
- package/dist/core/react-loop.d.ts.map +1 -0
- package/dist/core/react-loop.js +403 -0
- package/dist/core/react-loop.js.map +1 -0
- package/dist/core/stop-hooks.d.ts +18 -0
- package/dist/core/stop-hooks.d.ts.map +1 -0
- package/dist/core/stop-hooks.js +18 -0
- package/dist/core/stop-hooks.js.map +1 -0
- package/dist/core/stream-emitter.d.ts +24 -0
- package/dist/core/stream-emitter.d.ts.map +1 -0
- package/dist/core/stream-emitter.js +65 -0
- package/dist/core/stream-emitter.js.map +1 -0
- package/dist/core/streaming-tool-executor.d.ts +54 -0
- package/dist/core/streaming-tool-executor.d.ts.map +1 -0
- package/dist/core/streaming-tool-executor.js +164 -0
- package/dist/core/streaming-tool-executor.js.map +1 -0
- package/dist/core/turn-end-hooks.d.ts +39 -0
- package/dist/core/turn-end-hooks.d.ts.map +1 -0
- package/dist/core/turn-end-hooks.js +36 -0
- package/dist/core/turn-end-hooks.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge/chunking.d.ts +9 -0
- package/dist/knowledge/chunking.d.ts.map +1 -0
- package/dist/knowledge/chunking.js +49 -0
- package/dist/knowledge/chunking.js.map +1 -0
- package/dist/knowledge/embedding-service.d.ts +16 -0
- package/dist/knowledge/embedding-service.d.ts.map +1 -0
- package/dist/knowledge/embedding-service.js +43 -0
- package/dist/knowledge/embedding-service.js.map +1 -0
- package/dist/knowledge/knowledge-manager.d.ts +33 -0
- package/dist/knowledge/knowledge-manager.d.ts.map +1 -0
- package/dist/knowledge/knowledge-manager.js +62 -0
- package/dist/knowledge/knowledge-manager.js.map +1 -0
- package/dist/knowledge/sqlite-vector-store.d.ts +16 -0
- package/dist/knowledge/sqlite-vector-store.d.ts.map +1 -0
- package/dist/knowledge/sqlite-vector-store.js +56 -0
- package/dist/knowledge/sqlite-vector-store.js.map +1 -0
- package/dist/knowledge/vector-store.d.ts +2 -0
- package/dist/knowledge/vector-store.d.ts.map +1 -0
- package/dist/knowledge/vector-store.js +2 -0
- package/dist/knowledge/vector-store.js.map +1 -0
- package/dist/llm/errors.d.ts +15 -0
- package/dist/llm/errors.d.ts.map +1 -0
- package/dist/llm/errors.js +39 -0
- package/dist/llm/errors.js.map +1 -0
- package/dist/llm/message-types.d.ts +80 -0
- package/dist/llm/message-types.d.ts.map +1 -0
- package/dist/llm/message-types.js +2 -0
- package/dist/llm/message-types.js.map +1 -0
- package/dist/llm/openrouter-client.d.ts +18 -0
- package/dist/llm/openrouter-client.d.ts.map +1 -0
- package/dist/llm/openrouter-client.js +215 -0
- package/dist/llm/openrouter-client.js.map +1 -0
- package/dist/llm/reasoning.d.ts +10 -0
- package/dist/llm/reasoning.d.ts.map +1 -0
- package/dist/llm/reasoning.js +18 -0
- package/dist/llm/reasoning.js.map +1 -0
- package/dist/memory/file-memory-system.d.ts +98 -0
- package/dist/memory/file-memory-system.d.ts.map +1 -0
- package/dist/memory/file-memory-system.js +310 -0
- package/dist/memory/file-memory-system.js.map +1 -0
- package/dist/memory/memory-age.d.ts +22 -0
- package/dist/memory/memory-age.d.ts.map +1 -0
- package/dist/memory/memory-age.js +44 -0
- package/dist/memory/memory-age.js.map +1 -0
- package/dist/memory/memory-extractor.d.ts +56 -0
- package/dist/memory/memory-extractor.d.ts.map +1 -0
- package/dist/memory/memory-extractor.js +91 -0
- package/dist/memory/memory-extractor.js.map +1 -0
- package/dist/memory/memory-paths.d.ts +45 -0
- package/dist/memory/memory-paths.d.ts.map +1 -0
- package/dist/memory/memory-paths.js +121 -0
- package/dist/memory/memory-paths.js.map +1 -0
- package/dist/memory/memory-prompts.d.ts +41 -0
- package/dist/memory/memory-prompts.d.ts.map +1 -0
- package/dist/memory/memory-prompts.js +279 -0
- package/dist/memory/memory-prompts.js.map +1 -0
- package/dist/memory/memory-relevance.d.ts +16 -0
- package/dist/memory/memory-relevance.d.ts.map +1 -0
- package/dist/memory/memory-relevance.js +46 -0
- package/dist/memory/memory-relevance.js.map +1 -0
- package/dist/memory/memory-scanner.d.ts +22 -0
- package/dist/memory/memory-scanner.d.ts.map +1 -0
- package/dist/memory/memory-scanner.js +99 -0
- package/dist/memory/memory-scanner.js.map +1 -0
- package/dist/memory/memory-tools.d.ts +16 -0
- package/dist/memory/memory-tools.d.ts.map +1 -0
- package/dist/memory/memory-tools.js +196 -0
- package/dist/memory/memory-tools.js.map +1 -0
- package/dist/memory/memory-types.d.ts +47 -0
- package/dist/memory/memory-types.d.ts.map +1 -0
- package/dist/memory/memory-types.js +24 -0
- package/dist/memory/memory-types.js.map +1 -0
- package/dist/skills/skill-args.d.ts +23 -0
- package/dist/skills/skill-args.d.ts.map +1 -0
- package/dist/skills/skill-args.js +77 -0
- package/dist/skills/skill-args.js.map +1 -0
- package/dist/skills/skill-glob.d.ts +24 -0
- package/dist/skills/skill-glob.d.ts.map +1 -0
- package/dist/skills/skill-glob.js +60 -0
- package/dist/skills/skill-glob.js.map +1 -0
- package/dist/skills/skill-loader.d.ts +49 -0
- package/dist/skills/skill-loader.d.ts.map +1 -0
- package/dist/skills/skill-loader.js +197 -0
- package/dist/skills/skill-loader.js.map +1 -0
- package/dist/skills/skill-manager.d.ts +83 -0
- package/dist/skills/skill-manager.d.ts.map +1 -0
- package/dist/skills/skill-manager.js +338 -0
- package/dist/skills/skill-manager.js.map +1 -0
- package/dist/storage/sqlite-conversation-store.d.ts +15 -0
- package/dist/storage/sqlite-conversation-store.d.ts.map +1 -0
- package/dist/storage/sqlite-conversation-store.js +45 -0
- package/dist/storage/sqlite-conversation-store.js.map +1 -0
- package/dist/storage/sqlite-database.d.ts +14 -0
- package/dist/storage/sqlite-database.d.ts.map +1 -0
- package/dist/storage/sqlite-database.js +95 -0
- package/dist/storage/sqlite-database.js.map +1 -0
- package/dist/tools/builtin/ask-user.d.ts +7 -0
- package/dist/tools/builtin/ask-user.d.ts.map +1 -0
- package/dist/tools/builtin/ask-user.js +23 -0
- package/dist/tools/builtin/ask-user.js.map +1 -0
- package/dist/tools/builtin/bash.d.ts +3 -0
- package/dist/tools/builtin/bash.d.ts.map +1 -0
- package/dist/tools/builtin/bash.js +54 -0
- package/dist/tools/builtin/bash.js.map +1 -0
- package/dist/tools/builtin/file-edit.d.ts +3 -0
- package/dist/tools/builtin/file-edit.d.ts.map +1 -0
- package/dist/tools/builtin/file-edit.js +50 -0
- package/dist/tools/builtin/file-edit.js.map +1 -0
- package/dist/tools/builtin/file-read.d.ts +3 -0
- package/dist/tools/builtin/file-read.d.ts.map +1 -0
- package/dist/tools/builtin/file-read.js +47 -0
- package/dist/tools/builtin/file-read.js.map +1 -0
- package/dist/tools/builtin/file-write.d.ts +3 -0
- package/dist/tools/builtin/file-write.d.ts.map +1 -0
- package/dist/tools/builtin/file-write.js +29 -0
- package/dist/tools/builtin/file-write.js.map +1 -0
- package/dist/tools/builtin/glob.d.ts +3 -0
- package/dist/tools/builtin/glob.d.ts.map +1 -0
- package/dist/tools/builtin/glob.js +67 -0
- package/dist/tools/builtin/glob.js.map +1 -0
- package/dist/tools/builtin/grep.d.ts +3 -0
- package/dist/tools/builtin/grep.d.ts.map +1 -0
- package/dist/tools/builtin/grep.js +94 -0
- package/dist/tools/builtin/grep.js.map +1 -0
- package/dist/tools/builtin/index.d.ts +49 -0
- package/dist/tools/builtin/index.d.ts.map +1 -0
- package/dist/tools/builtin/index.js +65 -0
- package/dist/tools/builtin/index.js.map +1 -0
- package/dist/tools/builtin/web-fetch.d.ts +3 -0
- package/dist/tools/builtin/web-fetch.d.ts.map +1 -0
- package/dist/tools/builtin/web-fetch.js +56 -0
- package/dist/tools/builtin/web-fetch.js.map +1 -0
- package/dist/tools/json-schema-to-zod.d.ts +30 -0
- package/dist/tools/json-schema-to-zod.d.ts.map +1 -0
- package/dist/tools/json-schema-to-zod.js +123 -0
- package/dist/tools/json-schema-to-zod.js.map +1 -0
- package/dist/tools/mcp-adapter.d.ts +80 -0
- package/dist/tools/mcp-adapter.d.ts.map +1 -0
- package/dist/tools/mcp-adapter.js +326 -0
- package/dist/tools/mcp-adapter.js.map +1 -0
- package/dist/tools/skill-tool.d.ts +41 -0
- package/dist/tools/skill-tool.d.ts.map +1 -0
- package/dist/tools/skill-tool.js +149 -0
- package/dist/tools/skill-tool.js.map +1 -0
- package/dist/tools/sql/index.d.ts +4 -0
- package/dist/tools/sql/index.d.ts.map +1 -0
- package/dist/tools/sql/index.js +2 -0
- package/dist/tools/sql/index.js.map +1 -0
- package/dist/tools/sql/sql-query-def.d.ts +22 -0
- package/dist/tools/sql/sql-query-def.d.ts.map +1 -0
- package/dist/tools/sql/sql-query-def.js +2 -0
- package/dist/tools/sql/sql-query-def.js.map +1 -0
- package/dist/tools/sql/sql-tool-factory.d.ts +28 -0
- package/dist/tools/sql/sql-tool-factory.d.ts.map +1 -0
- package/dist/tools/sql/sql-tool-factory.js +136 -0
- package/dist/tools/sql/sql-tool-factory.js.map +1 -0
- package/dist/tools/tool-executor.d.ts +67 -0
- package/dist/tools/tool-executor.d.ts.map +1 -0
- package/dist/tools/tool-executor.js +232 -0
- package/dist/tools/tool-executor.js.map +1 -0
- package/dist/utils/cache.d.ts +22 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +61 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/logger.d.ts +15 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +46 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/model-context.d.ts +14 -0
- package/dist/utils/model-context.d.ts.map +1 -0
- package/dist/utils/model-context.js +52 -0
- package/dist/utils/model-context.js.map +1 -0
- package/dist/utils/retry.d.ts +13 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +41 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/token-counter.d.ts +6 -0
- package/dist/utils/token-counter.d.ts.map +1 -0
- package/dist/utils/token-counter.js +19 -0
- package/dist/utils/token-counter.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Snip compact — removes low-value early messages before autocompact.
|
|
3
|
+
*
|
|
4
|
+
* Targets orphaned tool results (results not referenced by later messages)
|
|
5
|
+
* in the compactable region (outside tail protection).
|
|
6
|
+
*
|
|
7
|
+
* Runs between tool-result-budget and autocompact in the compaction pipeline.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Remove orphaned tool results from early messages.
|
|
11
|
+
* Preserves: system messages, pinned messages, tail messages.
|
|
12
|
+
*/
|
|
13
|
+
export function snipCompact(messages, options) {
|
|
14
|
+
const { tailProtection } = options;
|
|
15
|
+
if (messages.length === 0)
|
|
16
|
+
return { messages: [], snippedCount: 0 };
|
|
17
|
+
// Separate protected messages
|
|
18
|
+
const system = messages.filter(m => m.role === 'system');
|
|
19
|
+
const pinned = messages.filter(m => m._pinned === true && m.role !== 'system');
|
|
20
|
+
const rest = messages.filter(m => m.role !== 'system' && m._pinned !== true);
|
|
21
|
+
const tailCount = Math.min(tailProtection, rest.length);
|
|
22
|
+
const early = rest.slice(0, rest.length - tailCount);
|
|
23
|
+
const tail = rest.slice(-tailCount);
|
|
24
|
+
if (early.length === 0) {
|
|
25
|
+
return { messages: [...messages], snippedCount: 0 };
|
|
26
|
+
}
|
|
27
|
+
// Find tool_call_ids that have a matching assistant tool_call anywhere (early + tail)
|
|
28
|
+
const referencedIds = new Set();
|
|
29
|
+
// From tail: both tool_call_id references and assistant tool_calls
|
|
30
|
+
for (const msg of tail) {
|
|
31
|
+
if (msg.tool_call_id)
|
|
32
|
+
referencedIds.add(msg.tool_call_id);
|
|
33
|
+
if (msg.tool_calls) {
|
|
34
|
+
for (const tc of msg.tool_calls) {
|
|
35
|
+
referencedIds.add(tc.id);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// From early: only assistant tool_calls (not tool results referencing themselves)
|
|
40
|
+
for (const msg of early) {
|
|
41
|
+
if (msg.tool_calls) {
|
|
42
|
+
for (const tc of msg.tool_calls) {
|
|
43
|
+
referencedIds.add(tc.id);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Remove orphaned tool results from early messages
|
|
48
|
+
let snippedCount = 0;
|
|
49
|
+
const keptEarly = early.filter(msg => {
|
|
50
|
+
if (msg.role === 'tool' && msg.tool_call_id && !referencedIds.has(msg.tool_call_id)) {
|
|
51
|
+
snippedCount++;
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
return true;
|
|
55
|
+
});
|
|
56
|
+
return {
|
|
57
|
+
messages: [...system, ...pinned, ...keptEarly, ...tail],
|
|
58
|
+
snippedCount,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=snip-compact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snip-compact.js","sourceRoot":"","sources":["../../../src/core/compaction/snip-compact.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH;;;GAGG;AACH,MAAM,UAAU,WAAW,CACzB,QAAsC,EACtC,OAA2B;IAE3B,MAAM,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;IAEnC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;IAEpE,8BAA8B;IAC9B,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAE,CAAwC,CAAC,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACvH,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAK,CAAwC,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC;IAErH,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACrD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC;IAEpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,QAAQ,EAAE,CAAC,GAAG,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;IACtD,CAAC;IAED,sFAAsF;IACtF,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;IACxC,mEAAmE;IACnE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,YAAY;YAAE,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC1D,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YACnB,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;gBAChC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IACD,kFAAkF;IAClF,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YACnB,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;gBAChC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAED,mDAAmD;IACnD,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;QACnC,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,YAAY,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YACpF,YAAY,EAAE,CAAC;YACf,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,QAAQ,EAAE,CAAC,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,SAAS,EAAE,GAAG,IAAI,CAAC;QACvD,YAAY;KACb,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool result budget — aggregate truncation of large tool results.
|
|
3
|
+
*
|
|
4
|
+
* Runs BEFORE microcompact. While microcompact truncates individual messages
|
|
5
|
+
* to a per-message limit, tool-result-budget enforces a GLOBAL budget across
|
|
6
|
+
* all tool result messages. When total tool result chars exceed the budget,
|
|
7
|
+
* the largest results are truncated first.
|
|
8
|
+
*
|
|
9
|
+
* Ported from old_src/utils/toolResultStorage.ts applyToolResultBudget().
|
|
10
|
+
*/
|
|
11
|
+
import type { OpenRouterMessage } from '../../llm/message-types.js';
|
|
12
|
+
export interface ToolResultBudgetOptions {
|
|
13
|
+
maxTotalToolResultChars: number;
|
|
14
|
+
}
|
|
15
|
+
export interface ToolResultBudgetResult {
|
|
16
|
+
messages: OpenRouterMessage[];
|
|
17
|
+
truncatedCount: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Apply a global budget to all tool result messages.
|
|
21
|
+
* Truncates the largest tool results first until total is within budget.
|
|
22
|
+
*/
|
|
23
|
+
export declare function applyToolResultBudget(messages: readonly OpenRouterMessage[], options: ToolResultBudgetOptions): ToolResultBudgetResult;
|
|
24
|
+
//# sourceMappingURL=tool-result-budget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-result-budget.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/tool-result-budget.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAKpE,MAAM,WAAW,uBAAuB;IACtC,uBAAuB,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,EACtC,OAAO,EAAE,uBAAuB,GAC/B,sBAAsB,CA0DxB"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool result budget — aggregate truncation of large tool results.
|
|
3
|
+
*
|
|
4
|
+
* Runs BEFORE microcompact. While microcompact truncates individual messages
|
|
5
|
+
* to a per-message limit, tool-result-budget enforces a GLOBAL budget across
|
|
6
|
+
* all tool result messages. When total tool result chars exceed the budget,
|
|
7
|
+
* the largest results are truncated first.
|
|
8
|
+
*
|
|
9
|
+
* Ported from old_src/utils/toolResultStorage.ts applyToolResultBudget().
|
|
10
|
+
*/
|
|
11
|
+
const HEAD_RATIO = 0.7;
|
|
12
|
+
const TAIL_RATIO = 0.2;
|
|
13
|
+
/**
|
|
14
|
+
* Apply a global budget to all tool result messages.
|
|
15
|
+
* Truncates the largest tool results first until total is within budget.
|
|
16
|
+
*/
|
|
17
|
+
export function applyToolResultBudget(messages, options) {
|
|
18
|
+
const { maxTotalToolResultChars } = options;
|
|
19
|
+
// Collect tool result indices and sizes
|
|
20
|
+
const toolResults = [];
|
|
21
|
+
for (let i = 0; i < messages.length; i++) {
|
|
22
|
+
const msg = messages[i];
|
|
23
|
+
if (msg.role === 'tool' && typeof msg.content === 'string') {
|
|
24
|
+
toolResults.push({ index: i, size: msg.content.length });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const totalChars = toolResults.reduce((sum, tr) => sum + tr.size, 0);
|
|
28
|
+
if (totalChars <= maxTotalToolResultChars) {
|
|
29
|
+
return { messages: [...messages], truncatedCount: 0 };
|
|
30
|
+
}
|
|
31
|
+
// Sort by size descending — truncate largest first
|
|
32
|
+
const sorted = [...toolResults].sort((a, b) => b.size - a.size);
|
|
33
|
+
// Calculate how much to cut
|
|
34
|
+
let remaining = totalChars - maxTotalToolResultChars;
|
|
35
|
+
const truncateTargets = new Map(); // index → target size
|
|
36
|
+
for (const tr of sorted) {
|
|
37
|
+
if (remaining <= 0)
|
|
38
|
+
break;
|
|
39
|
+
// Calculate how much this result should be
|
|
40
|
+
const cut = Math.min(remaining, tr.size - 200); // keep at least 200 chars
|
|
41
|
+
if (cut <= 0)
|
|
42
|
+
continue;
|
|
43
|
+
const targetSize = tr.size - cut;
|
|
44
|
+
truncateTargets.set(tr.index, targetSize);
|
|
45
|
+
remaining -= cut;
|
|
46
|
+
}
|
|
47
|
+
// Apply truncations
|
|
48
|
+
let truncatedCount = 0;
|
|
49
|
+
const result = messages.map((msg, i) => {
|
|
50
|
+
const targetSize = truncateTargets.get(i);
|
|
51
|
+
if (targetSize === undefined)
|
|
52
|
+
return msg;
|
|
53
|
+
truncatedCount++;
|
|
54
|
+
const content = msg.content;
|
|
55
|
+
const headSize = Math.floor(targetSize * HEAD_RATIO);
|
|
56
|
+
const tailSize = Math.floor(targetSize * TAIL_RATIO);
|
|
57
|
+
const head = content.slice(0, headSize);
|
|
58
|
+
const tail = content.slice(-tailSize);
|
|
59
|
+
const omitted = content.length - headSize - tailSize;
|
|
60
|
+
return {
|
|
61
|
+
...msg,
|
|
62
|
+
content: `${head}\n\n[truncated ${omitted} characters — tool result budget exceeded]\n\n${tail}`,
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
return { messages: result, truncatedCount };
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=tool-result-budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-result-budget.js","sourceRoot":"","sources":["../../../src/core/compaction/tool-result-budget.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context analysis — token accounting by role and subsystem.
|
|
3
|
+
*
|
|
4
|
+
* Provides visibility into where tokens are being spent.
|
|
5
|
+
* Ported from old_src/utils/contextAnalysis.ts pattern.
|
|
6
|
+
*/
|
|
7
|
+
import type { OpenRouterMessage } from '../llm/message-types.js';
|
|
8
|
+
export interface ContextAnalysis {
|
|
9
|
+
totalTokens: number;
|
|
10
|
+
messageCount: number;
|
|
11
|
+
byRole: {
|
|
12
|
+
system: number;
|
|
13
|
+
user: number;
|
|
14
|
+
assistant: number;
|
|
15
|
+
tool: number;
|
|
16
|
+
};
|
|
17
|
+
toolResultCount: number;
|
|
18
|
+
toolResultChars: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Analyze context messages and return token breakdown.
|
|
22
|
+
*/
|
|
23
|
+
export declare function analyzeContext(messages: readonly OpenRouterMessage[]): ContextAnalysis;
|
|
24
|
+
//# sourceMappingURL=context-analysis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-analysis.d.ts","sourceRoot":"","sources":["../../src/core/context-analysis.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAGjE,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,GAAG,eAAe,CA6BtF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context analysis — token accounting by role and subsystem.
|
|
3
|
+
*
|
|
4
|
+
* Provides visibility into where tokens are being spent.
|
|
5
|
+
* Ported from old_src/utils/contextAnalysis.ts pattern.
|
|
6
|
+
*/
|
|
7
|
+
import { estimateTokens } from '../utils/token-counter.js';
|
|
8
|
+
/**
|
|
9
|
+
* Analyze context messages and return token breakdown.
|
|
10
|
+
*/
|
|
11
|
+
export function analyzeContext(messages) {
|
|
12
|
+
const byRole = { system: 0, user: 0, assistant: 0, tool: 0 };
|
|
13
|
+
let totalTokens = 0;
|
|
14
|
+
let toolResultCount = 0;
|
|
15
|
+
let toolResultChars = 0;
|
|
16
|
+
for (const msg of messages) {
|
|
17
|
+
const content = typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content);
|
|
18
|
+
const tokens = estimateTokens(content);
|
|
19
|
+
totalTokens += tokens;
|
|
20
|
+
const role = msg.role;
|
|
21
|
+
if (role in byRole) {
|
|
22
|
+
byRole[role] += tokens;
|
|
23
|
+
}
|
|
24
|
+
if (msg.role === 'tool') {
|
|
25
|
+
toolResultCount++;
|
|
26
|
+
toolResultChars += content.length;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
totalTokens,
|
|
31
|
+
messageCount: messages.length,
|
|
32
|
+
byRole,
|
|
33
|
+
toolResultCount,
|
|
34
|
+
toolResultChars,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=context-analysis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-analysis.js","sourceRoot":"","sources":["../../src/core/context-analysis.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAe3D;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,QAAsC;IACnE,MAAM,MAAM,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC7D,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,IAAI,eAAe,GAAG,CAAC,CAAC;IAExB,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC5F,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QACvC,WAAW,IAAI,MAAM,CAAC;QAEtB,MAAM,IAAI,GAAG,GAAG,CAAC,IAA2B,CAAC;QAC7C,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;YACnB,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC;QACzB,CAAC;QAED,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACxB,eAAe,EAAE,CAAC;YAClB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC;QACpC,CAAC;IACH,CAAC;IAED,OAAO;QACL,WAAW;QACX,YAAY,EAAE,QAAQ,CAAC,MAAM;QAC7B,MAAM;QACN,eAAe;QACf,eAAe;KAChB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { OpenRouterMessage } from '../llm/message-types.js';
|
|
2
|
+
import type { ChatMessage } from '../contracts/entities/chat-message.js';
|
|
3
|
+
export interface ContextInjection {
|
|
4
|
+
source: string;
|
|
5
|
+
priority: number;
|
|
6
|
+
content: string;
|
|
7
|
+
tokens: number;
|
|
8
|
+
}
|
|
9
|
+
export interface ContextBuildResult {
|
|
10
|
+
messages: OpenRouterMessage[];
|
|
11
|
+
totalTokens: number;
|
|
12
|
+
injections: ContextInjection[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Builds the full context (system prompt + injections + history) within a token budget.
|
|
16
|
+
*/
|
|
17
|
+
export declare function buildContext(options: {
|
|
18
|
+
systemPrompt?: string;
|
|
19
|
+
injections: ContextInjection[];
|
|
20
|
+
history: ChatMessage[];
|
|
21
|
+
maxTokens: number;
|
|
22
|
+
reserveTokens: number;
|
|
23
|
+
maxPinnedMessages: number;
|
|
24
|
+
}): ContextBuildResult;
|
|
25
|
+
//# sourceMappingURL=context-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-builder.d.ts","sourceRoot":"","sources":["../../src/core/context-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAIzE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,GAAG,kBAAkB,CAyDrB"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { estimateTokens } from '../utils/token-counter.js';
|
|
2
|
+
/**
|
|
3
|
+
* Builds the full context (system prompt + injections + history) within a token budget.
|
|
4
|
+
*/
|
|
5
|
+
export function buildContext(options) {
|
|
6
|
+
const { systemPrompt, injections, history, maxTokens, reserveTokens, maxPinnedMessages } = options;
|
|
7
|
+
const budget = maxTokens - reserveTokens;
|
|
8
|
+
let used = 0;
|
|
9
|
+
const messages = [];
|
|
10
|
+
const appliedInjections = [];
|
|
11
|
+
// 1. System prompt
|
|
12
|
+
let systemContent = systemPrompt ?? '';
|
|
13
|
+
const systemTokens = estimateTokens(systemContent);
|
|
14
|
+
used += systemTokens;
|
|
15
|
+
// 2. Injections sorted by priority (higher = more important), wrapped in <system-reminder>
|
|
16
|
+
const sortedInjections = [...injections].sort((a, b) => b.priority - a.priority);
|
|
17
|
+
for (const injection of sortedInjections) {
|
|
18
|
+
if (used + injection.tokens <= budget) {
|
|
19
|
+
systemContent += `\n\n<system-reminder>\n${injection.content}\n</system-reminder>`;
|
|
20
|
+
used += injection.tokens;
|
|
21
|
+
appliedInjections.push(injection);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (systemContent) {
|
|
25
|
+
messages.push({ role: 'system', content: systemContent });
|
|
26
|
+
}
|
|
27
|
+
// 3. History — pinned messages always included, then recent messages
|
|
28
|
+
const pinned = history.filter(m => m.pinned).slice(0, maxPinnedMessages);
|
|
29
|
+
const unpinned = history.filter(m => !m.pinned);
|
|
30
|
+
// Include pinned first
|
|
31
|
+
for (const msg of pinned) {
|
|
32
|
+
const tokens = estimateTokens(typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content));
|
|
33
|
+
if (used + tokens <= budget) {
|
|
34
|
+
messages.push(chatMessageToOpenRouter(msg));
|
|
35
|
+
used += tokens;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Include unpinned from most recent, fill remaining budget
|
|
39
|
+
const unpinnedReversed = [...unpinned].reverse();
|
|
40
|
+
const unpinnedToInclude = [];
|
|
41
|
+
for (const msg of unpinnedReversed) {
|
|
42
|
+
const tokens = estimateTokens(typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content));
|
|
43
|
+
if (used + tokens <= budget) {
|
|
44
|
+
unpinnedToInclude.unshift(chatMessageToOpenRouter(msg));
|
|
45
|
+
used += tokens;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
messages.push(...unpinnedToInclude);
|
|
52
|
+
// 4. Merge consecutive same-role messages (API constraint: no consecutive user/user)
|
|
53
|
+
const merged = mergeConsecutiveMessages(messages);
|
|
54
|
+
return { messages: merged, totalTokens: used, injections: appliedInjections };
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Merge consecutive messages with the same role.
|
|
58
|
+
* Prevents API errors from consecutive user or assistant messages.
|
|
59
|
+
*/
|
|
60
|
+
function mergeConsecutiveMessages(messages) {
|
|
61
|
+
if (messages.length <= 1)
|
|
62
|
+
return messages;
|
|
63
|
+
const result = [messages[0]];
|
|
64
|
+
for (let i = 1; i < messages.length; i++) {
|
|
65
|
+
const current = messages[i];
|
|
66
|
+
const prev = result[result.length - 1];
|
|
67
|
+
// Only merge user+user or assistant+assistant (not system, not tool)
|
|
68
|
+
if (current.role === prev.role &&
|
|
69
|
+
(current.role === 'user' || current.role === 'assistant') &&
|
|
70
|
+
typeof prev.content === 'string' &&
|
|
71
|
+
typeof current.content === 'string' &&
|
|
72
|
+
!current.tool_call_id &&
|
|
73
|
+
!prev.tool_calls) {
|
|
74
|
+
result[result.length - 1] = { ...prev, content: `${prev.content}\n\n${current.content}` };
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
result.push(current);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
function chatMessageToOpenRouter(msg) {
|
|
83
|
+
const result = {
|
|
84
|
+
role: msg.role,
|
|
85
|
+
content: typeof msg.content === 'string' ? msg.content : contentPartsToOpenRouter(msg.content),
|
|
86
|
+
};
|
|
87
|
+
if (msg.toolCalls) {
|
|
88
|
+
result.tool_calls = msg.toolCalls.map(tc => ({
|
|
89
|
+
id: tc.id,
|
|
90
|
+
type: 'function',
|
|
91
|
+
function: { name: tc.function.name, arguments: tc.function.arguments },
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
94
|
+
if (msg.toolCallId) {
|
|
95
|
+
result.tool_call_id = msg.toolCallId;
|
|
96
|
+
}
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
function contentPartsToOpenRouter(parts) {
|
|
100
|
+
return parts.map(p => {
|
|
101
|
+
if (p.type === 'text')
|
|
102
|
+
return p.text;
|
|
103
|
+
if (p.type === 'image_url' && p.image_url?.url)
|
|
104
|
+
return `[image: ${p.image_url.url}]`;
|
|
105
|
+
return '';
|
|
106
|
+
}).filter(Boolean).join('');
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=context-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-builder.js","sourceRoot":"","sources":["../../src/core/context-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ChatMessage } from '../contracts/entities/chat-message.js';
|
|
2
|
+
import type { ConversationStore } from '../contracts/entities/stores.js';
|
|
3
|
+
/**
|
|
4
|
+
* Manages conversation threads with mutex for isolation.
|
|
5
|
+
*/
|
|
6
|
+
export declare class ConversationManager {
|
|
7
|
+
private readonly store;
|
|
8
|
+
private readonly locks;
|
|
9
|
+
constructor(store?: ConversationStore);
|
|
10
|
+
/**
|
|
11
|
+
* Acquires mutex for a thread, executes fn, then releases.
|
|
12
|
+
*/
|
|
13
|
+
withThread<T>(threadId: string, fn: () => Promise<T>): Promise<T>;
|
|
14
|
+
appendMessage(message: ChatMessage, threadId: string): void;
|
|
15
|
+
getHistory(threadId: string): ChatMessage[];
|
|
16
|
+
getPinnedMessages(threadId: string): ChatMessage[];
|
|
17
|
+
clearThread(threadId: string): void;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=conversation-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-manager.d.ts","sourceRoot":"","sources":["../../src/core/conversation-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AA0BzE;;GAEG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAC1C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoC;gBAE9C,KAAK,CAAC,EAAE,iBAAiB;IAIrC;;OAEG;IACG,UAAU,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAkBvE,aAAa,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAI3D,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE;IAI3C,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE;IAIlD,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;CAGpC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory fallback ConversationStore.
|
|
3
|
+
*/
|
|
4
|
+
class InMemoryConversationStore {
|
|
5
|
+
threads = new Map();
|
|
6
|
+
appendMessage(message, threadId) {
|
|
7
|
+
if (!this.threads.has(threadId))
|
|
8
|
+
this.threads.set(threadId, []);
|
|
9
|
+
this.threads.get(threadId).push(message);
|
|
10
|
+
}
|
|
11
|
+
listThread(threadId) {
|
|
12
|
+
return this.threads.get(threadId) ?? [];
|
|
13
|
+
}
|
|
14
|
+
listPinned(threadId) {
|
|
15
|
+
return this.listThread(threadId).filter(m => m.pinned);
|
|
16
|
+
}
|
|
17
|
+
clearThread(threadId) {
|
|
18
|
+
this.threads.delete(threadId);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Manages conversation threads with mutex for isolation.
|
|
23
|
+
*/
|
|
24
|
+
export class ConversationManager {
|
|
25
|
+
store;
|
|
26
|
+
locks = new Map();
|
|
27
|
+
constructor(store) {
|
|
28
|
+
this.store = store ?? new InMemoryConversationStore();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Acquires mutex for a thread, executes fn, then releases.
|
|
32
|
+
*/
|
|
33
|
+
async withThread(threadId, fn) {
|
|
34
|
+
// Wait for any existing lock on this thread
|
|
35
|
+
while (this.locks.has(threadId)) {
|
|
36
|
+
await this.locks.get(threadId);
|
|
37
|
+
}
|
|
38
|
+
let releaseLock;
|
|
39
|
+
const lockPromise = new Promise(resolve => { releaseLock = resolve; });
|
|
40
|
+
this.locks.set(threadId, lockPromise);
|
|
41
|
+
try {
|
|
42
|
+
return await fn();
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
this.locks.delete(threadId);
|
|
46
|
+
releaseLock();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
appendMessage(message, threadId) {
|
|
50
|
+
this.store.appendMessage(message, threadId);
|
|
51
|
+
}
|
|
52
|
+
getHistory(threadId) {
|
|
53
|
+
return this.store.listThread(threadId);
|
|
54
|
+
}
|
|
55
|
+
getPinnedMessages(threadId) {
|
|
56
|
+
return this.store.listPinned(threadId);
|
|
57
|
+
}
|
|
58
|
+
clearThread(threadId) {
|
|
59
|
+
this.store.clearThread(threadId);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=conversation-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-manager.js","sourceRoot":"","sources":["../../src/core/conversation-manager.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,yBAAyB;IACZ,OAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;IAE5D,aAAa,CAAC,OAAoB,EAAE,QAAgB;QAClD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAChE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,UAAU,CAAC,QAAgB;QACzB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC1C,CAAC;IAED,UAAU,CAAC,QAAgB;QACzB,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACzD,CAAC;IAED,WAAW,CAAC,QAAgB;QAC1B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,mBAAmB;IACb,KAAK,CAAoB;IACzB,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAE1D,YAAY,KAAyB;QACnC,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI,IAAI,yBAAyB,EAAE,CAAC;IACxD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAI,QAAgB,EAAE,EAAoB;QACxD,4CAA4C;QAC5C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;QAED,IAAI,WAAuB,CAAC;QAC5B,MAAM,WAAW,GAAG,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE,GAAG,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7E,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QAEtC,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5B,WAAY,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;IAED,aAAa,CAAC,OAAoB,EAAE,QAAgB;QAClD,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED,UAAU,CAAC,QAAgB;QACzB,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IAED,iBAAiB,CAAC,QAAgB;QAChC,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IAED,WAAW,CAAC,QAAgB;QAC1B,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;CACF"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ExecutionContext as IExecutionContext } from '../contracts/entities/execution-context.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a new execution context with a unique traceId.
|
|
4
|
+
*/
|
|
5
|
+
export declare function createExecutionContext(threadId: string, model: string, parentTraceId?: string): IExecutionContext;
|
|
6
|
+
//# sourceMappingURL=execution-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-context.d.ts","sourceRoot":"","sources":["../../src/core/execution-context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,IAAI,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAExG;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAQjH"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a new execution context with a unique traceId.
|
|
4
|
+
*/
|
|
5
|
+
export function createExecutionContext(threadId, model, parentTraceId) {
|
|
6
|
+
return {
|
|
7
|
+
traceId: randomUUID(),
|
|
8
|
+
threadId,
|
|
9
|
+
startedAt: Date.now(),
|
|
10
|
+
model,
|
|
11
|
+
parentTraceId,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=execution-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-context.js","sourceRoot":"","sources":["../../src/core/execution-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAAgB,EAAE,KAAa,EAAE,aAAsB;IAC5F,OAAO;QACL,OAAO,EAAE,UAAU,EAAE;QACrB,QAAQ;QACR,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,KAAK;QACL,aAAa;KACd,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { StreamChatParams, StreamChunk } from '../llm/message-types.js';
|
|
2
|
+
import type { OpenRouterClient } from '../llm/openrouter-client.js';
|
|
3
|
+
/**
|
|
4
|
+
* Dependency injection for the react loop.
|
|
5
|
+
* Allows tests to inject fakes without mocking the entire OpenRouterClient.
|
|
6
|
+
*/
|
|
7
|
+
export interface LoopDeps {
|
|
8
|
+
/** Override for client.streamChat — returns the same stream chunk types */
|
|
9
|
+
callModel: (params: StreamChatParams) => AsyncIterableIterator<StreamChunk>;
|
|
10
|
+
/** UUID generator — useful for deterministic tests */
|
|
11
|
+
uuid: () => string;
|
|
12
|
+
}
|
|
13
|
+
/** Create production deps from a real client */
|
|
14
|
+
export declare function createProductionDeps(client: OpenRouterClient): LoopDeps;
|
|
15
|
+
//# sourceMappingURL=loop-deps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop-deps.d.ts","sourceRoot":"","sources":["../../src/core/loop-deps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAEpE;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,2EAA2E;IAC3E,SAAS,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,qBAAqB,CAAC,WAAW,CAAC,CAAC;IAC5E,sDAAsD;IACtD,IAAI,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,gDAAgD;AAChD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,gBAAgB,GAAG,QAAQ,CAKvE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop-deps.js","sourceRoot":"","sources":["../../src/core/loop-deps.ts"],"names":[],"mappings":"AAcA,gDAAgD;AAChD,MAAM,UAAU,oBAAoB,CAAC,MAAwB;IAC3D,OAAO;QACL,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;QAChD,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,EAAE;KAChC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { OpenRouterMessage } from '../llm/message-types.js';
|
|
2
|
+
import type { TokenUsage } from '../contracts/entities/token-usage.js';
|
|
3
|
+
/** Why the loop ended */
|
|
4
|
+
export type TerminalReason = 'stop' | 'abort' | 'error' | 'cost_limit' | 'max_iterations' | 'prompt_too_long' | 'max_output_tokens' | 'stop_hook';
|
|
5
|
+
/** Return value of the generator when the loop exits */
|
|
6
|
+
export interface Terminal {
|
|
7
|
+
reason: TerminalReason;
|
|
8
|
+
usage: TokenUsage;
|
|
9
|
+
error?: Error;
|
|
10
|
+
}
|
|
11
|
+
/** Why the loop continued to the next iteration */
|
|
12
|
+
export type ContinueReason = 'next_turn' | 'max_output_tokens_escalate' | 'max_output_tokens_recovery' | 'reactive_compact_retry' | 'model_fallback' | 'stop_hook_blocking' | 'token_budget_continuation';
|
|
13
|
+
export interface Continue {
|
|
14
|
+
reason: ContinueReason;
|
|
15
|
+
}
|
|
16
|
+
export interface AutoCompactTracking {
|
|
17
|
+
lastCompactTurn: number;
|
|
18
|
+
consecutiveFailures: number;
|
|
19
|
+
}
|
|
20
|
+
export interface LoopState {
|
|
21
|
+
readonly messages: readonly OpenRouterMessage[];
|
|
22
|
+
readonly turnCount: number;
|
|
23
|
+
readonly consecutiveErrors: number;
|
|
24
|
+
readonly maxOutputTokensRecoveryCount: number;
|
|
25
|
+
readonly maxOutputTokensOverride: number | undefined;
|
|
26
|
+
readonly hasAttemptedCompaction: boolean;
|
|
27
|
+
readonly autoCompactTracking: AutoCompactTracking | undefined;
|
|
28
|
+
readonly transition: Continue | undefined;
|
|
29
|
+
/** Tracks tool-level retry attempts (onToolError: 'retry'). */
|
|
30
|
+
readonly toolRetryCount: number;
|
|
31
|
+
}
|
|
32
|
+
/** Create initial loop state from the starting messages */
|
|
33
|
+
export declare function createInitialState(messages: OpenRouterMessage[]): LoopState;
|
|
34
|
+
//# sourceMappingURL=loop-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop-types.d.ts","sourceRoot":"","sources":["../../src/core/loop-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAIvE,yBAAyB;AACzB,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,OAAO,GACP,OAAO,GACP,YAAY,GACZ,gBAAgB,GAChB,iBAAiB,GACjB,mBAAmB,GACnB,WAAW,CAAC;AAEhB,wDAAwD;AACxD,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAID,mDAAmD;AACnD,MAAM,MAAM,cAAc,GACtB,WAAW,GACX,4BAA4B,GAC5B,4BAA4B,GAC5B,wBAAwB,GACxB,gBAAgB,GAChB,oBAAoB,GACpB,2BAA2B,CAAC;AAEhC,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,cAAc,CAAC;CACxB;AAID,MAAM,WAAW,mBAAmB;IAClC,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAChD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,4BAA4B,EAAE,MAAM,CAAC;IAC9C,QAAQ,CAAC,uBAAuB,EAAE,MAAM,GAAG,SAAS,CAAC;IACrD,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,mBAAmB,EAAE,mBAAmB,GAAG,SAAS,CAAC;IAC9D,QAAQ,CAAC,UAAU,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC1C,+DAA+D;IAC/D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,2DAA2D;AAC3D,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,SAAS,CAY3E"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Create initial loop state from the starting messages */
|
|
2
|
+
export function createInitialState(messages) {
|
|
3
|
+
return {
|
|
4
|
+
messages,
|
|
5
|
+
turnCount: 1,
|
|
6
|
+
consecutiveErrors: 0,
|
|
7
|
+
maxOutputTokensRecoveryCount: 0,
|
|
8
|
+
maxOutputTokensOverride: undefined,
|
|
9
|
+
hasAttemptedCompaction: false,
|
|
10
|
+
autoCompactTracking: undefined,
|
|
11
|
+
transition: undefined,
|
|
12
|
+
toolRetryCount: 0,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=loop-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop-types.js","sourceRoot":"","sources":["../../src/core/loop-types.ts"],"names":[],"mappings":"AA2DA,2DAA2D;AAC3D,MAAM,UAAU,kBAAkB,CAAC,QAA6B;IAC9D,OAAO;QACL,QAAQ;QACR,SAAS,EAAE,CAAC;QACZ,iBAAiB,EAAE,CAAC;QACpB,4BAA4B,EAAE,CAAC;QAC/B,uBAAuB,EAAE,SAAS;QAClC,sBAAsB,EAAE,KAAK;QAC7B,mBAAmB,EAAE,SAAS;QAC9B,UAAU,EAAE,SAAS;QACrB,cAAc,EAAE,CAAC;KAClB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message normalization for API submission.
|
|
3
|
+
*
|
|
4
|
+
* Ensures messages respect LLM API constraints:
|
|
5
|
+
* - tool_result must follow an assistant message with matching tool_calls
|
|
6
|
+
* - Orphaned tool results (no matching tool_call) are removed
|
|
7
|
+
* - Assistant messages with orphaned tool_calls (no matching result) get tool_calls stripped
|
|
8
|
+
* - Empty assistant messages without tool_calls are removed
|
|
9
|
+
*
|
|
10
|
+
* Ported from old_src/utils/messages.ts normalizeMessagesForAPI() — simplified for SDK.
|
|
11
|
+
*/
|
|
12
|
+
import type { OpenRouterMessage } from '../llm/message-types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Normalize messages before sending to the LLM API.
|
|
15
|
+
* Removes orphaned tool results/calls and empty messages.
|
|
16
|
+
*/
|
|
17
|
+
export declare function normalizeMessagesForAPI(messages: readonly OpenRouterMessage[]): OpenRouterMessage[];
|
|
18
|
+
//# sourceMappingURL=message-normalize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-normalize.d.ts","sourceRoot":"","sources":["../../src/core/message-normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,CA4DnG"}
|