@contractspec/lib.ai-agent 5.0.4 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -0
- package/dist/agent/agent-factory.d.ts +13 -0
- package/dist/agent/agent-factory.js +290 -63
- package/dist/agent/contract-spec-agent.d.ts +9 -0
- package/dist/agent/contract-spec-agent.js +287 -63
- package/dist/agent/index.js +353 -129
- package/dist/agent/json-runner.js +290 -66
- package/dist/agent/unified-agent.js +350 -126
- package/dist/exporters/claude-agent-exporter.js +12 -1
- package/dist/exporters/index.js +12 -1
- package/dist/exporters/opencode-exporter.js +11 -0
- package/dist/index.js +11 -0
- package/dist/interop/index.js +24 -2
- package/dist/interop/spec-consumer.js +11 -0
- package/dist/interop/tool-consumer.js +13 -2
- package/dist/node/agent/agent-factory.js +290 -63
- package/dist/node/agent/contract-spec-agent.js +287 -63
- package/dist/node/agent/index.js +353 -129
- package/dist/node/agent/json-runner.js +290 -66
- package/dist/node/agent/unified-agent.js +350 -126
- package/dist/node/exporters/claude-agent-exporter.js +12 -1
- package/dist/node/exporters/index.js +12 -1
- package/dist/node/exporters/opencode-exporter.js +11 -0
- package/dist/node/index.js +11 -0
- package/dist/node/interop/index.js +24 -2
- package/dist/node/interop/spec-consumer.js +11 -0
- package/dist/node/interop/tool-consumer.js +13 -2
- package/dist/node/providers/claude-agent-sdk/adapter.js +11 -0
- package/dist/node/providers/claude-agent-sdk/index.js +11 -0
- package/dist/node/providers/index.js +11 -0
- package/dist/node/providers/opencode-sdk/adapter.js +11 -0
- package/dist/node/providers/opencode-sdk/index.js +11 -0
- package/dist/node/spec/index.js +11 -0
- package/dist/node/spec/spec.js +11 -0
- package/dist/node/tools/agent-memory-store.js +24 -0
- package/dist/node/tools/in-memory-agent-memory-store.js +236 -0
- package/dist/node/tools/index.js +463 -42
- package/dist/node/tools/memory-tools.js +45 -0
- package/dist/node/tools/operation-tool-handler.js +35 -0
- package/dist/node/tools/subagent-tool.js +95 -0
- package/dist/node/tools/tool-adapter.js +192 -25
- package/dist/providers/claude-agent-sdk/adapter.js +11 -0
- package/dist/providers/claude-agent-sdk/index.js +11 -0
- package/dist/providers/index.js +11 -0
- package/dist/providers/opencode-sdk/adapter.js +11 -0
- package/dist/providers/opencode-sdk/index.js +11 -0
- package/dist/spec/index.js +11 -0
- package/dist/spec/spec.d.ts +69 -1
- package/dist/spec/spec.js +11 -0
- package/dist/tools/agent-memory-store.d.ts +26 -0
- package/dist/tools/agent-memory-store.js +24 -0
- package/dist/tools/agent-memory-store.test.d.ts +1 -0
- package/dist/tools/in-memory-agent-memory-store.d.ts +18 -0
- package/dist/tools/in-memory-agent-memory-store.js +236 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.js +463 -42
- package/dist/tools/mcp-client.browser.d.ts +6 -6
- package/dist/tools/memory-tools.d.ts +29 -0
- package/dist/tools/memory-tools.js +45 -0
- package/dist/tools/operation-tool-handler.d.ts +24 -0
- package/dist/tools/operation-tool-handler.js +35 -0
- package/dist/tools/subagent-tool.d.ts +66 -0
- package/dist/tools/subagent-tool.js +95 -0
- package/dist/tools/tool-adapter.d.ts +26 -10
- package/dist/tools/tool-adapter.js +192 -25
- package/dist/types.d.ts +9 -3
- package/package.json +67 -7
|
@@ -2156,6 +2156,17 @@ function defineAgent(spec) {
|
|
|
2156
2156
|
}));
|
|
2157
2157
|
}
|
|
2158
2158
|
toolNames.add(tool.name);
|
|
2159
|
+
if (tool.subagentRef && tool.operationRef) {
|
|
2160
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" cannot have both subagentRef and operationRef. Use one.`);
|
|
2161
|
+
}
|
|
2162
|
+
const outputRefCount = [
|
|
2163
|
+
tool.outputPresentation,
|
|
2164
|
+
tool.outputForm,
|
|
2165
|
+
tool.outputDataView
|
|
2166
|
+
].filter(Boolean).length;
|
|
2167
|
+
if (outputRefCount > 1) {
|
|
2168
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" has multiple output refs (outputPresentation, outputForm, outputDataView). Use at most one.`);
|
|
2169
|
+
}
|
|
2159
2170
|
}
|
|
2160
2171
|
return Object.freeze(spec);
|
|
2161
2172
|
}
|
|
@@ -2211,7 +2222,7 @@ class ClaudeAgentExporter {
|
|
|
2211
2222
|
}
|
|
2212
2223
|
buildConfig(spec, tools, options) {
|
|
2213
2224
|
const config = {
|
|
2214
|
-
model: options.model ?? "claude-sonnet-4-
|
|
2225
|
+
model: options.model ?? "claude-sonnet-4-6",
|
|
2215
2226
|
system: this.buildSystemPrompt(spec, options),
|
|
2216
2227
|
tools,
|
|
2217
2228
|
max_turns: spec.maxSteps ?? 10
|
|
@@ -2156,6 +2156,17 @@ function defineAgent(spec) {
|
|
|
2156
2156
|
}));
|
|
2157
2157
|
}
|
|
2158
2158
|
toolNames.add(tool.name);
|
|
2159
|
+
if (tool.subagentRef && tool.operationRef) {
|
|
2160
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" cannot have both subagentRef and operationRef. Use one.`);
|
|
2161
|
+
}
|
|
2162
|
+
const outputRefCount = [
|
|
2163
|
+
tool.outputPresentation,
|
|
2164
|
+
tool.outputForm,
|
|
2165
|
+
tool.outputDataView
|
|
2166
|
+
].filter(Boolean).length;
|
|
2167
|
+
if (outputRefCount > 1) {
|
|
2168
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" has multiple output refs (outputPresentation, outputForm, outputDataView). Use at most one.`);
|
|
2169
|
+
}
|
|
2159
2170
|
}
|
|
2160
2171
|
return Object.freeze(spec);
|
|
2161
2172
|
}
|
|
@@ -2497,7 +2508,7 @@ class ClaudeAgentExporter {
|
|
|
2497
2508
|
}
|
|
2498
2509
|
buildConfig(spec, tools, options) {
|
|
2499
2510
|
const config = {
|
|
2500
|
-
model: options.model ?? "claude-sonnet-4-
|
|
2511
|
+
model: options.model ?? "claude-sonnet-4-6",
|
|
2501
2512
|
system: this.buildSystemPrompt(spec, options),
|
|
2502
2513
|
tools,
|
|
2503
2514
|
max_turns: spec.maxSteps ?? 10
|
|
@@ -2156,6 +2156,17 @@ function defineAgent(spec) {
|
|
|
2156
2156
|
}));
|
|
2157
2157
|
}
|
|
2158
2158
|
toolNames.add(tool.name);
|
|
2159
|
+
if (tool.subagentRef && tool.operationRef) {
|
|
2160
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" cannot have both subagentRef and operationRef. Use one.`);
|
|
2161
|
+
}
|
|
2162
|
+
const outputRefCount = [
|
|
2163
|
+
tool.outputPresentation,
|
|
2164
|
+
tool.outputForm,
|
|
2165
|
+
tool.outputDataView
|
|
2166
|
+
].filter(Boolean).length;
|
|
2167
|
+
if (outputRefCount > 1) {
|
|
2168
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" has multiple output refs (outputPresentation, outputForm, outputDataView). Use at most one.`);
|
|
2169
|
+
}
|
|
2159
2170
|
}
|
|
2160
2171
|
return Object.freeze(spec);
|
|
2161
2172
|
}
|
package/dist/node/index.js
CHANGED
|
@@ -2156,6 +2156,17 @@ function defineAgent(spec) {
|
|
|
2156
2156
|
}));
|
|
2157
2157
|
}
|
|
2158
2158
|
toolNames.add(tool.name);
|
|
2159
|
+
if (tool.subagentRef && tool.operationRef) {
|
|
2160
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" cannot have both subagentRef and operationRef. Use one.`);
|
|
2161
|
+
}
|
|
2162
|
+
const outputRefCount = [
|
|
2163
|
+
tool.outputPresentation,
|
|
2164
|
+
tool.outputForm,
|
|
2165
|
+
tool.outputDataView
|
|
2166
|
+
].filter(Boolean).length;
|
|
2167
|
+
if (outputRefCount > 1) {
|
|
2168
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" has multiple output refs (outputPresentation, outputForm, outputDataView). Use at most one.`);
|
|
2169
|
+
}
|
|
2159
2170
|
}
|
|
2160
2171
|
return Object.freeze(spec);
|
|
2161
2172
|
}
|
|
@@ -2156,6 +2156,17 @@ function defineAgent(spec) {
|
|
|
2156
2156
|
}));
|
|
2157
2157
|
}
|
|
2158
2158
|
toolNames.add(tool.name);
|
|
2159
|
+
if (tool.subagentRef && tool.operationRef) {
|
|
2160
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" cannot have both subagentRef and operationRef. Use one.`);
|
|
2161
|
+
}
|
|
2162
|
+
const outputRefCount = [
|
|
2163
|
+
tool.outputPresentation,
|
|
2164
|
+
tool.outputForm,
|
|
2165
|
+
tool.outputDataView
|
|
2166
|
+
].filter(Boolean).length;
|
|
2167
|
+
if (outputRefCount > 1) {
|
|
2168
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" has multiple output refs (outputPresentation, outputForm, outputDataView). Use at most one.`);
|
|
2169
|
+
}
|
|
2159
2170
|
}
|
|
2160
2171
|
return Object.freeze(spec);
|
|
2161
2172
|
}
|
|
@@ -2678,6 +2689,17 @@ function createSingleSpecConsumer(spec, options) {
|
|
|
2678
2689
|
init_tool_bridge();
|
|
2679
2690
|
init_tool_bridge2();
|
|
2680
2691
|
init_i18n();
|
|
2692
|
+
async function resolveToolResult(result) {
|
|
2693
|
+
const resolved = await result;
|
|
2694
|
+
if (typeof resolved === "object" && resolved !== null && typeof resolved.next === "function" && typeof resolved[Symbol.asyncIterator] === "function") {
|
|
2695
|
+
let last;
|
|
2696
|
+
for await (const value of resolved) {
|
|
2697
|
+
last = value;
|
|
2698
|
+
}
|
|
2699
|
+
return typeof last === "string" ? last : JSON.stringify(last ?? "");
|
|
2700
|
+
}
|
|
2701
|
+
return typeof resolved === "string" ? resolved : JSON.stringify(resolved ?? "");
|
|
2702
|
+
}
|
|
2681
2703
|
|
|
2682
2704
|
class MCPToolServer {
|
|
2683
2705
|
tools;
|
|
@@ -2738,7 +2760,7 @@ class MCPToolServer {
|
|
|
2738
2760
|
metadata: context?.metadata,
|
|
2739
2761
|
signal: context?.signal
|
|
2740
2762
|
};
|
|
2741
|
-
return
|
|
2763
|
+
return resolveToolResult(tool.handler(args, fullContext));
|
|
2742
2764
|
}
|
|
2743
2765
|
getMCPToolDefinitions() {
|
|
2744
2766
|
const definitions = [];
|
|
@@ -2853,7 +2875,7 @@ class ContractSpecToolConsumer {
|
|
|
2853
2875
|
metadata: context?.metadata,
|
|
2854
2876
|
signal: context?.signal
|
|
2855
2877
|
};
|
|
2856
|
-
return
|
|
2878
|
+
return resolveToolResult(tool.handler(args, fullContext));
|
|
2857
2879
|
}
|
|
2858
2880
|
addTool(config, handler) {
|
|
2859
2881
|
this.tools.set(config.name, { config, handler });
|
|
@@ -2156,6 +2156,17 @@ function defineAgent(spec) {
|
|
|
2156
2156
|
}));
|
|
2157
2157
|
}
|
|
2158
2158
|
toolNames.add(tool.name);
|
|
2159
|
+
if (tool.subagentRef && tool.operationRef) {
|
|
2160
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" cannot have both subagentRef and operationRef. Use one.`);
|
|
2161
|
+
}
|
|
2162
|
+
const outputRefCount = [
|
|
2163
|
+
tool.outputPresentation,
|
|
2164
|
+
tool.outputForm,
|
|
2165
|
+
tool.outputDataView
|
|
2166
|
+
].filter(Boolean).length;
|
|
2167
|
+
if (outputRefCount > 1) {
|
|
2168
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" has multiple output refs (outputPresentation, outputForm, outputDataView). Use at most one.`);
|
|
2169
|
+
}
|
|
2159
2170
|
}
|
|
2160
2171
|
return Object.freeze(spec);
|
|
2161
2172
|
}
|
|
@@ -2357,6 +2357,17 @@ var init_tool_bridge2 = __esm(() => {
|
|
|
2357
2357
|
init_tool_bridge();
|
|
2358
2358
|
init_tool_bridge2();
|
|
2359
2359
|
init_i18n();
|
|
2360
|
+
async function resolveToolResult(result) {
|
|
2361
|
+
const resolved = await result;
|
|
2362
|
+
if (typeof resolved === "object" && resolved !== null && typeof resolved.next === "function" && typeof resolved[Symbol.asyncIterator] === "function") {
|
|
2363
|
+
let last;
|
|
2364
|
+
for await (const value of resolved) {
|
|
2365
|
+
last = value;
|
|
2366
|
+
}
|
|
2367
|
+
return typeof last === "string" ? last : JSON.stringify(last ?? "");
|
|
2368
|
+
}
|
|
2369
|
+
return typeof resolved === "string" ? resolved : JSON.stringify(resolved ?? "");
|
|
2370
|
+
}
|
|
2360
2371
|
|
|
2361
2372
|
class MCPToolServer {
|
|
2362
2373
|
tools;
|
|
@@ -2417,7 +2428,7 @@ class MCPToolServer {
|
|
|
2417
2428
|
metadata: context?.metadata,
|
|
2418
2429
|
signal: context?.signal
|
|
2419
2430
|
};
|
|
2420
|
-
return
|
|
2431
|
+
return resolveToolResult(tool.handler(args, fullContext));
|
|
2421
2432
|
}
|
|
2422
2433
|
getMCPToolDefinitions() {
|
|
2423
2434
|
const definitions = [];
|
|
@@ -2532,7 +2543,7 @@ class ContractSpecToolConsumer {
|
|
|
2532
2543
|
metadata: context?.metadata,
|
|
2533
2544
|
signal: context?.signal
|
|
2534
2545
|
};
|
|
2535
|
-
return
|
|
2546
|
+
return resolveToolResult(tool.handler(args, fullContext));
|
|
2536
2547
|
}
|
|
2537
2548
|
addTool(config, handler) {
|
|
2538
2549
|
this.tools.set(config.name, { config, handler });
|
|
@@ -2156,6 +2156,17 @@ function defineAgent(spec) {
|
|
|
2156
2156
|
}));
|
|
2157
2157
|
}
|
|
2158
2158
|
toolNames.add(tool.name);
|
|
2159
|
+
if (tool.subagentRef && tool.operationRef) {
|
|
2160
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" cannot have both subagentRef and operationRef. Use one.`);
|
|
2161
|
+
}
|
|
2162
|
+
const outputRefCount = [
|
|
2163
|
+
tool.outputPresentation,
|
|
2164
|
+
tool.outputForm,
|
|
2165
|
+
tool.outputDataView
|
|
2166
|
+
].filter(Boolean).length;
|
|
2167
|
+
if (outputRefCount > 1) {
|
|
2168
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" has multiple output refs (outputPresentation, outputForm, outputDataView). Use at most one.`);
|
|
2169
|
+
}
|
|
2159
2170
|
}
|
|
2160
2171
|
return Object.freeze(spec);
|
|
2161
2172
|
}
|
|
@@ -2156,6 +2156,17 @@ function defineAgent(spec) {
|
|
|
2156
2156
|
}));
|
|
2157
2157
|
}
|
|
2158
2158
|
toolNames.add(tool.name);
|
|
2159
|
+
if (tool.subagentRef && tool.operationRef) {
|
|
2160
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" cannot have both subagentRef and operationRef. Use one.`);
|
|
2161
|
+
}
|
|
2162
|
+
const outputRefCount = [
|
|
2163
|
+
tool.outputPresentation,
|
|
2164
|
+
tool.outputForm,
|
|
2165
|
+
tool.outputDataView
|
|
2166
|
+
].filter(Boolean).length;
|
|
2167
|
+
if (outputRefCount > 1) {
|
|
2168
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" has multiple output refs (outputPresentation, outputForm, outputDataView). Use at most one.`);
|
|
2169
|
+
}
|
|
2159
2170
|
}
|
|
2160
2171
|
return Object.freeze(spec);
|
|
2161
2172
|
}
|
|
@@ -2156,6 +2156,17 @@ function defineAgent(spec) {
|
|
|
2156
2156
|
}));
|
|
2157
2157
|
}
|
|
2158
2158
|
toolNames.add(tool.name);
|
|
2159
|
+
if (tool.subagentRef && tool.operationRef) {
|
|
2160
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" cannot have both subagentRef and operationRef. Use one.`);
|
|
2161
|
+
}
|
|
2162
|
+
const outputRefCount = [
|
|
2163
|
+
tool.outputPresentation,
|
|
2164
|
+
tool.outputForm,
|
|
2165
|
+
tool.outputDataView
|
|
2166
|
+
].filter(Boolean).length;
|
|
2167
|
+
if (outputRefCount > 1) {
|
|
2168
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" has multiple output refs (outputPresentation, outputForm, outputDataView). Use at most one.`);
|
|
2169
|
+
}
|
|
2159
2170
|
}
|
|
2160
2171
|
return Object.freeze(spec);
|
|
2161
2172
|
}
|
|
@@ -2156,6 +2156,17 @@ function defineAgent(spec) {
|
|
|
2156
2156
|
}));
|
|
2157
2157
|
}
|
|
2158
2158
|
toolNames.add(tool.name);
|
|
2159
|
+
if (tool.subagentRef && tool.operationRef) {
|
|
2160
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" cannot have both subagentRef and operationRef. Use one.`);
|
|
2161
|
+
}
|
|
2162
|
+
const outputRefCount = [
|
|
2163
|
+
tool.outputPresentation,
|
|
2164
|
+
tool.outputForm,
|
|
2165
|
+
tool.outputDataView
|
|
2166
|
+
].filter(Boolean).length;
|
|
2167
|
+
if (outputRefCount > 1) {
|
|
2168
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" has multiple output refs (outputPresentation, outputForm, outputDataView). Use at most one.`);
|
|
2169
|
+
}
|
|
2159
2170
|
}
|
|
2160
2171
|
return Object.freeze(spec);
|
|
2161
2172
|
}
|
|
@@ -2156,6 +2156,17 @@ function defineAgent(spec) {
|
|
|
2156
2156
|
}));
|
|
2157
2157
|
}
|
|
2158
2158
|
toolNames.add(tool.name);
|
|
2159
|
+
if (tool.subagentRef && tool.operationRef) {
|
|
2160
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" cannot have both subagentRef and operationRef. Use one.`);
|
|
2161
|
+
}
|
|
2162
|
+
const outputRefCount = [
|
|
2163
|
+
tool.outputPresentation,
|
|
2164
|
+
tool.outputForm,
|
|
2165
|
+
tool.outputDataView
|
|
2166
|
+
].filter(Boolean).length;
|
|
2167
|
+
if (outputRefCount > 1) {
|
|
2168
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" has multiple output refs (outputPresentation, outputForm, outputDataView). Use at most one.`);
|
|
2169
|
+
}
|
|
2159
2170
|
}
|
|
2160
2171
|
return Object.freeze(spec);
|
|
2161
2172
|
}
|
package/dist/node/spec/index.js
CHANGED
|
@@ -2156,6 +2156,17 @@ function defineAgent(spec) {
|
|
|
2156
2156
|
}));
|
|
2157
2157
|
}
|
|
2158
2158
|
toolNames.add(tool.name);
|
|
2159
|
+
if (tool.subagentRef && tool.operationRef) {
|
|
2160
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" cannot have both subagentRef and operationRef. Use one.`);
|
|
2161
|
+
}
|
|
2162
|
+
const outputRefCount = [
|
|
2163
|
+
tool.outputPresentation,
|
|
2164
|
+
tool.outputForm,
|
|
2165
|
+
tool.outputDataView
|
|
2166
|
+
].filter(Boolean).length;
|
|
2167
|
+
if (outputRefCount > 1) {
|
|
2168
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" has multiple output refs (outputPresentation, outputForm, outputDataView). Use at most one.`);
|
|
2169
|
+
}
|
|
2159
2170
|
}
|
|
2160
2171
|
return Object.freeze(spec);
|
|
2161
2172
|
}
|
package/dist/node/spec/spec.js
CHANGED
|
@@ -2156,6 +2156,17 @@ function defineAgent(spec) {
|
|
|
2156
2156
|
}));
|
|
2157
2157
|
}
|
|
2158
2158
|
toolNames.add(tool.name);
|
|
2159
|
+
if (tool.subagentRef && tool.operationRef) {
|
|
2160
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" cannot have both subagentRef and operationRef. Use one.`);
|
|
2161
|
+
}
|
|
2162
|
+
const outputRefCount = [
|
|
2163
|
+
tool.outputPresentation,
|
|
2164
|
+
tool.outputForm,
|
|
2165
|
+
tool.outputDataView
|
|
2166
|
+
].filter(Boolean).length;
|
|
2167
|
+
if (outputRefCount > 1) {
|
|
2168
|
+
throw new Error(`Agent ${spec.meta.key} tool "${tool.name}" has multiple output refs (outputPresentation, outputForm, outputDataView). Use at most one.`);
|
|
2169
|
+
}
|
|
2159
2170
|
}
|
|
2160
2171
|
return Object.freeze(spec);
|
|
2161
2172
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __export = (target, all) => {
|
|
4
|
+
for (var name in all)
|
|
5
|
+
__defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true,
|
|
8
|
+
configurable: true,
|
|
9
|
+
set: (newValue) => all[name] = () => newValue
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
13
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
14
|
+
|
|
15
|
+
// src/tools/agent-memory-store.ts
|
|
16
|
+
function validateMemoryPath(path) {
|
|
17
|
+
const normalized = path.replace(/\\/g, "/").replace(/\/+/g, "/");
|
|
18
|
+
if (!normalized.startsWith("/memories") || normalized.includes("..") || normalized === "/memories/.." || normalized.startsWith("/memories/../")) {
|
|
19
|
+
throw new Error(`Invalid memory path: ${path}. Path must be under /memories and cannot contain traversal sequences.`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
validateMemoryPath
|
|
24
|
+
};
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __export = (target, all) => {
|
|
4
|
+
for (var name in all)
|
|
5
|
+
__defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true,
|
|
8
|
+
configurable: true,
|
|
9
|
+
set: (newValue) => all[name] = () => newValue
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
13
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
14
|
+
|
|
15
|
+
// src/tools/agent-memory-store.ts
|
|
16
|
+
function validateMemoryPath(path) {
|
|
17
|
+
const normalized = path.replace(/\\/g, "/").replace(/\/+/g, "/");
|
|
18
|
+
if (!normalized.startsWith("/memories") || normalized.includes("..") || normalized === "/memories/.." || normalized.startsWith("/memories/../")) {
|
|
19
|
+
throw new Error(`Invalid memory path: ${path}. Path must be under /memories and cannot contain traversal sequences.`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// src/tools/in-memory-agent-memory-store.ts
|
|
24
|
+
function formatSize(bytes) {
|
|
25
|
+
if (bytes < 1024)
|
|
26
|
+
return `${bytes}B`;
|
|
27
|
+
if (bytes < 1024 * 1024)
|
|
28
|
+
return `${(bytes / 1024).toFixed(1)}K`;
|
|
29
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)}M`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
class InMemoryAgentMemoryStore {
|
|
33
|
+
store = new Map;
|
|
34
|
+
async view(path, viewRange) {
|
|
35
|
+
validateMemoryPath(path);
|
|
36
|
+
const normalized = path.replace(/\/+/g, "/").replace(/\/$/, "") || "/memories";
|
|
37
|
+
if (this.isDirectory(normalized)) {
|
|
38
|
+
return this.listDirectory(normalized);
|
|
39
|
+
}
|
|
40
|
+
const content = this.store.get(normalized);
|
|
41
|
+
if (content === undefined) {
|
|
42
|
+
return `The path ${path} does not exist. Please provide a valid path.`;
|
|
43
|
+
}
|
|
44
|
+
const lines = content.split(`
|
|
45
|
+
`);
|
|
46
|
+
if (lines.length > 999999) {
|
|
47
|
+
return `File ${path} exceeds maximum line limit of 999,999 lines.`;
|
|
48
|
+
}
|
|
49
|
+
const [start, end] = viewRange ?? [1, lines.length];
|
|
50
|
+
const from = Math.max(0, start - 1);
|
|
51
|
+
const to = Math.min(lines.length, end);
|
|
52
|
+
const selected = lines.slice(from, to);
|
|
53
|
+
const numbered = selected.map((line, i) => {
|
|
54
|
+
const num = from + i + 1;
|
|
55
|
+
return `${String(num).padStart(6)} ${line}`;
|
|
56
|
+
}).join(`
|
|
57
|
+
`);
|
|
58
|
+
return `Here's the content of ${path} with line numbers:
|
|
59
|
+
${numbered}`;
|
|
60
|
+
}
|
|
61
|
+
async create(path, fileText) {
|
|
62
|
+
validateMemoryPath(path);
|
|
63
|
+
const normalized = path.replace(/\/+/g, "/");
|
|
64
|
+
if (this.store.has(normalized)) {
|
|
65
|
+
return `Error: File ${path} already exists`;
|
|
66
|
+
}
|
|
67
|
+
this.ensureParentDir(normalized);
|
|
68
|
+
this.store.set(normalized, fileText);
|
|
69
|
+
return `File created successfully at: ${path}`;
|
|
70
|
+
}
|
|
71
|
+
async strReplace(path, oldStr, newStr) {
|
|
72
|
+
validateMemoryPath(path);
|
|
73
|
+
const normalized = path.replace(/\/+/g, "/");
|
|
74
|
+
const content = this.store.get(normalized);
|
|
75
|
+
if (content === undefined) {
|
|
76
|
+
return `Error: The path ${path} does not exist. Please provide a valid path.`;
|
|
77
|
+
}
|
|
78
|
+
const count = (content.match(new RegExp(escapeRegex(oldStr), "g")) ?? []).length;
|
|
79
|
+
if (count > 1) {
|
|
80
|
+
const lines = content.split(`
|
|
81
|
+
`);
|
|
82
|
+
const lineNums = [];
|
|
83
|
+
lines.forEach((line, i) => {
|
|
84
|
+
if (line.includes(oldStr))
|
|
85
|
+
lineNums.push(i + 1);
|
|
86
|
+
});
|
|
87
|
+
return `No replacement was performed. Multiple occurrences of old_str \`${oldStr}\` in lines: ${lineNums.join(", ")}. Please ensure it is unique`;
|
|
88
|
+
}
|
|
89
|
+
if (count === 0) {
|
|
90
|
+
return `No replacement was performed, old_str \`${oldStr}\` did not appear verbatim in ${path}.`;
|
|
91
|
+
}
|
|
92
|
+
const newContent = content.replace(oldStr, newStr);
|
|
93
|
+
this.store.set(normalized, newContent);
|
|
94
|
+
const snippet = newContent.split(`
|
|
95
|
+
`).slice(0, 5);
|
|
96
|
+
const numbered = snippet.map((line, i) => `${String(i + 1).padStart(6)} ${line}`).join(`
|
|
97
|
+
`);
|
|
98
|
+
return `The memory file has been edited.
|
|
99
|
+
${numbered}`;
|
|
100
|
+
}
|
|
101
|
+
async insert(path, insertLine, insertText) {
|
|
102
|
+
validateMemoryPath(path);
|
|
103
|
+
const normalized = path.replace(/\/+/g, "/");
|
|
104
|
+
const content = this.store.get(normalized);
|
|
105
|
+
if (content === undefined) {
|
|
106
|
+
return `Error: The path ${path} does not exist`;
|
|
107
|
+
}
|
|
108
|
+
const lines = content.split(`
|
|
109
|
+
`);
|
|
110
|
+
const n = lines.length;
|
|
111
|
+
if (insertLine < 0 || insertLine > n) {
|
|
112
|
+
return `Error: Invalid \`insert_line\` parameter: ${insertLine}. It should be within the range of lines of the file: [0, ${n}]`;
|
|
113
|
+
}
|
|
114
|
+
lines.splice(insertLine, 0, insertText.replace(/\n$/, ""));
|
|
115
|
+
this.store.set(normalized, lines.join(`
|
|
116
|
+
`));
|
|
117
|
+
return `The file ${path} has been edited.`;
|
|
118
|
+
}
|
|
119
|
+
async delete(path) {
|
|
120
|
+
validateMemoryPath(path);
|
|
121
|
+
const normalized = path.replace(/\/+/g, "/");
|
|
122
|
+
if (this.isDirectory(normalized)) {
|
|
123
|
+
const prefix = normalized === "/memories" ? "/memories/" : `${normalized}/`;
|
|
124
|
+
for (const key of this.store.keys()) {
|
|
125
|
+
if (key.startsWith(prefix) || key === normalized) {
|
|
126
|
+
this.store.delete(key);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
if (!this.store.has(normalized)) {
|
|
131
|
+
return `Error: The path ${path} does not exist`;
|
|
132
|
+
}
|
|
133
|
+
this.store.delete(normalized);
|
|
134
|
+
}
|
|
135
|
+
return `Successfully deleted ${path}`;
|
|
136
|
+
}
|
|
137
|
+
async rename(oldPath, newPath) {
|
|
138
|
+
validateMemoryPath(oldPath);
|
|
139
|
+
validateMemoryPath(newPath);
|
|
140
|
+
const oldNorm = oldPath.replace(/\/+/g, "/");
|
|
141
|
+
const newNorm = newPath.replace(/\/+/g, "/");
|
|
142
|
+
if (this.store.has(newNorm) || this.hasAnyChild(newNorm)) {
|
|
143
|
+
return `Error: The destination ${newPath} already exists`;
|
|
144
|
+
}
|
|
145
|
+
if (this.isDirectory(oldNorm)) {
|
|
146
|
+
const oldPrefix = `${oldNorm}/`;
|
|
147
|
+
const entries = Array.from(this.store.entries()).filter(([k]) => k.startsWith(oldPrefix) || k === oldNorm);
|
|
148
|
+
const newPrefix = `${newNorm}/`;
|
|
149
|
+
for (const [k, v] of entries) {
|
|
150
|
+
this.store.delete(k);
|
|
151
|
+
const newKey = k === oldNorm ? newNorm : newPrefix + k.slice(oldPrefix.length);
|
|
152
|
+
this.store.set(newKey, v);
|
|
153
|
+
}
|
|
154
|
+
} else {
|
|
155
|
+
const content = this.store.get(oldNorm);
|
|
156
|
+
if (content === undefined) {
|
|
157
|
+
return `Error: The path ${oldPath} does not exist`;
|
|
158
|
+
}
|
|
159
|
+
this.store.delete(oldNorm);
|
|
160
|
+
this.ensureParentDir(newNorm);
|
|
161
|
+
this.store.set(newNorm, content);
|
|
162
|
+
}
|
|
163
|
+
return `Successfully renamed ${oldPath} to ${newPath}`;
|
|
164
|
+
}
|
|
165
|
+
isDirectory(path) {
|
|
166
|
+
if (path === "/memories")
|
|
167
|
+
return true;
|
|
168
|
+
for (const key of this.store.keys()) {
|
|
169
|
+
if (key.startsWith(path + "/"))
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
hasAnyChild(path) {
|
|
175
|
+
const prefix = path.endsWith("/") ? path : `${path}/`;
|
|
176
|
+
for (const key of this.store.keys()) {
|
|
177
|
+
if (key.startsWith(prefix))
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
ensureParentDir(path) {
|
|
183
|
+
const parts = path.split("/").filter(Boolean);
|
|
184
|
+
parts.pop();
|
|
185
|
+
for (let i = 1;i <= parts.length; i++) {
|
|
186
|
+
const p = "/" + parts.slice(0, i).join("/");
|
|
187
|
+
if (!this.store.has(p)) {
|
|
188
|
+
this.store.set(p, "");
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
listDirectory(path) {
|
|
193
|
+
const prefix = path === "/memories" ? "/memories/" : `${path}/`;
|
|
194
|
+
const seen = new Set;
|
|
195
|
+
const entries = [];
|
|
196
|
+
if (path === "/memories") {
|
|
197
|
+
entries.push({
|
|
198
|
+
path: "/memories",
|
|
199
|
+
size: Array.from(this.store.keys()).filter((k) => k.startsWith("/memories/")).reduce((acc, k) => acc + (this.store.get(k)?.length ?? 0), 0)
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
for (const key of this.store.keys()) {
|
|
203
|
+
if (!key.startsWith(prefix) && key !== path)
|
|
204
|
+
continue;
|
|
205
|
+
const rel = key.slice(prefix.length);
|
|
206
|
+
const first = rel.split("/")[0];
|
|
207
|
+
if (!first || first.startsWith(".") || first === "node_modules")
|
|
208
|
+
continue;
|
|
209
|
+
const fullPath = path === "/memories" ? `/memories/${first}` : `${path}/${first}`;
|
|
210
|
+
if (seen.has(fullPath))
|
|
211
|
+
continue;
|
|
212
|
+
seen.add(fullPath);
|
|
213
|
+
let size = 0;
|
|
214
|
+
if (this.store.has(key)) {
|
|
215
|
+
size = (this.store.get(key) ?? "").length;
|
|
216
|
+
} else {
|
|
217
|
+
for (const k of this.store.keys()) {
|
|
218
|
+
if (k.startsWith(fullPath + "/") || k === fullPath) {
|
|
219
|
+
size += (this.store.get(k) ?? "").length;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
entries.push({ path: fullPath, size });
|
|
224
|
+
}
|
|
225
|
+
const lines = entries.slice(0, 50).map((e) => `${formatSize(e.size)} ${e.path}`).join(`
|
|
226
|
+
`);
|
|
227
|
+
return `Here're the files and directories up to 2 levels deep in ${path}, excluding hidden items and node_modules:
|
|
228
|
+
${lines}`;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
function escapeRegex(s) {
|
|
232
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
233
|
+
}
|
|
234
|
+
export {
|
|
235
|
+
InMemoryAgentMemoryStore
|
|
236
|
+
};
|