@bowenqt/qiniu-ai-sdk 0.10.0 → 0.13.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.
Files changed (149) hide show
  1. package/README.md +225 -0
  2. package/dist/ai/agent-graph.d.ts +99 -0
  3. package/dist/ai/agent-graph.d.ts.map +1 -0
  4. package/dist/ai/agent-graph.js +321 -0
  5. package/dist/ai/agent-graph.js.map +1 -0
  6. package/dist/ai/agent-graph.mjs +317 -0
  7. package/dist/ai/generate-text.d.ts +51 -0
  8. package/dist/ai/generate-text.d.ts.map +1 -1
  9. package/dist/ai/generate-text.js +132 -0
  10. package/dist/ai/generate-text.js.map +1 -1
  11. package/dist/ai/generate-text.mjs +131 -0
  12. package/dist/ai/graph/checkpointer.d.ts +112 -0
  13. package/dist/ai/graph/checkpointer.d.ts.map +1 -0
  14. package/dist/ai/graph/checkpointer.js +131 -0
  15. package/dist/ai/graph/checkpointer.js.map +1 -0
  16. package/dist/ai/graph/checkpointer.mjs +126 -0
  17. package/dist/ai/graph/index.d.ts +13 -0
  18. package/dist/ai/graph/index.d.ts.map +1 -0
  19. package/dist/ai/graph/index.js +22 -0
  20. package/dist/ai/graph/index.js.map +1 -0
  21. package/dist/ai/graph/index.mjs +12 -0
  22. package/dist/ai/graph/postgres-checkpointer.d.ts +54 -0
  23. package/dist/ai/graph/postgres-checkpointer.d.ts.map +1 -0
  24. package/dist/ai/graph/postgres-checkpointer.js +134 -0
  25. package/dist/ai/graph/postgres-checkpointer.js.map +1 -0
  26. package/dist/ai/graph/postgres-checkpointer.mjs +130 -0
  27. package/dist/ai/graph/redis-checkpointer.d.ts +51 -0
  28. package/dist/ai/graph/redis-checkpointer.d.ts.map +1 -0
  29. package/dist/ai/graph/redis-checkpointer.js +124 -0
  30. package/dist/ai/graph/redis-checkpointer.js.map +1 -0
  31. package/dist/ai/graph/redis-checkpointer.mjs +120 -0
  32. package/dist/ai/graph/state-graph.d.ts +41 -0
  33. package/dist/ai/graph/state-graph.d.ts.map +1 -0
  34. package/dist/ai/graph/state-graph.js +149 -0
  35. package/dist/ai/graph/state-graph.js.map +1 -0
  36. package/dist/ai/graph/state-graph.mjs +144 -0
  37. package/dist/ai/graph/types.d.ts +41 -0
  38. package/dist/ai/graph/types.d.ts.map +1 -0
  39. package/dist/ai/graph/types.js +10 -0
  40. package/dist/ai/graph/types.js.map +1 -0
  41. package/dist/ai/graph/types.mjs +7 -0
  42. package/dist/ai/internal-types.d.ts +109 -0
  43. package/dist/ai/internal-types.d.ts.map +1 -0
  44. package/dist/ai/internal-types.js +28 -0
  45. package/dist/ai/internal-types.js.map +1 -0
  46. package/dist/ai/internal-types.mjs +23 -0
  47. package/dist/ai/nodes/execute-node.d.ts +27 -0
  48. package/dist/ai/nodes/execute-node.d.ts.map +1 -0
  49. package/dist/ai/nodes/execute-node.js +118 -0
  50. package/dist/ai/nodes/execute-node.js.map +1 -0
  51. package/dist/ai/nodes/execute-node.mjs +114 -0
  52. package/dist/ai/nodes/index.d.ts +8 -0
  53. package/dist/ai/nodes/index.d.ts.map +1 -0
  54. package/dist/ai/nodes/index.js +16 -0
  55. package/dist/ai/nodes/index.js.map +1 -0
  56. package/dist/ai/nodes/index.mjs +7 -0
  57. package/dist/ai/nodes/memory-node.d.ts +34 -0
  58. package/dist/ai/nodes/memory-node.d.ts.map +1 -0
  59. package/dist/ai/nodes/memory-node.js +164 -0
  60. package/dist/ai/nodes/memory-node.js.map +1 -0
  61. package/dist/ai/nodes/memory-node.mjs +158 -0
  62. package/dist/ai/nodes/predict-node.d.ts +42 -0
  63. package/dist/ai/nodes/predict-node.d.ts.map +1 -0
  64. package/dist/ai/nodes/predict-node.js +89 -0
  65. package/dist/ai/nodes/predict-node.js.map +1 -0
  66. package/dist/ai/nodes/predict-node.mjs +86 -0
  67. package/dist/ai/nodes/types.d.ts +44 -0
  68. package/dist/ai/nodes/types.d.ts.map +1 -0
  69. package/dist/ai/nodes/types.js +6 -0
  70. package/dist/ai/nodes/types.js.map +1 -0
  71. package/dist/ai/nodes/types.mjs +5 -0
  72. package/dist/index.d.ts +23 -0
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +80 -1
  75. package/dist/index.js.map +1 -1
  76. package/dist/index.mjs +34 -0
  77. package/dist/lib/otel-tracer.d.ts +47 -0
  78. package/dist/lib/otel-tracer.d.ts.map +1 -0
  79. package/dist/lib/otel-tracer.js +79 -0
  80. package/dist/lib/otel-tracer.js.map +1 -0
  81. package/dist/lib/otel-tracer.mjs +75 -0
  82. package/dist/lib/token-estimator.d.ts +62 -0
  83. package/dist/lib/token-estimator.d.ts.map +1 -0
  84. package/dist/lib/token-estimator.js +106 -0
  85. package/dist/lib/token-estimator.js.map +1 -0
  86. package/dist/lib/token-estimator.mjs +100 -0
  87. package/dist/lib/tool-registry.d.ts +103 -0
  88. package/dist/lib/tool-registry.d.ts.map +1 -0
  89. package/dist/lib/tool-registry.js +159 -0
  90. package/dist/lib/tool-registry.js.map +1 -0
  91. package/dist/lib/tool-registry.mjs +154 -0
  92. package/dist/lib/tracer.d.ts +85 -0
  93. package/dist/lib/tracer.d.ts.map +1 -0
  94. package/dist/lib/tracer.js +170 -0
  95. package/dist/lib/tracer.js.map +1 -0
  96. package/dist/lib/tracer.mjs +161 -0
  97. package/dist/lib/types.d.ts +11 -0
  98. package/dist/lib/types.d.ts.map +1 -1
  99. package/dist/modules/mcp/adapter.d.ts +23 -0
  100. package/dist/modules/mcp/adapter.d.ts.map +1 -0
  101. package/dist/modules/mcp/adapter.js +63 -0
  102. package/dist/modules/mcp/adapter.js.map +1 -0
  103. package/dist/modules/mcp/adapter.mjs +58 -0
  104. package/dist/modules/mcp/client.d.ts +75 -0
  105. package/dist/modules/mcp/client.d.ts.map +1 -0
  106. package/dist/modules/mcp/client.js +300 -0
  107. package/dist/modules/mcp/client.js.map +1 -0
  108. package/dist/modules/mcp/client.mjs +295 -0
  109. package/dist/modules/mcp/http-transport.d.ts +51 -0
  110. package/dist/modules/mcp/http-transport.d.ts.map +1 -0
  111. package/dist/modules/mcp/http-transport.js +146 -0
  112. package/dist/modules/mcp/http-transport.js.map +1 -0
  113. package/dist/modules/mcp/http-transport.mjs +141 -0
  114. package/dist/modules/mcp/index.d.ts +11 -0
  115. package/dist/modules/mcp/index.d.ts.map +1 -0
  116. package/dist/modules/mcp/index.js +34 -0
  117. package/dist/modules/mcp/index.js.map +1 -0
  118. package/dist/modules/mcp/index.mjs +14 -0
  119. package/dist/modules/mcp/oauth.d.ts +101 -0
  120. package/dist/modules/mcp/oauth.d.ts.map +1 -0
  121. package/dist/modules/mcp/oauth.js +347 -0
  122. package/dist/modules/mcp/oauth.js.map +1 -0
  123. package/dist/modules/mcp/oauth.mjs +304 -0
  124. package/dist/modules/mcp/token-store.d.ts +69 -0
  125. package/dist/modules/mcp/token-store.d.ts.map +1 -0
  126. package/dist/modules/mcp/token-store.js +174 -0
  127. package/dist/modules/mcp/token-store.js.map +1 -0
  128. package/dist/modules/mcp/token-store.mjs +135 -0
  129. package/dist/modules/mcp/types.d.ts +91 -0
  130. package/dist/modules/mcp/types.d.ts.map +1 -0
  131. package/dist/modules/mcp/types.js +14 -0
  132. package/dist/modules/mcp/types.js.map +1 -0
  133. package/dist/modules/mcp/types.mjs +11 -0
  134. package/dist/modules/skills/index.d.ts +7 -0
  135. package/dist/modules/skills/index.d.ts.map +1 -0
  136. package/dist/modules/skills/index.js +14 -0
  137. package/dist/modules/skills/index.js.map +1 -0
  138. package/dist/modules/skills/index.mjs +6 -0
  139. package/dist/modules/skills/loader.d.ts +51 -0
  140. package/dist/modules/skills/loader.d.ts.map +1 -0
  141. package/dist/modules/skills/loader.js +237 -0
  142. package/dist/modules/skills/loader.js.map +1 -0
  143. package/dist/modules/skills/loader.mjs +198 -0
  144. package/dist/modules/skills/types.d.ts +60 -0
  145. package/dist/modules/skills/types.d.ts.map +1 -0
  146. package/dist/modules/skills/types.js +20 -0
  147. package/dist/modules/skills/types.js.map +1 -0
  148. package/dist/modules/skills/types.mjs +17 -0
  149. package/package.json +4 -1
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ /**
3
+ * ExecuteNode - Tool execution abstraction.
4
+ * Extracted from generateText for modular use in Graph Runtime.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.executeTools = executeTools;
8
+ exports.toolResultsToMessages = toolResultsToMessages;
9
+ /**
10
+ * Execute tools based on tool calls from LLM.
11
+ */
12
+ async function executeTools(toolCalls, tools, context) {
13
+ const results = [];
14
+ for (const call of toolCalls) {
15
+ // Check abort signal
16
+ if (context.abortSignal?.aborted) {
17
+ results.push({
18
+ toolCallId: call.id,
19
+ result: 'Execution cancelled',
20
+ isError: true,
21
+ });
22
+ continue;
23
+ }
24
+ const tool = tools.get(call.function.name);
25
+ if (!tool) {
26
+ results.push({
27
+ toolCallId: call.id,
28
+ result: `Tool not found: ${call.function.name}`,
29
+ isError: true,
30
+ });
31
+ continue;
32
+ }
33
+ if (!tool.execute) {
34
+ results.push({
35
+ toolCallId: call.id,
36
+ result: `Tool ${call.function.name} has no execute function`,
37
+ isError: true,
38
+ });
39
+ continue;
40
+ }
41
+ try {
42
+ // Parse arguments
43
+ const args = parseToolArguments(call.function.arguments);
44
+ // Execute tool
45
+ const execContext = {
46
+ toolCallId: call.id,
47
+ messages: context.messages,
48
+ abortSignal: context.abortSignal,
49
+ };
50
+ const result = await tool.execute(args, execContext);
51
+ results.push({
52
+ toolCallId: call.id,
53
+ result: serializeResult(result),
54
+ isError: false,
55
+ });
56
+ }
57
+ catch (error) {
58
+ const errorMessage = error instanceof Error ? error.message : String(error);
59
+ results.push({
60
+ toolCallId: call.id,
61
+ result: `Error: ${errorMessage}`,
62
+ isError: true,
63
+ });
64
+ }
65
+ }
66
+ return results;
67
+ }
68
+ /**
69
+ * Convert tool execution results to chat messages.
70
+ */
71
+ function toolResultsToMessages(results) {
72
+ return results.map(r => ({
73
+ role: 'tool',
74
+ content: r.result,
75
+ tool_call_id: r.toolCallId,
76
+ }));
77
+ }
78
+ /**
79
+ * Parse tool arguments from JSON string.
80
+ */
81
+ function parseToolArguments(payload) {
82
+ if (!payload || payload.trim() === '') {
83
+ return {};
84
+ }
85
+ try {
86
+ return JSON.parse(payload);
87
+ }
88
+ catch {
89
+ // Try to fix common JSON issues
90
+ try {
91
+ const fixed = payload
92
+ .replace(/'/g, '"')
93
+ .replace(/(\w+):/g, '"$1":');
94
+ return JSON.parse(fixed);
95
+ }
96
+ catch {
97
+ return { _raw: payload };
98
+ }
99
+ }
100
+ }
101
+ /**
102
+ * Serialize tool result to string.
103
+ */
104
+ function serializeResult(result) {
105
+ if (result === undefined || result === null) {
106
+ return '';
107
+ }
108
+ if (typeof result === 'string') {
109
+ return result;
110
+ }
111
+ try {
112
+ return JSON.stringify(result, null, 2);
113
+ }
114
+ catch {
115
+ return String(result);
116
+ }
117
+ }
118
+ //# sourceMappingURL=execute-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute-node.js","sourceRoot":"","sources":["../../../src/ai/nodes/execute-node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * ExecuteNode - Tool execution abstraction.
3
+ * Extracted from generateText for modular use in Graph Runtime.
4
+ */
5
+ /**
6
+ * Execute tools based on tool calls from LLM.
7
+ */
8
+ export async function executeTools(toolCalls, tools, context) {
9
+ const results = [];
10
+ for (const call of toolCalls) {
11
+ // Check abort signal
12
+ if (context.abortSignal?.aborted) {
13
+ results.push({
14
+ toolCallId: call.id,
15
+ result: 'Execution cancelled',
16
+ isError: true,
17
+ });
18
+ continue;
19
+ }
20
+ const tool = tools.get(call.function.name);
21
+ if (!tool) {
22
+ results.push({
23
+ toolCallId: call.id,
24
+ result: `Tool not found: ${call.function.name}`,
25
+ isError: true,
26
+ });
27
+ continue;
28
+ }
29
+ if (!tool.execute) {
30
+ results.push({
31
+ toolCallId: call.id,
32
+ result: `Tool ${call.function.name} has no execute function`,
33
+ isError: true,
34
+ });
35
+ continue;
36
+ }
37
+ try {
38
+ // Parse arguments
39
+ const args = parseToolArguments(call.function.arguments);
40
+ // Execute tool
41
+ const execContext = {
42
+ toolCallId: call.id,
43
+ messages: context.messages,
44
+ abortSignal: context.abortSignal,
45
+ };
46
+ const result = await tool.execute(args, execContext);
47
+ results.push({
48
+ toolCallId: call.id,
49
+ result: serializeResult(result),
50
+ isError: false,
51
+ });
52
+ }
53
+ catch (error) {
54
+ const errorMessage = error instanceof Error ? error.message : String(error);
55
+ results.push({
56
+ toolCallId: call.id,
57
+ result: `Error: ${errorMessage}`,
58
+ isError: true,
59
+ });
60
+ }
61
+ }
62
+ return results;
63
+ }
64
+ /**
65
+ * Convert tool execution results to chat messages.
66
+ */
67
+ export function toolResultsToMessages(results) {
68
+ return results.map(r => ({
69
+ role: 'tool',
70
+ content: r.result,
71
+ tool_call_id: r.toolCallId,
72
+ }));
73
+ }
74
+ /**
75
+ * Parse tool arguments from JSON string.
76
+ */
77
+ function parseToolArguments(payload) {
78
+ if (!payload || payload.trim() === '') {
79
+ return {};
80
+ }
81
+ try {
82
+ return JSON.parse(payload);
83
+ }
84
+ catch {
85
+ // Try to fix common JSON issues
86
+ try {
87
+ const fixed = payload
88
+ .replace(/'/g, '"')
89
+ .replace(/(\w+):/g, '"$1":');
90
+ return JSON.parse(fixed);
91
+ }
92
+ catch {
93
+ return { _raw: payload };
94
+ }
95
+ }
96
+ }
97
+ /**
98
+ * Serialize tool result to string.
99
+ */
100
+ function serializeResult(result) {
101
+ if (result === undefined || result === null) {
102
+ return '';
103
+ }
104
+ if (typeof result === 'string') {
105
+ return result;
106
+ }
107
+ try {
108
+ return JSON.stringify(result, null, 2);
109
+ }
110
+ catch {
111
+ return String(result);
112
+ }
113
+ }
114
+ //# sourceMappingURL=execute-node.js.map
@@ -0,0 +1,8 @@
1
+ /**
2
+ * AI Nodes - Modular components for agent execution.
3
+ */
4
+ export { predict, type PredictOptions, type PredictResult } from './predict-node';
5
+ export { executeTools, toolResultsToMessages, type ExecutionContext, type ToolExecutionResult } from './execute-node';
6
+ export { compactMessages, buildToolPairs, ContextOverflowError } from './memory-node';
7
+ export type { CompactionResult, CompactionConfig, ToolPair, InjectedSkill } from './types';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ai/nodes/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,KAAK,gBAAgB,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACtH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACtF,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ /**
3
+ * AI Nodes - Modular components for agent execution.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ContextOverflowError = exports.buildToolPairs = exports.compactMessages = exports.toolResultsToMessages = exports.executeTools = exports.predict = void 0;
7
+ var predict_node_1 = require("./predict-node");
8
+ Object.defineProperty(exports, "predict", { enumerable: true, get: function () { return predict_node_1.predict; } });
9
+ var execute_node_1 = require("./execute-node");
10
+ Object.defineProperty(exports, "executeTools", { enumerable: true, get: function () { return execute_node_1.executeTools; } });
11
+ Object.defineProperty(exports, "toolResultsToMessages", { enumerable: true, get: function () { return execute_node_1.toolResultsToMessages; } });
12
+ var memory_node_1 = require("./memory-node");
13
+ Object.defineProperty(exports, "compactMessages", { enumerable: true, get: function () { return memory_node_1.compactMessages; } });
14
+ Object.defineProperty(exports, "buildToolPairs", { enumerable: true, get: function () { return memory_node_1.buildToolPairs; } });
15
+ Object.defineProperty(exports, "ContextOverflowError", { enumerable: true, get: function () { return memory_node_1.ContextOverflowError; } });
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ai/nodes/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,+CAAkF;AAAzE,uGAAA,OAAO,OAAA;AAChB,+CAAsH;AAA7G,4GAAA,YAAY,OAAA;AAAE,qHAAA,qBAAqB,OAAA;AAC5C,6CAAsF;AAA7E,8GAAA,eAAe,OAAA;AAAE,6GAAA,cAAc,OAAA;AAAE,mHAAA,oBAAoB,OAAA"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * AI Nodes - Modular components for agent execution.
3
+ */
4
+ export { predict } from './predict-node.mjs';
5
+ export { executeTools, toolResultsToMessages } from './execute-node.mjs';
6
+ export { compactMessages, buildToolPairs, ContextOverflowError } from './memory-node.mjs';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Memory Node - Context Compaction with deterministic fallback.
3
+ *
4
+ * Fallback order:
5
+ * 1. Drop low-priority skill messages (_meta.droppable)
6
+ * 2. Drop oldest unprotected messages
7
+ * 3. Throw ContextOverflowError
8
+ */
9
+ import type { ChatMessage } from '../../lib/types';
10
+ import type { CompactionResult, CompactionConfig, ToolPair, InjectedSkill } from './types';
11
+ import type { InternalMessage } from '../internal-types';
12
+ /** Context overflow error */
13
+ export declare class ContextOverflowError extends Error {
14
+ readonly currentTokens: number;
15
+ readonly maxTokens: number;
16
+ readonly recommendation: string;
17
+ constructor(currentTokens: number, maxTokens: number, recommendation: string);
18
+ }
19
+ /**
20
+ * Compact messages to fit within token budget.
21
+ * Implements deterministic fallback: droppable skills → old messages → error
22
+ *
23
+ * Key feature: recognizes _meta.droppable messages (skill-injected) for selective removal.
24
+ */
25
+ export declare function compactMessages(messages: InternalMessage[], config: CompactionConfig, injectedSkills?: InjectedSkill[]): CompactionResult;
26
+ /**
27
+ * Build tool call/result pairs.
28
+ * Returns pairs and orphan call IDs.
29
+ */
30
+ export declare function buildToolPairs(messages: ChatMessage[]): {
31
+ toolPairs: ToolPair[];
32
+ orphanCalls: string[];
33
+ };
34
+ //# sourceMappingURL=memory-node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-node.d.ts","sourceRoot":"","sources":["../../../src/ai/nodes/memory-node.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC3F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGzD,6BAA6B;AAC7B,qBAAa,oBAAqB,SAAQ,KAAK;aAEvB,aAAa,EAAE,MAAM;aACrB,SAAS,EAAE,MAAM;aACjB,cAAc,EAAE,MAAM;gBAFtB,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM;CAK7C;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC3B,QAAQ,EAAE,eAAe,EAAE,EAC3B,MAAM,EAAE,gBAAgB,EACxB,cAAc,GAAE,aAAa,EAAO,GACrC,gBAAgB,CA0HlB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG;IACrD,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;CACzB,CAgCA"}
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ /**
3
+ * Memory Node - Context Compaction with deterministic fallback.
4
+ *
5
+ * Fallback order:
6
+ * 1. Drop low-priority skill messages (_meta.droppable)
7
+ * 2. Drop oldest unprotected messages
8
+ * 3. Throw ContextOverflowError
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.ContextOverflowError = void 0;
12
+ exports.compactMessages = compactMessages;
13
+ exports.buildToolPairs = buildToolPairs;
14
+ const internal_types_1 = require("../internal-types");
15
+ /** Context overflow error */
16
+ class ContextOverflowError extends Error {
17
+ constructor(currentTokens, maxTokens, recommendation) {
18
+ super(`Context overflow: ${currentTokens} tokens exceeds max ${maxTokens}. ${recommendation}`);
19
+ this.currentTokens = currentTokens;
20
+ this.maxTokens = maxTokens;
21
+ this.recommendation = recommendation;
22
+ this.name = 'ContextOverflowError';
23
+ }
24
+ }
25
+ exports.ContextOverflowError = ContextOverflowError;
26
+ /**
27
+ * Compact messages to fit within token budget.
28
+ * Implements deterministic fallback: droppable skills → old messages → error
29
+ *
30
+ * Key feature: recognizes _meta.droppable messages (skill-injected) for selective removal.
31
+ */
32
+ function compactMessages(messages, config, injectedSkills = []) {
33
+ const result = {
34
+ messages: [...messages],
35
+ occurred: false,
36
+ droppedSkills: [],
37
+ droppedMessages: 0,
38
+ orphanToolCalls: [],
39
+ recommendation: undefined,
40
+ };
41
+ // Check if compaction needed
42
+ let currentTokens = config.estimateTokens(result.messages);
43
+ if (currentTokens <= config.maxTokens) {
44
+ return result;
45
+ }
46
+ result.occurred = true;
47
+ // Build tool pairs (must be kept together)
48
+ const { toolPairs, orphanCalls } = buildToolPairs(result.messages);
49
+ result.orphanToolCalls = orphanCalls;
50
+ // Identify protected indices
51
+ const protectedIndices = new Set();
52
+ // Non-droppable system messages are protected
53
+ result.messages.forEach((msg, idx) => {
54
+ if (msg.role === 'system' && !(0, internal_types_1.isDroppable)(msg)) {
55
+ protectedIndices.add(idx);
56
+ }
57
+ });
58
+ // Tool pairs are protected
59
+ for (const pair of toolPairs) {
60
+ protectedIndices.add(pair.callMessageIndex);
61
+ if (pair.resultMessageIndex !== null) {
62
+ protectedIndices.add(pair.resultMessageIndex);
63
+ }
64
+ }
65
+ // Last user message is protected
66
+ for (let i = result.messages.length - 1; i >= 0; i--) {
67
+ if (result.messages[i].role === 'user') {
68
+ protectedIndices.add(i);
69
+ break;
70
+ }
71
+ }
72
+ // Step 1: Drop droppable skill messages (lowest priority first)
73
+ // Collect all droppable messages with their skill IDs
74
+ const droppableIndices = [];
75
+ result.messages.forEach((msg, idx) => {
76
+ if ((0, internal_types_1.isDroppable)(msg)) {
77
+ const skillId = (0, internal_types_1.getSkillId)(msg);
78
+ if (skillId) {
79
+ droppableIndices.push({
80
+ idx,
81
+ skillId,
82
+ tokens: config.estimateTokens([msg]),
83
+ });
84
+ }
85
+ }
86
+ });
87
+ // Sort by priority (using injectedSkills order) - lowest priority first
88
+ const skillPriorityMap = new Map();
89
+ injectedSkills.forEach((skill, i) => skillPriorityMap.set(skill.name, i));
90
+ droppableIndices.sort((a, b) => {
91
+ const priorityA = skillPriorityMap.get(a.skillId) ?? 0;
92
+ const priorityB = skillPriorityMap.get(b.skillId) ?? 0;
93
+ return priorityA - priorityB; // Lower priority (earlier in list) dropped first
94
+ });
95
+ // Drop droppable messages until under budget
96
+ const indicesToRemove = new Set();
97
+ for (const { idx, skillId, tokens } of droppableIndices) {
98
+ if (currentTokens <= config.maxTokens)
99
+ break;
100
+ indicesToRemove.add(idx);
101
+ currentTokens -= tokens;
102
+ if (!result.droppedSkills.includes(skillId)) {
103
+ result.droppedSkills.push(skillId);
104
+ }
105
+ }
106
+ // Step 2: Drop oldest unprotected non-skill messages
107
+ for (let i = 0; i < result.messages.length && currentTokens > config.maxTokens; i++) {
108
+ if (!protectedIndices.has(i) && !indicesToRemove.has(i) && !(0, internal_types_1.isDroppable)(result.messages[i])) {
109
+ indicesToRemove.add(i);
110
+ currentTokens -= config.estimateTokens([result.messages[i]]);
111
+ }
112
+ }
113
+ // Apply removals
114
+ if (indicesToRemove.size > 0) {
115
+ const droppedSkillCount = droppableIndices.filter(d => indicesToRemove.has(d.idx)).length;
116
+ const droppedNonSkillCount = indicesToRemove.size - droppedSkillCount;
117
+ result.messages = result.messages.filter((_, idx) => !indicesToRemove.has(idx));
118
+ result.droppedMessages = droppedNonSkillCount;
119
+ }
120
+ // Step 3: Check if still over budget
121
+ currentTokens = config.estimateTokens(result.messages);
122
+ if (currentTokens > config.maxTokens) {
123
+ result.recommendation = `Reduce system prompt or decrease skill count. Current: ${currentTokens}, Max: ${config.maxTokens}`;
124
+ throw new ContextOverflowError(currentTokens, config.maxTokens, result.recommendation);
125
+ }
126
+ if (result.droppedSkills.length > 0 || result.droppedMessages > 0) {
127
+ result.recommendation = `Dropped ${result.droppedSkills.length} skills and ${result.droppedMessages} messages to fit context.`;
128
+ }
129
+ return result;
130
+ }
131
+ /**
132
+ * Build tool call/result pairs.
133
+ * Returns pairs and orphan call IDs.
134
+ */
135
+ function buildToolPairs(messages) {
136
+ const toolPairs = [];
137
+ const orphanCalls = [];
138
+ messages.forEach((msg, idx) => {
139
+ if (msg.role === 'assistant' && msg.tool_calls) {
140
+ for (const call of msg.tool_calls) {
141
+ // Find matching result
142
+ const resultIdx = messages.findIndex((m, i) => i > idx && m.role === 'tool' && m.tool_call_id === call.id);
143
+ if (resultIdx !== -1) {
144
+ toolPairs.push({
145
+ callMessageIndex: idx,
146
+ callId: call.id,
147
+ resultMessageIndex: resultIdx,
148
+ });
149
+ }
150
+ else {
151
+ // Orphan call - keep but warn
152
+ orphanCalls.push(call.id);
153
+ toolPairs.push({
154
+ callMessageIndex: idx,
155
+ callId: call.id,
156
+ resultMessageIndex: null,
157
+ });
158
+ }
159
+ }
160
+ }
161
+ });
162
+ return { toolPairs, orphanCalls };
163
+ }
164
+ //# sourceMappingURL=memory-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-node.js","sourceRoot":"","sources":["../../../src/ai/nodes/memory-node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Memory Node - Context Compaction with deterministic fallback.
3
+ *
4
+ * Fallback order:
5
+ * 1. Drop low-priority skill messages (_meta.droppable)
6
+ * 2. Drop oldest unprotected messages
7
+ * 3. Throw ContextOverflowError
8
+ */
9
+ import { isDroppable, getSkillId } from '../internal-types.mjs';
10
+ /** Context overflow error */
11
+ export class ContextOverflowError extends Error {
12
+ constructor(currentTokens, maxTokens, recommendation) {
13
+ super(`Context overflow: ${currentTokens} tokens exceeds max ${maxTokens}. ${recommendation}`);
14
+ this.currentTokens = currentTokens;
15
+ this.maxTokens = maxTokens;
16
+ this.recommendation = recommendation;
17
+ this.name = 'ContextOverflowError';
18
+ }
19
+ }
20
+ /**
21
+ * Compact messages to fit within token budget.
22
+ * Implements deterministic fallback: droppable skills → old messages → error
23
+ *
24
+ * Key feature: recognizes _meta.droppable messages (skill-injected) for selective removal.
25
+ */
26
+ export function compactMessages(messages, config, injectedSkills = []) {
27
+ const result = {
28
+ messages: [...messages],
29
+ occurred: false,
30
+ droppedSkills: [],
31
+ droppedMessages: 0,
32
+ orphanToolCalls: [],
33
+ recommendation: undefined,
34
+ };
35
+ // Check if compaction needed
36
+ let currentTokens = config.estimateTokens(result.messages);
37
+ if (currentTokens <= config.maxTokens) {
38
+ return result;
39
+ }
40
+ result.occurred = true;
41
+ // Build tool pairs (must be kept together)
42
+ const { toolPairs, orphanCalls } = buildToolPairs(result.messages);
43
+ result.orphanToolCalls = orphanCalls;
44
+ // Identify protected indices
45
+ const protectedIndices = new Set();
46
+ // Non-droppable system messages are protected
47
+ result.messages.forEach((msg, idx) => {
48
+ if (msg.role === 'system' && !isDroppable(msg)) {
49
+ protectedIndices.add(idx);
50
+ }
51
+ });
52
+ // Tool pairs are protected
53
+ for (const pair of toolPairs) {
54
+ protectedIndices.add(pair.callMessageIndex);
55
+ if (pair.resultMessageIndex !== null) {
56
+ protectedIndices.add(pair.resultMessageIndex);
57
+ }
58
+ }
59
+ // Last user message is protected
60
+ for (let i = result.messages.length - 1; i >= 0; i--) {
61
+ if (result.messages[i].role === 'user') {
62
+ protectedIndices.add(i);
63
+ break;
64
+ }
65
+ }
66
+ // Step 1: Drop droppable skill messages (lowest priority first)
67
+ // Collect all droppable messages with their skill IDs
68
+ const droppableIndices = [];
69
+ result.messages.forEach((msg, idx) => {
70
+ if (isDroppable(msg)) {
71
+ const skillId = getSkillId(msg);
72
+ if (skillId) {
73
+ droppableIndices.push({
74
+ idx,
75
+ skillId,
76
+ tokens: config.estimateTokens([msg]),
77
+ });
78
+ }
79
+ }
80
+ });
81
+ // Sort by priority (using injectedSkills order) - lowest priority first
82
+ const skillPriorityMap = new Map();
83
+ injectedSkills.forEach((skill, i) => skillPriorityMap.set(skill.name, i));
84
+ droppableIndices.sort((a, b) => {
85
+ const priorityA = skillPriorityMap.get(a.skillId) ?? 0;
86
+ const priorityB = skillPriorityMap.get(b.skillId) ?? 0;
87
+ return priorityA - priorityB; // Lower priority (earlier in list) dropped first
88
+ });
89
+ // Drop droppable messages until under budget
90
+ const indicesToRemove = new Set();
91
+ for (const { idx, skillId, tokens } of droppableIndices) {
92
+ if (currentTokens <= config.maxTokens)
93
+ break;
94
+ indicesToRemove.add(idx);
95
+ currentTokens -= tokens;
96
+ if (!result.droppedSkills.includes(skillId)) {
97
+ result.droppedSkills.push(skillId);
98
+ }
99
+ }
100
+ // Step 2: Drop oldest unprotected non-skill messages
101
+ for (let i = 0; i < result.messages.length && currentTokens > config.maxTokens; i++) {
102
+ if (!protectedIndices.has(i) && !indicesToRemove.has(i) && !isDroppable(result.messages[i])) {
103
+ indicesToRemove.add(i);
104
+ currentTokens -= config.estimateTokens([result.messages[i]]);
105
+ }
106
+ }
107
+ // Apply removals
108
+ if (indicesToRemove.size > 0) {
109
+ const droppedSkillCount = droppableIndices.filter(d => indicesToRemove.has(d.idx)).length;
110
+ const droppedNonSkillCount = indicesToRemove.size - droppedSkillCount;
111
+ result.messages = result.messages.filter((_, idx) => !indicesToRemove.has(idx));
112
+ result.droppedMessages = droppedNonSkillCount;
113
+ }
114
+ // Step 3: Check if still over budget
115
+ currentTokens = config.estimateTokens(result.messages);
116
+ if (currentTokens > config.maxTokens) {
117
+ result.recommendation = `Reduce system prompt or decrease skill count. Current: ${currentTokens}, Max: ${config.maxTokens}`;
118
+ throw new ContextOverflowError(currentTokens, config.maxTokens, result.recommendation);
119
+ }
120
+ if (result.droppedSkills.length > 0 || result.droppedMessages > 0) {
121
+ result.recommendation = `Dropped ${result.droppedSkills.length} skills and ${result.droppedMessages} messages to fit context.`;
122
+ }
123
+ return result;
124
+ }
125
+ /**
126
+ * Build tool call/result pairs.
127
+ * Returns pairs and orphan call IDs.
128
+ */
129
+ export function buildToolPairs(messages) {
130
+ const toolPairs = [];
131
+ const orphanCalls = [];
132
+ messages.forEach((msg, idx) => {
133
+ if (msg.role === 'assistant' && msg.tool_calls) {
134
+ for (const call of msg.tool_calls) {
135
+ // Find matching result
136
+ const resultIdx = messages.findIndex((m, i) => i > idx && m.role === 'tool' && m.tool_call_id === call.id);
137
+ if (resultIdx !== -1) {
138
+ toolPairs.push({
139
+ callMessageIndex: idx,
140
+ callId: call.id,
141
+ resultMessageIndex: resultIdx,
142
+ });
143
+ }
144
+ else {
145
+ // Orphan call - keep but warn
146
+ orphanCalls.push(call.id);
147
+ toolPairs.push({
148
+ callMessageIndex: idx,
149
+ callId: call.id,
150
+ resultMessageIndex: null,
151
+ });
152
+ }
153
+ }
154
+ }
155
+ });
156
+ return { toolPairs, orphanCalls };
157
+ }
158
+ //# sourceMappingURL=memory-node.js.map