@botbotgo/agent-harness 0.0.475 → 0.0.476
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 +3 -1234
- package/README.zh.md +3 -1191
- package/dist/acp.js +1 -1
- package/dist/api.js +1 -404
- package/dist/benchmark/checkpoint-resume-cost-benchmark.js +1 -55
- package/dist/benchmark/deepagent-local-model-benchmark.js +2 -35
- package/dist/benchmark/upstream-runtime-ab-benchmark.js +1 -179
- package/dist/cli/chat-interactive.js +25 -244
- package/dist/cli/chat-rendering.js +6 -100
- package/dist/cli/chat-stream.js +23 -512
- package/dist/cli/chat-ui.js +21 -199
- package/dist/cli/chat-workspace.js +2 -210
- package/dist/cli/main.js +21 -428
- package/dist/cli/managed-service-commands.js +9 -63
- package/dist/cli/managed-service.js +2 -137
- package/dist/cli/options-init-chat.js +1 -108
- package/dist/cli/options-runtime.js +1 -158
- package/dist/cli/options-serve.js +1 -282
- package/dist/cli/options.js +2 -19
- package/dist/cli/process-guards.js +1 -139
- package/dist/cli/request-tree.js +7 -296
- package/dist/cli/runtime-commands.js +12 -258
- package/dist/cli/runtime-output.js +16 -155
- package/dist/cli/server-commands.js +16 -270
- package/dist/cli/workspace.js +1 -67
- package/dist/cli.js +1 -7
- package/dist/client/acp.js +1 -1
- package/dist/client/in-process.js +1 -67
- package/dist/client/index.js +1 -2
- package/dist/client/types.js +0 -1
- package/dist/client.js +1 -1
- package/dist/contracts/core.js +1 -1
- package/dist/contracts/runtime-evaluation.js +0 -1
- package/dist/contracts/runtime-memory.js +0 -1
- package/dist/contracts/runtime-observability.js +0 -1
- package/dist/contracts/runtime-requests.js +0 -1
- package/dist/contracts/runtime-scheduling.js +0 -1
- package/dist/contracts/runtime.js +1 -27
- package/dist/contracts/types.js +1 -3
- package/dist/contracts/workspace.js +0 -1
- package/dist/flow/build-flow-graph.js +1 -50
- package/dist/flow/export-mermaid.js +2 -464
- package/dist/flow/export-sequence-mermaid.js +2 -325
- package/dist/flow/flow-graph-normalization.js +1 -214
- package/dist/flow/flow-graph-runtime.js +1 -107
- package/dist/flow/flow-graph-upstream.js +1 -494
- package/dist/flow/index.js +1 -3
- package/dist/flow/types.js +0 -1
- package/dist/index.js +1 -5
- package/dist/init-project.js +1 -1
- package/dist/knowledge/config.js +1 -32
- package/dist/knowledge/contracts.js +0 -1
- package/dist/knowledge/index.js +1 -2
- package/dist/knowledge/module.js +12 -909
- package/dist/knowledge/procedural/config.js +1 -125
- package/dist/knowledge/procedural/index.js +1 -2
- package/dist/knowledge/procedural/manager.js +9 -345
- package/dist/mcp.js +1 -2
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -2
- package/dist/persistence/file-store.js +3 -758
- package/dist/persistence/sqlite-request-context-store.js +5 -54
- package/dist/persistence/sqlite-request-queue-store.js +10 -108
- package/dist/persistence/sqlite-runtime.js +1 -86
- package/dist/persistence/sqlite-store.js +62 -810
- package/dist/persistence/types.js +0 -1
- package/dist/projections/presentation.js +37 -206
- package/dist/projections/request-events.js +2 -502
- package/dist/projections/upstream-events.js +1 -201
- package/dist/protocol/a2a/http-discovery.js +1 -178
- package/dist/protocol/a2a/http-rpc.js +6 -622
- package/dist/protocol/a2a/http.js +1 -138
- package/dist/protocol/a2a/task-state.js +3 -317
- package/dist/protocol/acp/client.js +8 -294
- package/dist/protocol/acp/harness-client.js +1 -218
- package/dist/protocol/acp/http.js +5 -130
- package/dist/protocol/acp/server.js +1 -310
- package/dist/protocol/acp/stdio.js +2 -69
- package/dist/protocol/ag-ui/http.js +3 -378
- package/dist/protocol/mcp/server.js +1 -428
- package/dist/resource/backend/workspace-scoped-backend.js +1 -319
- package/dist/resource/isolation.js +1 -237
- package/dist/resource/mcp/tool-support.js +3 -296
- package/dist/resource/mcp-tool-support.js +1 -2
- package/dist/resource/providers/resource-provider.js +1 -215
- package/dist/resource/resource-impl.js +1 -3
- package/dist/resource/resource-types.js +0 -1
- package/dist/resource/resource.js +1 -1
- package/dist/resource/sources.js +1 -247
- package/dist/resource/tools/function-tool-resolver.js +2 -272
- package/dist/runtime/adapter/compat/deepagent-compat.js +1 -29
- package/dist/runtime/adapter/compat/openai-compatible.js +1 -55
- package/dist/runtime/adapter/direct-builtin-utility.js +2 -90
- package/dist/runtime/adapter/flow/execution-context.js +1 -71
- package/dist/runtime/adapter/flow/invocation-flow.js +8 -425
- package/dist/runtime/adapter/flow/invoke-runtime.js +1 -20
- package/dist/runtime/adapter/flow/stream-runtime.js +11 -1395
- package/dist/runtime/adapter/invocation-result.js +2 -473
- package/dist/runtime/adapter/local-tool-invocation.js +6 -638
- package/dist/runtime/adapter/middleware/context-hygiene.js +1 -83
- package/dist/runtime/adapter/middleware-assembly.js +5 -477
- package/dist/runtime/adapter/model/invocation-request.js +3 -183
- package/dist/runtime/adapter/model/message-assembly.js +1 -28
- package/dist/runtime/adapter/model/model-providers.js +23 -1115
- package/dist/runtime/adapter/model/prompted-json-tool-call-capture.js +1 -40
- package/dist/runtime/adapter/model/prompted-json-tool-policy.js +1 -22
- package/dist/runtime/adapter/resilience.js +1 -104
- package/dist/runtime/adapter/runtime-adapter-support.js +3 -141
- package/dist/runtime/adapter/runtime-shell.js +5 -166
- package/dist/runtime/adapter/stream-event-projection.js +2 -622
- package/dist/runtime/adapter/stream-text-consumption.js +1 -18
- package/dist/runtime/adapter/terminal-status.js +2 -67
- package/dist/runtime/adapter/tool/builtin-middleware-tools.js +6 -627
- package/dist/runtime/adapter/tool/declared-middleware.js +1 -154
- package/dist/runtime/adapter/tool/interrupt-policy.js +1 -34
- package/dist/runtime/adapter/tool/provider-tool.js +1 -25
- package/dist/runtime/adapter/tool/resolved-tool.js +1 -225
- package/dist/runtime/adapter/tool/tool-arguments.js +3 -486
- package/dist/runtime/adapter/tool/tool-hitl.js +1 -346
- package/dist/runtime/adapter/tool/tool-name-mapping.js +1 -128
- package/dist/runtime/adapter/tool/tool-output-artifacts.js +2 -88
- package/dist/runtime/adapter/tool/tool-replay.js +1 -37
- package/dist/runtime/adapter/tool-resolution.js +1 -86
- package/dist/runtime/adapter/upstream-configurable-keys.js +1 -2
- package/dist/runtime/agent-runtime-adapter.js +60 -2338
- package/dist/runtime/agent-runtime-assembly.js +7 -249
- package/dist/runtime/env/runtime-env.js +1 -62
- package/dist/runtime/harness/background-runtime.js +1 -8
- package/dist/runtime/harness/bindings.js +1 -58
- package/dist/runtime/harness/events/event-bus.js +1 -16
- package/dist/runtime/harness/events/event-sink.js +1 -61
- package/dist/runtime/harness/events/events.js +1 -80
- package/dist/runtime/harness/events/listener-runtime.js +1 -13
- package/dist/runtime/harness/events/runtime-event-operations.js +1 -9
- package/dist/runtime/harness/events/streaming.js +1 -100
- package/dist/runtime/harness/events/timeline.js +1 -52
- package/dist/runtime/harness/public-shapes.js +1 -186
- package/dist/runtime/harness/run/artifact-paths.js +1 -15
- package/dist/runtime/harness/run/governance.js +1 -295
- package/dist/runtime/harness/run/helpers.js +1 -71
- package/dist/runtime/harness/run/inspection.js +1 -409
- package/dist/runtime/harness/run/operator-overview.js +1 -80
- package/dist/runtime/harness/run/queue-diagnostics.js +1 -15
- package/dist/runtime/harness/run/recovery.js +1 -162
- package/dist/runtime/harness/run/resources.js +1 -60
- package/dist/runtime/harness/run/resume.js +1 -56
- package/dist/runtime/harness/run/routing.js +1 -48
- package/dist/runtime/harness/run/run-lifecycle.js +1 -66
- package/dist/runtime/harness/run/run-operations.js +1 -217
- package/dist/runtime/harness/run/run-queue.js +1 -43
- package/dist/runtime/harness/run/run-slot-acquisition.js +1 -157
- package/dist/runtime/harness/run/session-records.js +1 -97
- package/dist/runtime/harness/run/start-run.js +1 -120
- package/dist/runtime/harness/run/startup-runtime.js +1 -69
- package/dist/runtime/harness/run/stream-run.js +8 -1418
- package/dist/runtime/harness/run/surface-semantics.js +1 -79
- package/dist/runtime/harness/runtime-defaults.js +1 -39
- package/dist/runtime/harness/system/boundary-analysis.js +1 -234
- package/dist/runtime/harness/system/health-monitor.js +1 -258
- package/dist/runtime/harness/system/inventory.js +1 -129
- package/dist/runtime/harness/system/mem0-ingestion-sync.js +5 -345
- package/dist/runtime/harness/system/policy-engine.js +1 -175
- package/dist/runtime/harness/system/runtime-memory-candidates.js +4 -110
- package/dist/runtime/harness/system/runtime-memory-consolidation.js +1 -51
- package/dist/runtime/harness/system/runtime-memory-manager.js +10 -693
- package/dist/runtime/harness/system/runtime-memory-policy.js +1 -155
- package/dist/runtime/harness/system/runtime-memory-records.js +11 -577
- package/dist/runtime/harness/system/runtime-memory-sync.js +5 -206
- package/dist/runtime/harness/system/session-memory-sync.js +3 -113
- package/dist/runtime/harness/system/skill-requirements.js +1 -112
- package/dist/runtime/harness/system/store.js +9 -365
- package/dist/runtime/harness/tool-gateway/index.js +1 -2
- package/dist/runtime/harness/tool-gateway/policy.js +1 -45
- package/dist/runtime/harness/tool-gateway/validation.js +1 -176
- package/dist/runtime/harness/tool-schema.js +1 -3
- package/dist/runtime/harness.js +3 -1490
- package/dist/runtime/index.js +1 -3
- package/dist/runtime/layout/runtime-layout.js +1 -31
- package/dist/runtime/maintenance/checkpoint-maintenance.js +2 -178
- package/dist/runtime/maintenance/file-checkpoint-saver.js +1 -106
- package/dist/runtime/maintenance/runtime-record-maintenance.js +2 -169
- package/dist/runtime/maintenance/sqlite-checkpoint-saver.js +4 -289
- package/dist/runtime/parsing/output-content.js +10 -550
- package/dist/runtime/parsing/output-parsing.js +1 -4
- package/dist/runtime/parsing/output-recovery.js +3 -213
- package/dist/runtime/parsing/output-tool-args.js +7 -663
- package/dist/runtime/parsing/stream-event-parsing.js +3 -362
- package/dist/runtime/prompts/runtime-prompts.js +4 -73
- package/dist/runtime/scheduling/system-schedule-manager.js +11 -532
- package/dist/runtime/skills/skill-metadata.js +1 -197
- package/dist/runtime/startup-tracing.js +2 -37
- package/dist/runtime/support/compiled-binding.js +1 -290
- package/dist/runtime/support/embedding-models.js +1 -118
- package/dist/runtime/support/harness-support.js +5 -137
- package/dist/runtime/support/llamaindex.js +1 -108
- package/dist/runtime/support/runtime-adapter-options.js +1 -29
- package/dist/runtime/support/runtime-factories.js +1 -51
- package/dist/runtime/support/vector-stores.js +9 -270
- package/dist/scaffold/init-project.js +54 -233
- package/dist/tooling/extensions.js +1 -311
- package/dist/tooling/module-loader.js +1 -55
- package/dist/tools.js +1 -176
- package/dist/utils/agent-display.js +1 -18
- package/dist/utils/bundled-text.js +4 -39
- package/dist/utils/compiled-binding.js +1 -33
- package/dist/utils/fs.js +2 -45
- package/dist/utils/id.js +1 -9
- package/dist/utils/message-content.js +1 -30
- package/dist/utils/object.js +1 -6
- package/dist/workspace/agent-binding-compiler.js +3 -613
- package/dist/workspace/compile.js +1 -472
- package/dist/workspace/framework-contract-validation.js +2 -322
- package/dist/workspace/index.js +1 -1
- package/dist/workspace/object-loader-paths.js +1 -71
- package/dist/workspace/object-loader-readers.js +1 -187
- package/dist/workspace/object-loader.js +1 -754
- package/dist/workspace/resource-compilers.js +1 -374
- package/dist/workspace/support/agent-capabilities.js +1 -37
- package/dist/workspace/support/agent-execution-config.js +1 -44
- package/dist/workspace/support/discovery.js +1 -147
- package/dist/workspace/support/source-collectors.js +1 -30
- package/dist/workspace/support/source-protocols.js +2 -192
- package/dist/workspace/support/workspace-ref-utils.js +1 -362
- package/dist/workspace/tool-hydration.js +1 -280
- package/dist/workspace/validate.js +1 -99
- package/dist/workspace/yaml-object-reader.js +1 -285
- package/package.json +7 -3
|
@@ -1,219 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { mkdirSync } from "node:fs";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { InMemoryStore } from "@langchain/langgraph";
|
|
5
|
-
import { createClient } from "@libsql/client";
|
|
6
|
-
const NAMESPACE_SEPARATOR = "\u001f";
|
|
7
|
-
function encodeValue(value) {
|
|
8
|
-
if (value instanceof Date) {
|
|
9
|
-
return {
|
|
10
|
-
__type: "Date",
|
|
11
|
-
value: value.toISOString(),
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
if (value instanceof Uint8Array) {
|
|
15
|
-
return {
|
|
16
|
-
__type: "Uint8Array",
|
|
17
|
-
data: Array.from(value),
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
if (value instanceof Map) {
|
|
21
|
-
return {
|
|
22
|
-
__type: "Map",
|
|
23
|
-
entries: Array.from(value.entries()).map(([key, entry]) => [encodeValue(key), encodeValue(entry)]),
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
if (Array.isArray(value)) {
|
|
27
|
-
return value.map((item) => encodeValue(item));
|
|
28
|
-
}
|
|
29
|
-
if (typeof value === "object" && value) {
|
|
30
|
-
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, encodeValue(entry)]));
|
|
31
|
-
}
|
|
32
|
-
return value;
|
|
33
|
-
}
|
|
34
|
-
function decodeValue(value) {
|
|
35
|
-
if (Array.isArray(value)) {
|
|
36
|
-
return value.map((item) => decodeValue(item));
|
|
37
|
-
}
|
|
38
|
-
if (typeof value === "object" && value) {
|
|
39
|
-
const typed = value;
|
|
40
|
-
if (typed.__type === "Date" && typeof typed.value === "string") {
|
|
41
|
-
return new Date(typed.value);
|
|
42
|
-
}
|
|
43
|
-
if (typed.__type === "Uint8Array" && Array.isArray(typed.data)) {
|
|
44
|
-
return new Uint8Array(typed.data.map((item) => Number(item)));
|
|
45
|
-
}
|
|
46
|
-
if (typed.__type === "Map" && Array.isArray(typed.entries)) {
|
|
47
|
-
return new Map(typed.entries.map((entry) => {
|
|
48
|
-
const [key, item] = Array.isArray(entry) ? entry : [undefined, undefined];
|
|
49
|
-
return [decodeValue(key), decodeValue(item)];
|
|
50
|
-
}));
|
|
51
|
-
}
|
|
52
|
-
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, decodeValue(entry)]));
|
|
53
|
-
}
|
|
54
|
-
return value;
|
|
55
|
-
}
|
|
56
|
-
function serializeNamespace(namespace) {
|
|
57
|
-
return namespace.join(NAMESPACE_SEPARATOR);
|
|
58
|
-
}
|
|
59
|
-
function parseRow(row) {
|
|
60
|
-
return {
|
|
61
|
-
value: decodeValue(JSON.parse(row.value_json)),
|
|
62
|
-
key: row.key,
|
|
63
|
-
namespace: JSON.parse(row.namespace_json),
|
|
64
|
-
createdAt: new Date(row.created_at),
|
|
65
|
-
updatedAt: new Date(row.updated_at),
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
function isKnowledgeRecordNamespace(namespace) {
|
|
69
|
-
return namespace.length === 3 && namespace[0] === "memories" && namespace[1] === "records";
|
|
70
|
-
}
|
|
71
|
-
function extractKnowledgeRecordEntry(namespace, key, value, createdAt, updatedAt) {
|
|
72
|
-
if (!isKnowledgeRecordNamespace(namespace) || typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
73
|
-
return null;
|
|
74
|
-
}
|
|
75
|
-
const typed = value;
|
|
76
|
-
const recordId = typeof typed.id === "string" ? typed.id : undefined;
|
|
77
|
-
const scope = typeof typed.scope === "string" ? typed.scope : undefined;
|
|
78
|
-
const kind = typeof typed.kind === "string" ? typed.kind : undefined;
|
|
79
|
-
const status = typeof typed.status === "string" ? typed.status : undefined;
|
|
80
|
-
const canonicalKey = typeof typed.canonicalKey === "string" ? typed.canonicalKey : undefined;
|
|
81
|
-
const sourceType = typeof typed.sourceType === "string" ? typed.sourceType : undefined;
|
|
82
|
-
const summary = typeof typed.summary === "string" ? typed.summary : undefined;
|
|
83
|
-
const content = typeof typed.content === "string" ? typed.content : undefined;
|
|
84
|
-
if (!recordId || !scope || !kind || !status || !canonicalKey || !sourceType || !summary || !content) {
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
|
-
return {
|
|
88
|
-
namespace: serializeNamespace(namespace),
|
|
89
|
-
key,
|
|
90
|
-
record_id: recordId,
|
|
91
|
-
scope,
|
|
92
|
-
kind,
|
|
93
|
-
status,
|
|
94
|
-
canonical_key: canonicalKey,
|
|
95
|
-
source_type: sourceType,
|
|
96
|
-
knowledge_identity: typeof typed.knowledgeIdentity === "string" ? typed.knowledgeIdentity : null,
|
|
97
|
-
knowledge_operation: typeof typed.knowledgeOperation === "string" ? typed.knowledgeOperation : null,
|
|
98
|
-
summary_text: summary,
|
|
99
|
-
content_text: content,
|
|
100
|
-
confidence: typeof typed.confidence === "number" ? typed.confidence : null,
|
|
101
|
-
observed_at: typeof typed.observedAt === "string" ? typed.observedAt : null,
|
|
102
|
-
last_confirmed_at: typeof typed.lastConfirmedAt === "string" ? typed.lastConfirmedAt : null,
|
|
103
|
-
created_at: createdAt,
|
|
104
|
-
updated_at: updatedAt,
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
export class FileBackedStore {
|
|
108
|
-
filePath;
|
|
109
|
-
delegate = new InMemoryStore();
|
|
110
|
-
loaded = false;
|
|
111
|
-
operationChain = Promise.resolve();
|
|
112
|
-
constructor(filePath) {
|
|
113
|
-
this.filePath = filePath;
|
|
114
|
-
}
|
|
115
|
-
async runSerialized(operation) {
|
|
116
|
-
const pending = this.operationChain.then(operation, operation);
|
|
117
|
-
this.operationChain = pending.then(() => undefined, () => undefined);
|
|
118
|
-
return pending;
|
|
119
|
-
}
|
|
120
|
-
async ensureLoaded() {
|
|
121
|
-
if (this.loaded) {
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
try {
|
|
125
|
-
const raw = await readFile(this.filePath, "utf8");
|
|
126
|
-
const parsed = JSON.parse(raw);
|
|
127
|
-
this.delegate.data = decodeValue(parsed.data);
|
|
128
|
-
this.delegate.vectors = decodeValue(parsed.vectors);
|
|
129
|
-
}
|
|
130
|
-
catch {
|
|
131
|
-
this.delegate.data = new Map();
|
|
132
|
-
this.delegate.vectors = new Map();
|
|
133
|
-
}
|
|
134
|
-
this.loaded = true;
|
|
135
|
-
}
|
|
136
|
-
async persist() {
|
|
137
|
-
await mkdir(path.dirname(this.filePath), { recursive: true });
|
|
138
|
-
await writeFile(this.filePath, JSON.stringify({
|
|
139
|
-
data: encodeValue(this.delegate.data),
|
|
140
|
-
vectors: encodeValue(this.delegate.vectors),
|
|
141
|
-
}, null, 2), "utf8");
|
|
142
|
-
}
|
|
143
|
-
async batch(operations) {
|
|
144
|
-
return this.runSerialized(async () => {
|
|
145
|
-
await this.ensureLoaded();
|
|
146
|
-
const result = await this.delegate.batch(operations);
|
|
147
|
-
if (operations.some((operation) => "value" in operation)) {
|
|
148
|
-
await this.persist();
|
|
149
|
-
}
|
|
150
|
-
return result;
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
async get(namespace, key) {
|
|
154
|
-
return this.runSerialized(async () => {
|
|
155
|
-
await this.ensureLoaded();
|
|
156
|
-
return this.delegate.get(namespace, key);
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
async search(namespacePrefix, options) {
|
|
160
|
-
return this.runSerialized(async () => {
|
|
161
|
-
await this.ensureLoaded();
|
|
162
|
-
return this.delegate.search(namespacePrefix, options);
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
async put(namespace, key, value, index) {
|
|
166
|
-
return this.runSerialized(async () => {
|
|
167
|
-
await this.ensureLoaded();
|
|
168
|
-
const result = await this.delegate.put(namespace, key, value, index);
|
|
169
|
-
await this.persist();
|
|
170
|
-
return result;
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
async delete(namespace, key) {
|
|
174
|
-
return this.runSerialized(async () => {
|
|
175
|
-
await this.ensureLoaded();
|
|
176
|
-
const result = await this.delegate.delete(namespace, key);
|
|
177
|
-
await this.persist();
|
|
178
|
-
return result;
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
async listNamespaces(options) {
|
|
182
|
-
return this.runSerialized(async () => {
|
|
183
|
-
await this.ensureLoaded();
|
|
184
|
-
return this.delegate.listNamespaces(options);
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
export class SqliteBackedStore {
|
|
189
|
-
filePath;
|
|
190
|
-
client = null;
|
|
191
|
-
initialized = false;
|
|
192
|
-
initialization = null;
|
|
193
|
-
constructor(filePath) {
|
|
194
|
-
this.filePath = filePath;
|
|
195
|
-
mkdirSync(path.dirname(filePath), { recursive: true });
|
|
196
|
-
}
|
|
197
|
-
async getClient() {
|
|
198
|
-
if (!this.client) {
|
|
199
|
-
this.client = createClient({ url: `file:${this.filePath}` });
|
|
200
|
-
}
|
|
201
|
-
return this.client;
|
|
202
|
-
}
|
|
203
|
-
async ensureInitialized() {
|
|
204
|
-
if (this.initialized) {
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
if (this.initialization) {
|
|
208
|
-
await this.initialization;
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
this.initialization = (async () => {
|
|
212
|
-
const client = await this.getClient();
|
|
213
|
-
await client.execute("PRAGMA journal_mode=WAL");
|
|
214
|
-
await client.execute("PRAGMA foreign_keys=ON");
|
|
215
|
-
await client.execute("PRAGMA busy_timeout=5000");
|
|
216
|
-
await client.execute(`
|
|
1
|
+
import{mkdir as N,readFile as k,writeFile as A}from"node:fs/promises";import{mkdirSync as O}from"node:fs";import E from"node:path";import{InMemoryStore as m}from"@langchain/langgraph";import{createClient as L}from"@libsql/client";const p="";function c(a){return a instanceof Date?{__type:"Date",value:a.toISOString()}:a instanceof Uint8Array?{__type:"Uint8Array",data:Array.from(a)}:a instanceof Map?{__type:"Map",entries:Array.from(a.entries()).map(([e,t])=>[c(e),c(t)])}:Array.isArray(a)?a.map(e=>c(e)):typeof a=="object"&&a?Object.fromEntries(Object.entries(a).map(([e,t])=>[e,c(t)])):a}function o(a){if(Array.isArray(a))return a.map(e=>o(e));if(typeof a=="object"&&a){const e=a;return e.__type==="Date"&&typeof e.value=="string"?new Date(e.value):e.__type==="Uint8Array"&&Array.isArray(e.data)?new Uint8Array(e.data.map(t=>Number(t))):e.__type==="Map"&&Array.isArray(e.entries)?new Map(e.entries.map(t=>{const[i,s]=Array.isArray(t)?t:[void 0,void 0];return[o(i),o(s)]})):Object.fromEntries(Object.entries(a).map(([t,i])=>[t,o(i)]))}return a}function l(a){return a.join(p)}function g(a){return{value:o(JSON.parse(a.value_json)),key:a.key,namespace:JSON.parse(a.namespace_json),createdAt:new Date(a.created_at),updatedAt:new Date(a.updated_at)}}function x(a){return a.length===3&&a[0]==="memories"&&a[1]==="records"}function h(a,e,t,i,s){if(!x(a)||typeof t!="object"||t===null||Array.isArray(t))return null;const n=t,r=typeof n.id=="string"?n.id:void 0,d=typeof n.scope=="string"?n.scope:void 0,_=typeof n.kind=="string"?n.kind:void 0,u=typeof n.status=="string"?n.status:void 0,y=typeof n.canonicalKey=="string"?n.canonicalKey:void 0,w=typeof n.sourceType=="string"?n.sourceType:void 0,f=typeof n.summary=="string"?n.summary:void 0,T=typeof n.content=="string"?n.content:void 0;return!r||!d||!_||!u||!y||!w||!f||!T?null:{namespace:l(a),key:e,record_id:r,scope:d,kind:_,status:u,canonical_key:y,source_type:w,knowledge_identity:typeof n.knowledgeIdentity=="string"?n.knowledgeIdentity:null,knowledge_operation:typeof n.knowledgeOperation=="string"?n.knowledgeOperation:null,summary_text:f,content_text:T,confidence:typeof n.confidence=="number"?n.confidence:null,observed_at:typeof n.observedAt=="string"?n.observedAt:null,last_confirmed_at:typeof n.lastConfirmedAt=="string"?n.lastConfirmedAt:null,created_at:i,updated_at:s}}class j{filePath;delegate=new m;loaded=!1;operationChain=Promise.resolve();constructor(e){this.filePath=e}async runSerialized(e){const t=this.operationChain.then(e,e);return this.operationChain=t.then(()=>{},()=>{}),t}async ensureLoaded(){if(!this.loaded){try{const e=await k(this.filePath,"utf8"),t=JSON.parse(e);this.delegate.data=o(t.data),this.delegate.vectors=o(t.vectors)}catch{this.delegate.data=new Map,this.delegate.vectors=new Map}this.loaded=!0}}async persist(){await N(E.dirname(this.filePath),{recursive:!0}),await A(this.filePath,JSON.stringify({data:c(this.delegate.data),vectors:c(this.delegate.vectors)},null,2),"utf8")}async batch(e){return this.runSerialized(async()=>{await this.ensureLoaded();const t=await this.delegate.batch(e);return e.some(i=>"value"in i)&&await this.persist(),t})}async get(e,t){return this.runSerialized(async()=>(await this.ensureLoaded(),this.delegate.get(e,t)))}async search(e,t){return this.runSerialized(async()=>(await this.ensureLoaded(),this.delegate.search(e,t)))}async put(e,t,i,s){return this.runSerialized(async()=>{await this.ensureLoaded();const n=await this.delegate.put(e,t,i,s);return await this.persist(),n})}async delete(e,t){return this.runSerialized(async()=>{await this.ensureLoaded();const i=await this.delegate.delete(e,t);return await this.persist(),i})}async listNamespaces(e){return this.runSerialized(async()=>(await this.ensureLoaded(),this.delegate.listNamespaces(e)))}}class U{filePath;client=null;initialized=!1;initialization=null;constructor(e){this.filePath=e,O(E.dirname(e),{recursive:!0})}async getClient(){return this.client||(this.client=L({url:`file:${this.filePath}`})),this.client}async ensureInitialized(){if(!this.initialized){if(this.initialization){await this.initialization;return}this.initialization=(async()=>{const e=await this.getClient();await e.execute("PRAGMA journal_mode=WAL"),await e.execute("PRAGMA foreign_keys=ON"),await e.execute("PRAGMA busy_timeout=5000"),await e.execute(`
|
|
217
2
|
CREATE TABLE IF NOT EXISTS store_entries (
|
|
218
3
|
namespace TEXT NOT NULL,
|
|
219
4
|
namespace_json TEXT NOT NULL,
|
|
@@ -223,9 +8,7 @@ export class SqliteBackedStore {
|
|
|
223
8
|
updated_at TEXT NOT NULL,
|
|
224
9
|
PRIMARY KEY (namespace, key)
|
|
225
10
|
)
|
|
226
|
-
`)
|
|
227
|
-
await client.execute("CREATE INDEX IF NOT EXISTS idx_store_entries_namespace ON store_entries(namespace)");
|
|
228
|
-
await client.execute(`
|
|
11
|
+
`),await e.execute("CREATE INDEX IF NOT EXISTS idx_store_entries_namespace ON store_entries(namespace)"),await e.execute(`
|
|
229
12
|
CREATE TABLE IF NOT EXISTS knowledge_record_entries (
|
|
230
13
|
namespace TEXT NOT NULL,
|
|
231
14
|
key TEXT NOT NULL,
|
|
@@ -246,51 +29,9 @@ export class SqliteBackedStore {
|
|
|
246
29
|
updated_at TEXT NOT NULL,
|
|
247
30
|
PRIMARY KEY (namespace, key)
|
|
248
31
|
)
|
|
249
|
-
`);
|
|
250
|
-
await this.ensureKnowledgeRecordEntryColumns(client);
|
|
251
|
-
await client.execute("CREATE INDEX IF NOT EXISTS idx_knowledge_record_entries_scope_status ON knowledge_record_entries(scope, status)");
|
|
252
|
-
await client.execute("CREATE INDEX IF NOT EXISTS idx_knowledge_record_entries_canonical_key ON knowledge_record_entries(canonical_key)");
|
|
253
|
-
await client.execute("CREATE INDEX IF NOT EXISTS idx_knowledge_record_entries_knowledge_identity ON knowledge_record_entries(knowledge_identity)");
|
|
254
|
-
await client.execute("CREATE INDEX IF NOT EXISTS idx_knowledge_record_entries_record_id ON knowledge_record_entries(record_id)");
|
|
255
|
-
await this.backfillKnowledgeRecordEntries(client);
|
|
256
|
-
this.initialized = true;
|
|
257
|
-
this.initialization = null;
|
|
258
|
-
})();
|
|
259
|
-
await this.initialization;
|
|
260
|
-
}
|
|
261
|
-
async ensureKnowledgeRecordEntryColumns(client) {
|
|
262
|
-
const result = await client.execute("PRAGMA table_info(knowledge_record_entries)");
|
|
263
|
-
const existing = new Set(result.rows.map((row) => String(row.name ?? "")));
|
|
264
|
-
if (!existing.has("knowledge_identity")) {
|
|
265
|
-
await client.execute("ALTER TABLE knowledge_record_entries ADD COLUMN knowledge_identity TEXT");
|
|
266
|
-
}
|
|
267
|
-
if (!existing.has("knowledge_operation")) {
|
|
268
|
-
await client.execute("ALTER TABLE knowledge_record_entries ADD COLUMN knowledge_operation TEXT");
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
async backfillKnowledgeRecordEntries(client) {
|
|
272
|
-
const countResult = await client.execute("SELECT COUNT(*) AS count FROM knowledge_record_entries");
|
|
273
|
-
const count = Number(countResult.rows?.[0]?.count ?? 0);
|
|
274
|
-
if (count > 0) {
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
const result = await client.execute({
|
|
278
|
-
sql: `SELECT namespace, namespace_json, key, value_json, created_at, updated_at
|
|
32
|
+
`),await this.ensureKnowledgeRecordEntryColumns(e),await e.execute("CREATE INDEX IF NOT EXISTS idx_knowledge_record_entries_scope_status ON knowledge_record_entries(scope, status)"),await e.execute("CREATE INDEX IF NOT EXISTS idx_knowledge_record_entries_canonical_key ON knowledge_record_entries(canonical_key)"),await e.execute("CREATE INDEX IF NOT EXISTS idx_knowledge_record_entries_knowledge_identity ON knowledge_record_entries(knowledge_identity)"),await e.execute("CREATE INDEX IF NOT EXISTS idx_knowledge_record_entries_record_id ON knowledge_record_entries(record_id)"),await this.backfillKnowledgeRecordEntries(e),this.initialized=!0,this.initialization=null})(),await this.initialization}}async ensureKnowledgeRecordEntryColumns(e){const t=await e.execute("PRAGMA table_info(knowledge_record_entries)"),i=new Set(t.rows.map(s=>String(s.name??"")));i.has("knowledge_identity")||await e.execute("ALTER TABLE knowledge_record_entries ADD COLUMN knowledge_identity TEXT"),i.has("knowledge_operation")||await e.execute("ALTER TABLE knowledge_record_entries ADD COLUMN knowledge_operation TEXT")}async backfillKnowledgeRecordEntries(e){const t=await e.execute("SELECT COUNT(*) AS count FROM knowledge_record_entries");if(Number(t.rows?.[0]?.count??0)>0)return;const s=await e.execute({sql:`SELECT namespace, namespace_json, key, value_json, created_at, updated_at
|
|
279
33
|
FROM store_entries
|
|
280
|
-
WHERE namespace LIKE ?`,
|
|
281
|
-
args: [`memories${NAMESPACE_SEPARATOR}records${NAMESPACE_SEPARATOR}%`],
|
|
282
|
-
});
|
|
283
|
-
for (const row of result.rows) {
|
|
284
|
-
const namespace = JSON.parse(row.namespace_json);
|
|
285
|
-
const entry = extractKnowledgeRecordEntry(namespace, row.key, decodeValue(JSON.parse(row.value_json)), row.created_at, row.updated_at);
|
|
286
|
-
if (entry) {
|
|
287
|
-
await this.upsertKnowledgeRecordEntry(client, entry);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
async upsertKnowledgeRecordEntry(client, entry) {
|
|
292
|
-
await client.execute({
|
|
293
|
-
sql: `INSERT INTO knowledge_record_entries (
|
|
34
|
+
WHERE namespace LIKE ?`,args:[`memories${p}records${p}%`]});for(const n of s.rows){const r=JSON.parse(n.namespace_json),d=h(r,n.key,o(JSON.parse(n.value_json)),n.created_at,n.updated_at);d&&await this.upsertKnowledgeRecordEntry(e,d)}}async upsertKnowledgeRecordEntry(e,t){await e.execute({sql:`INSERT INTO knowledge_record_entries (
|
|
294
35
|
namespace, key, record_id, scope, kind, status, canonical_key, source_type,
|
|
295
36
|
knowledge_identity, knowledge_operation, summary_text, content_text, confidence, observed_at, last_confirmed_at, created_at, updated_at
|
|
296
37
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
@@ -308,113 +49,16 @@ export class SqliteBackedStore {
|
|
|
308
49
|
confidence = excluded.confidence,
|
|
309
50
|
observed_at = excluded.observed_at,
|
|
310
51
|
last_confirmed_at = excluded.last_confirmed_at,
|
|
311
|
-
updated_at = excluded.updated_at`,
|
|
312
|
-
args: [
|
|
313
|
-
entry.namespace,
|
|
314
|
-
entry.key,
|
|
315
|
-
entry.record_id,
|
|
316
|
-
entry.scope,
|
|
317
|
-
entry.kind,
|
|
318
|
-
entry.status,
|
|
319
|
-
entry.canonical_key,
|
|
320
|
-
entry.source_type,
|
|
321
|
-
entry.knowledge_identity,
|
|
322
|
-
entry.knowledge_operation,
|
|
323
|
-
entry.summary_text,
|
|
324
|
-
entry.content_text,
|
|
325
|
-
entry.confidence,
|
|
326
|
-
entry.observed_at,
|
|
327
|
-
entry.last_confirmed_at,
|
|
328
|
-
entry.created_at,
|
|
329
|
-
entry.updated_at,
|
|
330
|
-
],
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
|
-
async deleteKnowledgeRecordEntry(client, namespace, key) {
|
|
334
|
-
await client.execute({
|
|
335
|
-
sql: `DELETE FROM knowledge_record_entries WHERE namespace = ? AND key = ?`,
|
|
336
|
-
args: [serializeNamespace(namespace), key],
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
async selectAll(sql, args = []) {
|
|
340
|
-
await this.ensureInitialized();
|
|
341
|
-
const client = await this.getClient();
|
|
342
|
-
const result = await client.execute({ sql, args });
|
|
343
|
-
return result.rows;
|
|
344
|
-
}
|
|
345
|
-
async batch(operations) {
|
|
346
|
-
const results = [];
|
|
347
|
-
for (const operation of operations) {
|
|
348
|
-
const namespace = Array.isArray(operation.namespace) ? operation.namespace.filter((item) => typeof item === "string") : [];
|
|
349
|
-
const key = typeof operation.key === "string" ? operation.key : "";
|
|
350
|
-
if ("value" in operation) {
|
|
351
|
-
await this.put(namespace, key, operation.value);
|
|
352
|
-
results.push(undefined);
|
|
353
|
-
continue;
|
|
354
|
-
}
|
|
355
|
-
if (operation.delete === true) {
|
|
356
|
-
await this.delete(namespace, key);
|
|
357
|
-
results.push(undefined);
|
|
358
|
-
continue;
|
|
359
|
-
}
|
|
360
|
-
results.push(await this.get(namespace, key));
|
|
361
|
-
}
|
|
362
|
-
return results;
|
|
363
|
-
}
|
|
364
|
-
async get(namespace, key) {
|
|
365
|
-
const rows = await this.selectAll(`SELECT namespace, namespace_json, key, value_json, created_at, updated_at
|
|
52
|
+
updated_at = excluded.updated_at`,args:[t.namespace,t.key,t.record_id,t.scope,t.kind,t.status,t.canonical_key,t.source_type,t.knowledge_identity,t.knowledge_operation,t.summary_text,t.content_text,t.confidence,t.observed_at,t.last_confirmed_at,t.created_at,t.updated_at]})}async deleteKnowledgeRecordEntry(e,t,i){await e.execute({sql:"DELETE FROM knowledge_record_entries WHERE namespace = ? AND key = ?",args:[l(t),i]})}async selectAll(e,t=[]){return await this.ensureInitialized(),(await(await this.getClient()).execute({sql:e,args:t})).rows}async batch(e){const t=[];for(const i of e){const s=Array.isArray(i.namespace)?i.namespace.filter(r=>typeof r=="string"):[],n=typeof i.key=="string"?i.key:"";if("value"in i){await this.put(s,n,i.value),t.push(void 0);continue}if(i.delete===!0){await this.delete(s,n),t.push(void 0);continue}t.push(await this.get(s,n))}return t}async get(e,t){const s=(await this.selectAll(`SELECT namespace, namespace_json, key, value_json, created_at, updated_at
|
|
366
53
|
FROM store_entries
|
|
367
|
-
WHERE namespace = ? AND key = ?`,
|
|
368
|
-
const row = rows[0];
|
|
369
|
-
return row ? parseRow(row) : null;
|
|
370
|
-
}
|
|
371
|
-
async search(namespacePrefix) {
|
|
372
|
-
const prefix = serializeNamespace(namespacePrefix);
|
|
373
|
-
const rows = await this.selectAll(`SELECT namespace, namespace_json, key, value_json, created_at, updated_at
|
|
54
|
+
WHERE namespace = ? AND key = ?`,[l(e),t]))[0];return s?g(s):null}async search(e){const t=l(e);return(await this.selectAll(`SELECT namespace, namespace_json, key, value_json, created_at, updated_at
|
|
374
55
|
FROM store_entries
|
|
375
56
|
WHERE namespace = ? OR namespace LIKE ?
|
|
376
|
-
ORDER BY namespace ASC, key ASC`,
|
|
377
|
-
return rows.map((row) => parseRow(row));
|
|
378
|
-
}
|
|
379
|
-
async put(namespace, key, value, _index) {
|
|
380
|
-
await this.ensureInitialized();
|
|
381
|
-
const client = await this.getClient();
|
|
382
|
-
const now = new Date().toISOString();
|
|
383
|
-
const serializedNamespace = serializeNamespace(namespace);
|
|
384
|
-
const encodedValue = JSON.stringify(encodeValue(value));
|
|
385
|
-
await client.execute({
|
|
386
|
-
sql: `INSERT INTO store_entries (namespace, namespace_json, key, value_json, created_at, updated_at)
|
|
57
|
+
ORDER BY namespace ASC, key ASC`,[t,`${t}${p}%`])).map(s=>g(s))}async put(e,t,i,s){await this.ensureInitialized();const n=await this.getClient(),r=new Date().toISOString(),d=l(e),_=JSON.stringify(c(i));await n.execute({sql:`INSERT INTO store_entries (namespace, namespace_json, key, value_json, created_at, updated_at)
|
|
387
58
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
388
59
|
ON CONFLICT(namespace, key) DO UPDATE SET
|
|
389
60
|
namespace_json = excluded.namespace_json,
|
|
390
61
|
value_json = excluded.value_json,
|
|
391
|
-
updated_at = excluded.updated_at`,
|
|
392
|
-
args: [serializedNamespace, JSON.stringify(namespace), key, encodedValue, now, now],
|
|
393
|
-
});
|
|
394
|
-
const knowledgeEntry = extractKnowledgeRecordEntry(namespace, key, value, now, now);
|
|
395
|
-
if (knowledgeEntry) {
|
|
396
|
-
await this.upsertKnowledgeRecordEntry(client, knowledgeEntry);
|
|
397
|
-
}
|
|
398
|
-
else {
|
|
399
|
-
await this.deleteKnowledgeRecordEntry(client, namespace, key);
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
async delete(namespace, key) {
|
|
403
|
-
await this.ensureInitialized();
|
|
404
|
-
const client = await this.getClient();
|
|
405
|
-
await client.execute({
|
|
406
|
-
sql: `DELETE FROM store_entries WHERE namespace = ? AND key = ?`,
|
|
407
|
-
args: [serializeNamespace(namespace), key],
|
|
408
|
-
});
|
|
409
|
-
await this.deleteKnowledgeRecordEntry(client, namespace, key);
|
|
410
|
-
}
|
|
411
|
-
async listNamespaces() {
|
|
412
|
-
const rows = await this.selectAll(`SELECT DISTINCT namespace_json
|
|
62
|
+
updated_at = excluded.updated_at`,args:[d,JSON.stringify(e),t,_,r,r]});const u=h(e,t,i,r,r);u?await this.upsertKnowledgeRecordEntry(n,u):await this.deleteKnowledgeRecordEntry(n,e,t)}async delete(e,t){await this.ensureInitialized();const i=await this.getClient();await i.execute({sql:"DELETE FROM store_entries WHERE namespace = ? AND key = ?",args:[l(e),t]}),await this.deleteKnowledgeRecordEntry(i,e,t)}async listNamespaces(){return(await this.selectAll(`SELECT DISTINCT namespace_json
|
|
413
63
|
FROM store_entries
|
|
414
|
-
ORDER BY namespace ASC`);
|
|
415
|
-
return rows.map((row) => JSON.parse(row.namespace_json));
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
export function createInMemoryStore() {
|
|
419
|
-
return new InMemoryStore();
|
|
420
|
-
}
|
|
64
|
+
ORDER BY namespace ASC`)).map(t=>JSON.parse(t.namespace_json))}}function D(){return new m}export{j as FileBackedStore,U as SqliteBackedStore,D as createInMemoryStore};
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from "./validation.js";
|
|
1
|
+
export*from"./policy.js";export*from"./validation.js";
|
|
@@ -1,45 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { getBindingPrimaryTools } from "../../support/compiled-binding.js";
|
|
3
|
-
import { compiledToolHasInputSchema } from "../tool-schema.js";
|
|
4
|
-
export function projectBindingToolGatewayPolicy(binding) {
|
|
5
|
-
const tools = getBindingPrimaryTools(binding).map((tool) => {
|
|
6
|
-
const hasInputSchema = compiledToolHasInputSchema(tool);
|
|
7
|
-
const requiresApproval = toolRequiresRuntimeApproval(tool);
|
|
8
|
-
return {
|
|
9
|
-
toolId: tool.id,
|
|
10
|
-
name: tool.name,
|
|
11
|
-
retryable: tool.retryable === true,
|
|
12
|
-
hasInputSchema,
|
|
13
|
-
requiresApproval,
|
|
14
|
-
gatewayMode: requiresApproval ? "approval-gated" : hasInputSchema ? "schema-first" : "best-effort",
|
|
15
|
-
modelRole: "propose",
|
|
16
|
-
runtimeRole: requiresApproval
|
|
17
|
-
? "request-approval"
|
|
18
|
-
: hasInputSchema
|
|
19
|
-
? "validate-and-execute"
|
|
20
|
-
: "execute-with-runtime-checks",
|
|
21
|
-
};
|
|
22
|
-
});
|
|
23
|
-
const schemaBoundToolCount = tools.filter((tool) => tool.hasInputSchema).length;
|
|
24
|
-
const approvalRequiredToolCount = tools.filter((tool) => tool.requiresApproval).length;
|
|
25
|
-
return {
|
|
26
|
-
layer: "tool-gateway",
|
|
27
|
-
toolScope: {
|
|
28
|
-
source: "agent-binding",
|
|
29
|
-
exposedToolCount: tools.length,
|
|
30
|
-
schemaBoundToolCount,
|
|
31
|
-
approvalRequiredToolCount,
|
|
32
|
-
},
|
|
33
|
-
validation: {
|
|
34
|
-
strategy: "schema-first",
|
|
35
|
-
runtimeValidationRequired: tools.some((tool) => !tool.hasInputSchema || tool.requiresApproval),
|
|
36
|
-
strictProviderSchemaPreferred: tools.length > 0,
|
|
37
|
-
},
|
|
38
|
-
correction: {
|
|
39
|
-
invalidArguments: "structured-error-retry",
|
|
40
|
-
maxModelRetries: 2,
|
|
41
|
-
highRiskInvalidArguments: "approval-or-deny",
|
|
42
|
-
},
|
|
43
|
-
tools,
|
|
44
|
-
};
|
|
45
|
-
}
|
|
1
|
+
import{toolRequiresRuntimeApproval as l}from"../../adapter/tool/tool-hitl.js";import{getBindingPrimaryTools as s}from"../../support/compiled-binding.js";import{compiledToolHasInputSchema as p}from"../tool-schema.js";function d(a){const r=s(a).map(e=>{const t=p(e),o=l(e);return{toolId:e.id,name:e.name,retryable:e.retryable===!0,hasInputSchema:t,requiresApproval:o,gatewayMode:o?"approval-gated":t?"schema-first":"best-effort",modelRole:"propose",runtimeRole:o?"request-approval":t?"validate-and-execute":"execute-with-runtime-checks"}}),i=r.filter(e=>e.hasInputSchema).length,n=r.filter(e=>e.requiresApproval).length;return{layer:"tool-gateway",toolScope:{source:"agent-binding",exposedToolCount:r.length,schemaBoundToolCount:i,approvalRequiredToolCount:n},validation:{strategy:"schema-first",runtimeValidationRequired:r.some(e=>!e.hasInputSchema||e.requiresApproval),strictProviderSchemaPreferred:r.length>0},correction:{invalidArguments:"structured-error-retry",maxModelRetries:2,highRiskInvalidArguments:"approval-or-deny"},tools:r}}export{d as projectBindingToolGatewayPolicy};
|
|
@@ -1,176 +1 @@
|
|
|
1
|
-
function
|
|
2
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3
|
-
}
|
|
4
|
-
function readJsonSchemaType(schema) {
|
|
5
|
-
if (!isRecord(schema)) {
|
|
6
|
-
return [];
|
|
7
|
-
}
|
|
8
|
-
const type = schema.type;
|
|
9
|
-
if (typeof type === "string") {
|
|
10
|
-
return [type];
|
|
11
|
-
}
|
|
12
|
-
return Array.isArray(type) ? type.filter((entry) => typeof entry === "string") : [];
|
|
13
|
-
}
|
|
14
|
-
function typeMatches(value, allowedTypes) {
|
|
15
|
-
if (allowedTypes.length === 0) {
|
|
16
|
-
return true;
|
|
17
|
-
}
|
|
18
|
-
if (value === null) {
|
|
19
|
-
return allowedTypes.includes("null");
|
|
20
|
-
}
|
|
21
|
-
return allowedTypes.some((type) => {
|
|
22
|
-
if (type === "integer") {
|
|
23
|
-
return Number.isInteger(value);
|
|
24
|
-
}
|
|
25
|
-
if (type === "array") {
|
|
26
|
-
return Array.isArray(value);
|
|
27
|
-
}
|
|
28
|
-
if (type === "object") {
|
|
29
|
-
return isRecord(value);
|
|
30
|
-
}
|
|
31
|
-
return typeof value === type;
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
function toPath(path) {
|
|
35
|
-
if (path.length === 0) {
|
|
36
|
-
return "$";
|
|
37
|
-
}
|
|
38
|
-
let rendered = "$";
|
|
39
|
-
for (const part of path) {
|
|
40
|
-
rendered = typeof part === "number" ? `${rendered}[${part}]` : `${rendered}.${part}`;
|
|
41
|
-
}
|
|
42
|
-
return rendered;
|
|
43
|
-
}
|
|
44
|
-
function zodIssues(error) {
|
|
45
|
-
const issues = isRecord(error) && Array.isArray(error.issues) ? error.issues : [];
|
|
46
|
-
return issues
|
|
47
|
-
.map((issue) => {
|
|
48
|
-
if (!isRecord(issue)) {
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
const path = Array.isArray(issue.path) ? issue.path.filter((part) => typeof part === "string" || typeof part === "number") : [];
|
|
52
|
-
const message = typeof issue.message === "string" ? issue.message : "Invalid value";
|
|
53
|
-
return {
|
|
54
|
-
path: toPath(path),
|
|
55
|
-
message,
|
|
56
|
-
...(typeof issue.expected === "string" ? { expected: issue.expected } : {}),
|
|
57
|
-
...(typeof issue.received === "string" ? { received: issue.received } : {}),
|
|
58
|
-
};
|
|
59
|
-
})
|
|
60
|
-
.filter((issue) => issue !== null);
|
|
61
|
-
}
|
|
62
|
-
function validateJsonSchemaObject(schema, input) {
|
|
63
|
-
const issues = [];
|
|
64
|
-
const rootTypes = readJsonSchemaType(schema);
|
|
65
|
-
if (!typeMatches(input, rootTypes.length > 0 ? rootTypes : ["object"])) {
|
|
66
|
-
return [{
|
|
67
|
-
path: "$",
|
|
68
|
-
message: "Tool input must match the declared schema root type.",
|
|
69
|
-
expected: rootTypes.join("|") || "object",
|
|
70
|
-
received: Array.isArray(input) ? "array" : input === null ? "null" : typeof input,
|
|
71
|
-
}];
|
|
72
|
-
}
|
|
73
|
-
if (!isRecord(input)) {
|
|
74
|
-
return issues;
|
|
75
|
-
}
|
|
76
|
-
const properties = isRecord(schema.properties) ? schema.properties : {};
|
|
77
|
-
const required = Array.isArray(schema.required)
|
|
78
|
-
? schema.required.filter((entry) => typeof entry === "string")
|
|
79
|
-
: [];
|
|
80
|
-
for (const key of required) {
|
|
81
|
-
if (!(key in input)) {
|
|
82
|
-
issues.push({
|
|
83
|
-
path: `$.${key}`,
|
|
84
|
-
message: "Required tool argument is missing.",
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
for (const [key, value] of Object.entries(input)) {
|
|
89
|
-
const fieldSchema = properties[key];
|
|
90
|
-
if (!fieldSchema) {
|
|
91
|
-
if (schema.additionalProperties === false) {
|
|
92
|
-
issues.push({
|
|
93
|
-
path: `$.${key}`,
|
|
94
|
-
message: "Unexpected tool argument.",
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
const fieldTypes = readJsonSchemaType(fieldSchema);
|
|
100
|
-
if (!typeMatches(value, fieldTypes)) {
|
|
101
|
-
issues.push({
|
|
102
|
-
path: `$.${key}`,
|
|
103
|
-
message: "Tool argument has the wrong type.",
|
|
104
|
-
...(fieldTypes.length > 0 ? { expected: fieldTypes.join("|") } : {}),
|
|
105
|
-
received: Array.isArray(value) ? "array" : value === null ? "null" : typeof value,
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
if (isRecord(fieldSchema) && Array.isArray(fieldSchema.enum) && !fieldSchema.enum.includes(value)) {
|
|
109
|
-
issues.push({
|
|
110
|
-
path: `$.${key}`,
|
|
111
|
-
message: "Tool argument must be one of the declared enum values.",
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
return issues;
|
|
116
|
-
}
|
|
117
|
-
export function createInvalidToolArgumentsResult(input) {
|
|
118
|
-
return {
|
|
119
|
-
isError: true,
|
|
120
|
-
code: "INVALID_ARGUMENTS",
|
|
121
|
-
toolName: input.toolName,
|
|
122
|
-
message: `Tool ${input.toolName} received invalid arguments. Correct the arguments to match the declared schema before retrying.`,
|
|
123
|
-
retryable: !input.requiresApproval,
|
|
124
|
-
requiresApproval: input.requiresApproval,
|
|
125
|
-
validationErrors: input.issues.length > 0
|
|
126
|
-
? input.issues
|
|
127
|
-
: [{ path: "$", message: "Tool input failed schema validation." }],
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
export function validateToolGatewayInput(input) {
|
|
131
|
-
const schema = input.schema;
|
|
132
|
-
const requiresApproval = input.requiresApproval === true;
|
|
133
|
-
if (schema && typeof schema.safeParse === "function") {
|
|
134
|
-
const parsed = schema.safeParse(input.args);
|
|
135
|
-
if (parsed.success) {
|
|
136
|
-
return { ok: true, input: parsed.data };
|
|
137
|
-
}
|
|
138
|
-
return {
|
|
139
|
-
ok: false,
|
|
140
|
-
error: createInvalidToolArgumentsResult({
|
|
141
|
-
toolName: input.toolName,
|
|
142
|
-
requiresApproval,
|
|
143
|
-
issues: zodIssues(parsed.error),
|
|
144
|
-
}),
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
if (schema && typeof schema.parse === "function") {
|
|
148
|
-
try {
|
|
149
|
-
return { ok: true, input: schema.parse(input.args) };
|
|
150
|
-
}
|
|
151
|
-
catch (error) {
|
|
152
|
-
return {
|
|
153
|
-
ok: false,
|
|
154
|
-
error: createInvalidToolArgumentsResult({
|
|
155
|
-
toolName: input.toolName,
|
|
156
|
-
requiresApproval,
|
|
157
|
-
issues: zodIssues(error),
|
|
158
|
-
}),
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
if (isRecord(input.schema) && (input.schema.type === "object" || isRecord(input.schema.properties))) {
|
|
163
|
-
const issues = validateJsonSchemaObject(input.schema, input.args);
|
|
164
|
-
if (issues.length > 0) {
|
|
165
|
-
return {
|
|
166
|
-
ok: false,
|
|
167
|
-
error: createInvalidToolArgumentsResult({
|
|
168
|
-
toolName: input.toolName,
|
|
169
|
-
requiresApproval,
|
|
170
|
-
issues,
|
|
171
|
-
}),
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
return { ok: true, input: input.args };
|
|
176
|
-
}
|
|
1
|
+
function a(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function p(e){if(!a(e))return[];const t=e.type;return typeof t=="string"?[t]:Array.isArray(t)?t.filter(r=>typeof r=="string"):[]}function y(e,t){return t.length===0?!0:e===null?t.includes("null"):t.some(r=>r==="integer"?Number.isInteger(e):r==="array"?Array.isArray(e):r==="object"?a(e):typeof e===r)}function d(e){if(e.length===0)return"$";let t="$";for(const r of e)t=typeof r=="number"?`${t}[${r}]`:`${t}.${r}`;return t}function m(e){return(a(e)&&Array.isArray(e.issues)?e.issues:[]).map(r=>{if(!a(r))return null;const o=Array.isArray(r.path)?r.path.filter(c=>typeof c=="string"||typeof c=="number"):[],f=typeof r.message=="string"?r.message:"Invalid value";return{path:d(o),message:f,...typeof r.expected=="string"?{expected:r.expected}:{},...typeof r.received=="string"?{received:r.received}:{}}}).filter(r=>r!==null)}function g(e,t){const r=[],o=p(e);if(!y(t,o.length>0?o:["object"]))return[{path:"$",message:"Tool input must match the declared schema root type.",expected:o.join("|")||"object",received:Array.isArray(t)?"array":t===null?"null":typeof t}];if(!a(t))return r;const f=a(e.properties)?e.properties:{},c=Array.isArray(e.required)?e.required.filter(s=>typeof s=="string"):[];for(const s of c)s in t||r.push({path:`$.${s}`,message:"Required tool argument is missing."});for(const[s,n]of Object.entries(t)){const i=f[s];if(!i){e.additionalProperties===!1&&r.push({path:`$.${s}`,message:"Unexpected tool argument."});continue}const l=p(i);y(n,l)||r.push({path:`$.${s}`,message:"Tool argument has the wrong type.",...l.length>0?{expected:l.join("|")}:{},received:Array.isArray(n)?"array":n===null?"null":typeof n}),a(i)&&Array.isArray(i.enum)&&!i.enum.includes(n)&&r.push({path:`$.${s}`,message:"Tool argument must be one of the declared enum values."})}return r}function u(e){return{isError:!0,code:"INVALID_ARGUMENTS",toolName:e.toolName,message:`Tool ${e.toolName} received invalid arguments. Correct the arguments to match the declared schema before retrying.`,retryable:!e.requiresApproval,requiresApproval:e.requiresApproval,validationErrors:e.issues.length>0?e.issues:[{path:"$",message:"Tool input failed schema validation."}]}}function h(e){const t=e.schema,r=e.requiresApproval===!0;if(t&&typeof t.safeParse=="function"){const o=t.safeParse(e.args);return o.success?{ok:!0,input:o.data}:{ok:!1,error:u({toolName:e.toolName,requiresApproval:r,issues:m(o.error)})}}if(t&&typeof t.parse=="function")try{return{ok:!0,input:t.parse(e.args)}}catch(o){return{ok:!1,error:u({toolName:e.toolName,requiresApproval:r,issues:m(o)})}}if(a(e.schema)&&(e.schema.type==="object"||a(e.schema.properties))){const o=g(e.schema,e.args);if(o.length>0)return{ok:!1,error:u({toolName:e.toolName,requiresApproval:r,issues:o})}}return{ok:!0,input:e.args}}export{u as createInvalidToolArgumentsResult,h as validateToolGatewayInput};
|
|
@@ -1,3 +1 @@
|
|
|
1
|
-
|
|
2
|
-
return (typeof tool.inputSchemaRef === "string" && tool.inputSchemaRef.trim().length > 0) || tool.hasModuleSchema === true;
|
|
3
|
-
}
|
|
1
|
+
function t(e){return typeof e.inputSchemaRef=="string"&&e.inputSchemaRef.trim().length>0||e.hasModuleSchema===!0}export{t as compiledToolHasInputSchema};
|