@botbotgo/agent-harness 0.0.99 → 0.0.101
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 -6
- package/README.zh.md +2 -2
- package/dist/benchmark/upstream-runtime-ab-benchmark.d.ts +1 -1
- package/dist/benchmark/upstream-runtime-ab-benchmark.js +1 -2
- package/dist/contracts/core.d.ts +2 -2
- package/dist/contracts/runtime.d.ts +1 -5
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/resource/resource-impl.js +78 -76
- package/dist/runtime/adapter/deepagent-runnable-config.d.ts +30 -0
- package/dist/runtime/adapter/deepagent-runnable-config.js +22 -0
- package/dist/runtime/adapter/index.d.ts +0 -2
- package/dist/runtime/adapter/index.js +0 -2
- package/dist/runtime/adapter/invocation-result.d.ts +13 -0
- package/dist/runtime/adapter/invocation-result.js +40 -0
- package/dist/runtime/adapter/langchain-runnable-config.d.ts +25 -0
- package/dist/runtime/adapter/langchain-runnable-config.js +19 -0
- package/dist/runtime/adapter/local-tool-invocation.d.ts +23 -0
- package/dist/runtime/adapter/local-tool-invocation.js +64 -0
- package/dist/runtime/adapter/runtime-adapter-support.d.ts +18 -0
- package/dist/runtime/adapter/runtime-adapter-support.js +54 -0
- package/dist/runtime/adapter/stream-event-projection.d.ts +19 -0
- package/dist/runtime/adapter/stream-event-projection.js +79 -0
- package/dist/runtime/adapter/stream-text-consumption.d.ts +4 -0
- package/dist/runtime/adapter/stream-text-consumption.js +18 -0
- package/dist/runtime/adapter/tool/builtin-middleware-tools.d.ts +64 -0
- package/dist/runtime/adapter/tool/builtin-middleware-tools.js +144 -0
- package/dist/runtime/adapter/tool/tool-replay.d.ts +18 -0
- package/dist/runtime/adapter/tool/tool-replay.js +26 -0
- package/dist/runtime/agent-runtime-adapter.d.ts +2 -54
- package/dist/runtime/agent-runtime-adapter.js +122 -1568
- package/dist/runtime/harness/run/helpers.js +2 -8
- package/dist/runtime/harness/run/recovery.d.ts +42 -0
- package/dist/runtime/harness/run/recovery.js +139 -0
- package/dist/runtime/harness/run/routing.d.ts +1 -3
- package/dist/runtime/harness/run/routing.js +2 -25
- package/dist/runtime/harness/run/run-lifecycle.d.ts +0 -11
- package/dist/runtime/harness/run/run-lifecycle.js +7 -50
- package/dist/runtime/harness/runtime-defaults.d.ts +4 -0
- package/dist/runtime/harness/runtime-defaults.js +39 -0
- package/dist/runtime/harness/system/inventory.js +2 -1
- package/dist/runtime/harness/system/skill-requirements.d.ts +1 -0
- package/dist/runtime/harness.d.ts +5 -24
- package/dist/runtime/harness.js +356 -536
- package/dist/runtime/index.d.ts +1 -12
- package/dist/runtime/index.js +1 -12
- package/dist/runtime/support/compiled-binding.d.ts +0 -2
- package/dist/runtime/support/compiled-binding.js +3 -22
- package/dist/runtime/support/harness-support.d.ts +0 -11
- package/dist/runtime/support/harness-support.js +1 -44
- package/dist/runtime/support/index.d.ts +1 -1
- package/dist/runtime/support/index.js +1 -1
- package/dist/runtime/support/runtime-factories.js +2 -2
- package/dist/workspace/agent-binding-compiler.js +9 -93
- package/dist/workspace/index.d.ts +0 -5
- package/dist/workspace/index.js +0 -5
- package/dist/workspace/object-loader.js +44 -99
- package/dist/workspace/support/agent-capabilities.js +2 -2
- package/dist/workspace/support/workspace-ref-utils.d.ts +0 -2
- package/dist/workspace/support/workspace-ref-utils.js +0 -17
- package/dist/workspace/validate.js +1 -1
- package/package.json +1 -1
- package/dist/config/workflows/langgraph-workflows.yaml +0 -570
- package/dist/config/workflows/runtime-profiles.yaml +0 -94
- package/dist/runtime/adapter/langgraph/presets.d.ts +0 -25
- package/dist/runtime/adapter/langgraph/presets.js +0 -165
- package/dist/runtime/adapter/langgraph/profiles.d.ts +0 -6
- package/dist/runtime/adapter/langgraph/profiles.js +0 -206
- package/dist/runtime/checkpoint-maintenance.d.ts +0 -1
- package/dist/runtime/checkpoint-maintenance.js +0 -1
- package/dist/runtime/file-checkpoint-saver.d.ts +0 -1
- package/dist/runtime/file-checkpoint-saver.js +0 -1
- package/dist/runtime/sqlite-maintained-checkpoint-saver.d.ts +0 -1
- package/dist/runtime/sqlite-maintained-checkpoint-saver.js +0 -1
package/README.md
CHANGED
|
@@ -79,7 +79,7 @@ Boundary documents live in:
|
|
|
79
79
|
- `docs/model-layering.md`
|
|
80
80
|
- `docs/coding-agent-guide.md`
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
`deepagents-acp` is the required external protocol direction when external tools need a standard runtime boundary. The harness should conform to `deepagents-acp` semantics at that boundary while keeping runtime lifecycle, persistence, recovery, and governance harness-owned.
|
|
83
83
|
|
|
84
84
|
Recommended orchestration shape for long-running flows:
|
|
85
85
|
|
|
@@ -262,7 +262,7 @@ const result = await run(runtime, {
|
|
|
262
262
|
});
|
|
263
263
|
```
|
|
264
264
|
|
|
265
|
-
`agentId: "auto"` evaluates ordered routing rules in `config/runtime/workspace.yaml`, then `routing.defaultAgentId`, and
|
|
265
|
+
`agentId: "auto"` evaluates ordered routing rules in `config/runtime/workspace.yaml`, then `routing.defaultAgentId`, and otherwise falls back to the default runtime entry host.
|
|
266
266
|
|
|
267
267
|
### Stream Output And Events
|
|
268
268
|
|
|
@@ -416,8 +416,6 @@ Important fields:
|
|
|
416
416
|
- `concurrency.maxConcurrentRuns`
|
|
417
417
|
- `routing.defaultAgentId`
|
|
418
418
|
- `routing.rules`
|
|
419
|
-
- `routing.systemPrompt`
|
|
420
|
-
- `routing.modelRouting`
|
|
421
419
|
- `maintenance.checkpoints`
|
|
422
420
|
- `maintenance.records`
|
|
423
421
|
- `recovery.enabled`
|
|
@@ -444,7 +442,6 @@ spec:
|
|
|
444
442
|
maxConcurrentRuns: 3
|
|
445
443
|
routing:
|
|
446
444
|
defaultAgentId: orchestra
|
|
447
|
-
modelRouting: false
|
|
448
445
|
maintenance:
|
|
449
446
|
checkpoints:
|
|
450
447
|
enabled: true
|
|
@@ -639,7 +636,7 @@ For backend-specific options, prefer the upstream concept directly inside `spec.
|
|
|
639
636
|
- `agent-harness` is not a third agent framework
|
|
640
637
|
- public runtime contract stays generic and small
|
|
641
638
|
- application-level orchestration and lifecycle management stays in the harness
|
|
642
|
-
-
|
|
639
|
+
- the external protocol boundary should strictly conform to `deepagents-acp` instead of a parallel harness-only protocol
|
|
643
640
|
- upstream LangChain v1 and DeepAgents concepts should be expressed as directly as possible in YAML
|
|
644
641
|
- when a feature can be expressed in YAML, prefer YAML over expanding the public API
|
|
645
642
|
- recovery, approvals, threads, runs, and events are runtime concepts, not backend escape hatches
|
package/README.zh.md
CHANGED
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
- `docs/model-layering.md`
|
|
80
80
|
- `docs/coding-agent-guide.md`
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
当外部工具需要标准运行时边界时,`deepagents-acp` 是必须遵循的外部协议方向。`agent-harness` 应在该边界上严格契合 `deepagents-acp` 语义,同时继续把运行时生命周期、持久化、恢复与治理保留在 harness 内部。
|
|
83
83
|
|
|
84
84
|
长链路编排的推荐形态:
|
|
85
85
|
|
|
@@ -633,7 +633,7 @@ spec:
|
|
|
633
633
|
- `agent-harness` 不是第三个 agent 框架
|
|
634
634
|
- 公共运行时契约保持通用且精简
|
|
635
635
|
- 应用级编排与生命周期管理留在 harness 中
|
|
636
|
-
-
|
|
636
|
+
- 外部协议边界应严格契合 `deepagents-acp`,而不是再做一套并行的 harness 私有协议
|
|
637
637
|
- 应尽量在 YAML 中直接表达 LangChain v1 与 DeepAgents 的概念
|
|
638
638
|
- 能用 YAML 表达的能力,优先 YAML 而非扩张公共 API
|
|
639
639
|
- 恢复、审批、线程、运行与事件是运行时概念,不是后端逃生舱
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const DEFAULT_UPSTREAM_BENCHMARK_PATHS: readonly ["harness", "raw-langchain-v1", "raw-
|
|
1
|
+
export declare const DEFAULT_UPSTREAM_BENCHMARK_PATHS: readonly ["harness", "raw-langchain-v1", "raw-deepagent"];
|
|
2
2
|
export declare const DEFAULT_UPSTREAM_BENCHMARK_WORKLOAD: "tool";
|
|
3
3
|
export type UpstreamBenchmarkPath = (typeof DEFAULT_UPSTREAM_BENCHMARK_PATHS)[number];
|
|
4
4
|
export type UpstreamBenchmarkWorkload = "tool" | "no-tool";
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export const DEFAULT_UPSTREAM_BENCHMARK_PATHS = Object.freeze([
|
|
2
2
|
"harness",
|
|
3
3
|
"raw-langchain-v1",
|
|
4
|
-
"raw-langgraph",
|
|
5
4
|
"raw-deepagent",
|
|
6
5
|
]);
|
|
7
6
|
export const DEFAULT_UPSTREAM_BENCHMARK_WORKLOAD = "tool";
|
|
@@ -48,7 +47,7 @@ export function resolveUpstreamBenchmarkPaths(rawValue) {
|
|
|
48
47
|
const parsed = rawValue
|
|
49
48
|
.split(",")
|
|
50
49
|
.map((value) => value.trim().toLowerCase())
|
|
51
|
-
.filter((value) => value === "harness" || value === "raw-langchain-v1" || value === "raw-
|
|
50
|
+
.filter((value) => value === "harness" || value === "raw-langchain-v1" || value === "raw-deepagent");
|
|
52
51
|
return parsed.length > 0 ? parsed : [...DEFAULT_UPSTREAM_BENCHMARK_PATHS];
|
|
53
52
|
}
|
|
54
53
|
export function resolveUpstreamBenchmarkWorkload(rawValue) {
|
package/dist/contracts/core.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export type ExecutionMode = "deepagent" | "langchain-v1"
|
|
1
|
+
export type ExecutionMode = "deepagent" | "langchain-v1";
|
|
2
2
|
export declare const AUTO_AGENT_ID = "auto";
|
|
3
|
-
export type RuntimeModelSlot = "
|
|
3
|
+
export type RuntimeModelSlot = "planning" | "execution" | "review" | "final";
|
|
4
4
|
export type RuntimeModelRefMap = Partial<Record<RuntimeModelSlot, string>>;
|
|
5
5
|
export type RuntimeCapabilities = {
|
|
6
6
|
delegation?: boolean;
|
|
@@ -9,7 +9,7 @@ export type ThreadSummary = {
|
|
|
9
9
|
status: RunState;
|
|
10
10
|
};
|
|
11
11
|
export type SessionRecord = ThreadSummary;
|
|
12
|
-
export type KnownHarnessEventType = "run.created" | "run.queued" | "run.dequeued" | "run.state.changed" | "run.
|
|
12
|
+
export type KnownHarnessEventType = "run.created" | "run.queued" | "run.dequeued" | "run.state.changed" | "run.resumed" | "approval.requested" | "approval.resolved" | "artifact.created" | "output.delta" | "reasoning.delta" | "runtime.health.changed" | "runtime.synthetic_fallback";
|
|
13
13
|
export type HarnessEventType = KnownHarnessEventType | (string & {});
|
|
14
14
|
export type HarnessEvent = {
|
|
15
15
|
eventId: string;
|
|
@@ -190,8 +190,6 @@ export type RunStartOptions = {
|
|
|
190
190
|
priority?: number;
|
|
191
191
|
invocation?: InvocationEnvelope;
|
|
192
192
|
listeners?: RunListeners;
|
|
193
|
-
runtimeListeners?: RuntimeListeners;
|
|
194
|
-
frontendListeners?: FrontendStreamListeners;
|
|
195
193
|
};
|
|
196
194
|
export type RunDecisionOptions = {
|
|
197
195
|
threadId: string;
|
|
@@ -200,8 +198,6 @@ export type RunDecisionOptions = {
|
|
|
200
198
|
decision: "approve" | "edit" | "reject";
|
|
201
199
|
editedInput?: Record<string, unknown>;
|
|
202
200
|
listeners?: RunListeners;
|
|
203
|
-
runtimeListeners?: RuntimeListeners;
|
|
204
|
-
frontendListeners?: FrontendStreamListeners;
|
|
205
201
|
};
|
|
206
202
|
export type RunOptions = RunStartOptions | RunDecisionOptions;
|
|
207
203
|
export type HarnessStreamItem = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.100";
|
package/dist/package-version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.100";
|
|
@@ -81,13 +81,14 @@ function listProviderTools(provider) {
|
|
|
81
81
|
toolPath: tool.toolPath ?? tool.builtinPath ?? "",
|
|
82
82
|
}));
|
|
83
83
|
}
|
|
84
|
+
function preferProviderValue(provider, primary, fallback) {
|
|
85
|
+
return provider ? (primary(provider) ?? fallback(provider)) : undefined;
|
|
86
|
+
}
|
|
84
87
|
function createProviderToolResolver(provider, workspace, options) {
|
|
85
|
-
return (provider
|
|
86
|
-
provider?.createBuiltinToolResolver?.(workspace, options));
|
|
88
|
+
return preferProviderValue(provider, (candidate) => candidate.createResourceToolResolver?.(workspace, options), (candidate) => candidate.createBuiltinToolResolver?.(workspace, options));
|
|
87
89
|
}
|
|
88
90
|
function createProviderBackendResolver(provider, workspace) {
|
|
89
|
-
return (provider
|
|
90
|
-
provider?.createBuiltinBackendResolver?.(workspace));
|
|
91
|
+
return preferProviderValue(provider, (candidate) => candidate.createResourceBackendResolver?.(workspace), (candidate) => candidate.createBuiltinBackendResolver?.(workspace));
|
|
91
92
|
}
|
|
92
93
|
class CompatibleCompositeBackend {
|
|
93
94
|
id;
|
|
@@ -133,69 +134,66 @@ class CompatibleCompositeBackend {
|
|
|
133
134
|
return this.composite.downloadFiles(paths);
|
|
134
135
|
}
|
|
135
136
|
}
|
|
137
|
+
const INLINE_BACKEND_ERROR = 'Unsupported DeepAgent backend kind "%s". Supported inline kinds: LocalShellBackend, VfsSandbox, StateBackend, StoreBackend, CompositeBackend.';
|
|
138
|
+
function unsupportedInlineBackend(kind) {
|
|
139
|
+
throw new Error(INLINE_BACKEND_ERROR.replace("%s", kind));
|
|
140
|
+
}
|
|
141
|
+
function resolveInlineBackendRootDir(workspaceRoot, configuredRootDir) {
|
|
142
|
+
if (typeof configuredRootDir === "string" && configuredRootDir.trim().length > 0) {
|
|
143
|
+
return path.isAbsolute(configuredRootDir)
|
|
144
|
+
? configuredRootDir
|
|
145
|
+
: path.resolve(workspaceRoot, configuredRootDir);
|
|
146
|
+
}
|
|
147
|
+
return workspaceRoot;
|
|
148
|
+
}
|
|
149
|
+
function createLocalShellStyleBackend(workspaceRoot, config, options) {
|
|
150
|
+
const rootDir = resolveInlineBackendRootDir(workspaceRoot, config?.rootDir);
|
|
151
|
+
mkdirSync(rootDir, { recursive: true });
|
|
152
|
+
const inheritedEnv = config?.inheritEnv === false ? {} : process.env;
|
|
153
|
+
return new LocalShellBackend({
|
|
154
|
+
rootDir,
|
|
155
|
+
virtualMode: options.virtualMode,
|
|
156
|
+
timeout: typeof config?.timeout === "number" ? config.timeout : undefined,
|
|
157
|
+
maxOutputBytes: typeof config?.maxOutputBytes === "number" ? config.maxOutputBytes : undefined,
|
|
158
|
+
env: createRuntimeEnv(readStringRecord(config?.env), inheritedEnv),
|
|
159
|
+
inheritEnv: config?.inheritEnv !== false,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
function createInlineBackendInstance(workspaceRoot, kind, config, runtimeLike) {
|
|
163
|
+
switch (kind) {
|
|
164
|
+
case "LocalShellBackend":
|
|
165
|
+
return createLocalShellStyleBackend(workspaceRoot, config, {
|
|
166
|
+
virtualMode: config?.virtualMode === true,
|
|
167
|
+
});
|
|
168
|
+
case "VfsSandbox":
|
|
169
|
+
return createLocalShellStyleBackend(workspaceRoot, config, {
|
|
170
|
+
virtualMode: config?.virtualMode === false ? false : true,
|
|
171
|
+
});
|
|
172
|
+
case "StateBackend":
|
|
173
|
+
return new StateBackend(runtimeLike);
|
|
174
|
+
case "StoreBackend":
|
|
175
|
+
return new StoreBackend(runtimeLike);
|
|
176
|
+
default:
|
|
177
|
+
return unsupportedInlineBackend(kind);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
136
180
|
function createInlineBackendResolver(workspace) {
|
|
137
181
|
return (binding) => {
|
|
138
182
|
const backendConfig = binding.deepAgentParams?.backend;
|
|
139
183
|
if (!backendConfig || typeof backendConfig !== "object") {
|
|
140
184
|
return undefined;
|
|
141
185
|
}
|
|
142
|
-
const resolveBackendRootDir = (configuredRootDir) => {
|
|
143
|
-
if (typeof configuredRootDir === "string" && configuredRootDir.trim().length > 0) {
|
|
144
|
-
return path.isAbsolute(configuredRootDir)
|
|
145
|
-
? configuredRootDir
|
|
146
|
-
: path.resolve(workspace.workspaceRoot, configuredRootDir);
|
|
147
|
-
}
|
|
148
|
-
return workspace.workspaceRoot;
|
|
149
|
-
};
|
|
150
|
-
const createBackend = (kind, config, runtimeLike) => {
|
|
151
|
-
const configuredEnv = typeof config?.env === "object" && config.env
|
|
152
|
-
? Object.fromEntries(Object.entries(config.env).filter((entry) => typeof entry[1] === "string"))
|
|
153
|
-
: undefined;
|
|
154
|
-
const inheritedEnv = config?.inheritEnv === false ? {} : process.env;
|
|
155
|
-
switch (kind) {
|
|
156
|
-
case "LocalShellBackend": {
|
|
157
|
-
const rootDir = resolveBackendRootDir(config?.rootDir);
|
|
158
|
-
mkdirSync(rootDir, { recursive: true });
|
|
159
|
-
return new LocalShellBackend({
|
|
160
|
-
rootDir,
|
|
161
|
-
virtualMode: config?.virtualMode === true,
|
|
162
|
-
timeout: typeof config?.timeout === "number" ? config.timeout : undefined,
|
|
163
|
-
maxOutputBytes: typeof config?.maxOutputBytes === "number" ? config.maxOutputBytes : undefined,
|
|
164
|
-
env: createRuntimeEnv(configuredEnv, inheritedEnv),
|
|
165
|
-
inheritEnv: config?.inheritEnv !== false,
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
case "VfsSandbox": {
|
|
169
|
-
const rootDir = resolveBackendRootDir(config?.rootDir);
|
|
170
|
-
mkdirSync(rootDir, { recursive: true });
|
|
171
|
-
return new LocalShellBackend({
|
|
172
|
-
rootDir,
|
|
173
|
-
virtualMode: config?.virtualMode === false ? false : true,
|
|
174
|
-
timeout: typeof config?.timeout === "number" ? config.timeout : undefined,
|
|
175
|
-
maxOutputBytes: typeof config?.maxOutputBytes === "number" ? config.maxOutputBytes : undefined,
|
|
176
|
-
env: createRuntimeEnv(configuredEnv, inheritedEnv),
|
|
177
|
-
inheritEnv: config?.inheritEnv !== false,
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
case "StateBackend":
|
|
181
|
-
return new StateBackend(runtimeLike);
|
|
182
|
-
case "StoreBackend":
|
|
183
|
-
return new StoreBackend(runtimeLike);
|
|
184
|
-
default:
|
|
185
|
-
throw new Error(`Unsupported DeepAgent backend kind "${kind}". Supported inline kinds: LocalShellBackend, VfsSandbox, StateBackend, StoreBackend, CompositeBackend.`);
|
|
186
|
-
}
|
|
187
|
-
};
|
|
188
186
|
return (runtimeLike) => {
|
|
189
187
|
const kind = typeof backendConfig.kind === "string" ? backendConfig.kind : "CompositeBackend";
|
|
190
188
|
switch (kind) {
|
|
191
189
|
case "LocalShellBackend":
|
|
192
|
-
return
|
|
190
|
+
return createInlineBackendInstance(workspace.workspaceRoot, "LocalShellBackend", backendConfig, runtimeLike);
|
|
193
191
|
case "VfsSandbox":
|
|
194
|
-
return
|
|
192
|
+
return createInlineBackendInstance(workspace.workspaceRoot, "VfsSandbox", backendConfig, runtimeLike);
|
|
195
193
|
case "StateBackend":
|
|
196
|
-
return
|
|
194
|
+
return createInlineBackendInstance(workspace.workspaceRoot, "StateBackend", backendConfig, runtimeLike);
|
|
197
195
|
case "StoreBackend":
|
|
198
|
-
return
|
|
196
|
+
return createInlineBackendInstance(workspace.workspaceRoot, "StoreBackend", backendConfig, runtimeLike);
|
|
199
197
|
case "CompositeBackend": {
|
|
200
198
|
const stateConfig = typeof backendConfig.state === "object" && backendConfig.state
|
|
201
199
|
? backendConfig.state
|
|
@@ -206,12 +204,12 @@ function createInlineBackendResolver(workspace) {
|
|
|
206
204
|
: { "/memories/": { kind: "StoreBackend" } };
|
|
207
205
|
const mappedRoutes = Object.fromEntries(Object.entries(routes).map(([route, routeConfig]) => {
|
|
208
206
|
const routeKind = typeof routeConfig?.kind === "string" ? routeConfig.kind : "StoreBackend";
|
|
209
|
-
return [route,
|
|
207
|
+
return [route, createInlineBackendInstance(workspace.workspaceRoot, routeKind, routeConfig, runtimeLike)];
|
|
210
208
|
}));
|
|
211
|
-
return new CompatibleCompositeBackend(
|
|
209
|
+
return new CompatibleCompositeBackend(createInlineBackendInstance(workspace.workspaceRoot, defaultBackendKind, stateConfig, runtimeLike), mappedRoutes);
|
|
212
210
|
}
|
|
213
211
|
default:
|
|
214
|
-
|
|
212
|
+
return unsupportedInlineBackend(kind);
|
|
215
213
|
}
|
|
216
214
|
};
|
|
217
215
|
};
|
|
@@ -240,6 +238,23 @@ async function findPackageRoot(startPath) {
|
|
|
240
238
|
}
|
|
241
239
|
const functionToolModuleCache = new Map();
|
|
242
240
|
const mcpClientCache = new Map();
|
|
241
|
+
function readStringRecord(value) {
|
|
242
|
+
if (typeof value !== "object" || !value) {
|
|
243
|
+
return undefined;
|
|
244
|
+
}
|
|
245
|
+
const entries = Object.entries(value).filter((entry) => typeof entry[1] === "string");
|
|
246
|
+
return entries.length > 0 ? Object.fromEntries(entries) : undefined;
|
|
247
|
+
}
|
|
248
|
+
function listWorkspaceResourceProviders(workspace) {
|
|
249
|
+
return (workspace.resourceSources ?? [])
|
|
250
|
+
.map((source) => remoteResourceCache.get(source))
|
|
251
|
+
.filter((provider) => Boolean(provider));
|
|
252
|
+
}
|
|
253
|
+
function createWorkspaceProviderResolvers(workspace, factory) {
|
|
254
|
+
return listWorkspaceResourceProviders(workspace)
|
|
255
|
+
.map((provider) => factory(provider))
|
|
256
|
+
.filter((resolver) => Boolean(resolver));
|
|
257
|
+
}
|
|
243
258
|
async function loadFunctionToolModule(tool) {
|
|
244
259
|
const cacheKey = `${tool.sourcePath}:${tool.implementationName ?? tool.id}`;
|
|
245
260
|
const cached = functionToolModuleCache.get(cacheKey);
|
|
@@ -294,20 +309,15 @@ function readMcpServerConfig(workspace, tool) {
|
|
|
294
309
|
if (!mcpServer) {
|
|
295
310
|
return null;
|
|
296
311
|
}
|
|
297
|
-
const envRecord = typeof mcpServer.env === "object" && mcpServer.env
|
|
298
|
-
? Object.fromEntries(Object.entries(mcpServer.env).filter((entry) => typeof entry[1] === "string"))
|
|
299
|
-
: undefined;
|
|
300
312
|
return {
|
|
301
313
|
transport: normalizeMcpTransport(mcpServer.transport) ?? ((typeof mcpServer.url === "string" && mcpServer.url.trim()) ? "http" : "stdio"),
|
|
302
314
|
command: typeof mcpServer.command === "string" ? mcpServer.command.trim() : undefined,
|
|
303
315
|
args: Array.isArray(mcpServer.args) ? mcpServer.args.filter((item) => typeof item === "string") : undefined,
|
|
304
|
-
env:
|
|
316
|
+
env: readStringRecord(mcpServer.env),
|
|
305
317
|
cwd: typeof mcpServer.cwd === "string" ? mcpServer.cwd : undefined,
|
|
306
318
|
url: typeof mcpServer.url === "string" ? mcpServer.url.trim() : undefined,
|
|
307
319
|
token: typeof mcpServer.token === "string" ? mcpServer.token : undefined,
|
|
308
|
-
headers:
|
|
309
|
-
? Object.fromEntries(Object.entries(mcpServer.headers).filter((entry) => typeof entry[1] === "string"))
|
|
310
|
-
: undefined,
|
|
320
|
+
headers: readStringRecord(mcpServer.headers),
|
|
311
321
|
};
|
|
312
322
|
}
|
|
313
323
|
function createMcpCacheKey(config) {
|
|
@@ -514,11 +524,11 @@ export async function ensureResourceSources(sources = [], workspaceRoot = proces
|
|
|
514
524
|
}
|
|
515
525
|
export function defaultResourceSkillsRoot() {
|
|
516
526
|
const provider = requireLocalResource("default resource skill resolution");
|
|
517
|
-
return provider.defaultResourceSkillsRoot?.()
|
|
527
|
+
return preferProviderValue(provider, (candidate) => candidate.defaultResourceSkillsRoot?.(), (candidate) => candidate.builtinSkillsRoot?.()) ?? "";
|
|
518
528
|
}
|
|
519
529
|
export function defaultResourceConfigRoot() {
|
|
520
530
|
const provider = requireLocalResource("default resource config resolution");
|
|
521
|
-
return provider.defaultResourceConfigRoot?.()
|
|
531
|
+
return (preferProviderValue(provider, (candidate) => candidate.defaultResourceConfigRoot?.(), (candidate) => candidate.builtinConfigRoot?.() ?? candidate.builtinDefaultsRoot?.()) ?? "");
|
|
522
532
|
}
|
|
523
533
|
export async function listResourceTools(sources = [], workspaceRoot = process.cwd()) {
|
|
524
534
|
await ensureResourceSources(sources, workspaceRoot);
|
|
@@ -539,11 +549,7 @@ export async function listResourceToolsForSource(source, workspaceRoot = process
|
|
|
539
549
|
}
|
|
540
550
|
export function createResourceBackendResolver(workspace) {
|
|
541
551
|
const localResolver = createProviderBackendResolver(localResource, workspace);
|
|
542
|
-
const remoteResolvers = (workspace
|
|
543
|
-
.map((source) => remoteResourceCache.get(source))
|
|
544
|
-
.filter((provider) => Boolean(provider))
|
|
545
|
-
.map((provider) => createProviderBackendResolver(provider, workspace))
|
|
546
|
-
.filter((resolver) => Boolean(resolver));
|
|
552
|
+
const remoteResolvers = createWorkspaceProviderResolvers(workspace, (provider) => createProviderBackendResolver(provider, workspace));
|
|
547
553
|
const inlineResolver = createInlineBackendResolver(workspace);
|
|
548
554
|
return (binding) => {
|
|
549
555
|
const providerResolved = localResolver?.(binding) ??
|
|
@@ -555,11 +561,7 @@ export function createResourceToolResolver(workspace, options = {}) {
|
|
|
555
561
|
const functionResolver = createFunctionToolResolver(workspace);
|
|
556
562
|
const mcpResolver = createMcpToolResolver(workspace);
|
|
557
563
|
const localResolver = createProviderToolResolver(localResource, workspace, options);
|
|
558
|
-
const remoteResolvers = (workspace
|
|
559
|
-
.map((source) => remoteResourceCache.get(source))
|
|
560
|
-
.filter((provider) => Boolean(provider))
|
|
561
|
-
.map((provider) => createProviderToolResolver(provider, workspace, options))
|
|
562
|
-
.filter((resolver) => Boolean(resolver));
|
|
564
|
+
const remoteResolvers = createWorkspaceProviderResolvers(workspace, (provider) => createProviderToolResolver(provider, workspace, options));
|
|
563
565
|
return (toolIds, binding) => {
|
|
564
566
|
const resolved = [
|
|
565
567
|
...functionResolver(toolIds, binding),
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { DeepAgentParams } from "../../contracts/types.js";
|
|
2
|
+
export declare function buildDeepAgentRunnableConfig(params: {
|
|
3
|
+
compatibleParams: DeepAgentParams;
|
|
4
|
+
resolvedModel: unknown;
|
|
5
|
+
resolvedTools: unknown[];
|
|
6
|
+
resolvedMiddleware: unknown[];
|
|
7
|
+
resolvedSubagents: unknown[];
|
|
8
|
+
resolvedCheckpointer: unknown;
|
|
9
|
+
resolvedStore: unknown;
|
|
10
|
+
resolvedBackend: unknown;
|
|
11
|
+
resolvedInterruptOn: unknown;
|
|
12
|
+
resolvedSkills: string[];
|
|
13
|
+
}): {
|
|
14
|
+
model: never;
|
|
15
|
+
tools: never;
|
|
16
|
+
systemPrompt: string | undefined;
|
|
17
|
+
responseFormat: never;
|
|
18
|
+
contextSchema: never;
|
|
19
|
+
middleware: never;
|
|
20
|
+
subagents: never;
|
|
21
|
+
checkpointer: never;
|
|
22
|
+
store: never;
|
|
23
|
+
backend: never;
|
|
24
|
+
interruptOn: never;
|
|
25
|
+
name: string;
|
|
26
|
+
memory: string[];
|
|
27
|
+
skills: string[];
|
|
28
|
+
generalPurposeAgent: boolean | undefined;
|
|
29
|
+
taskDescription: string | undefined;
|
|
30
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function buildDeepAgentRunnableConfig(params) {
|
|
2
|
+
const { compatibleParams, resolvedModel, resolvedTools, resolvedMiddleware, resolvedSubagents, resolvedCheckpointer, resolvedStore, resolvedBackend, resolvedInterruptOn, resolvedSkills, } = params;
|
|
3
|
+
return {
|
|
4
|
+
...(compatibleParams.passthrough ?? {}),
|
|
5
|
+
model: resolvedModel,
|
|
6
|
+
tools: resolvedTools,
|
|
7
|
+
systemPrompt: compatibleParams.systemPrompt,
|
|
8
|
+
responseFormat: compatibleParams.responseFormat,
|
|
9
|
+
contextSchema: compatibleParams.contextSchema,
|
|
10
|
+
middleware: resolvedMiddleware,
|
|
11
|
+
subagents: resolvedSubagents,
|
|
12
|
+
checkpointer: resolvedCheckpointer,
|
|
13
|
+
store: resolvedStore,
|
|
14
|
+
backend: resolvedBackend,
|
|
15
|
+
interruptOn: resolvedInterruptOn,
|
|
16
|
+
name: compatibleParams.name,
|
|
17
|
+
memory: compatibleParams.memory,
|
|
18
|
+
skills: resolvedSkills,
|
|
19
|
+
generalPurposeAgent: compatibleParams.generalPurposeAgent,
|
|
20
|
+
taskDescription: compatibleParams.taskDescription,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -2,8 +2,6 @@ export * from "./tool/declared-middleware.js";
|
|
|
2
2
|
export * from "./compat/deepagent-compat.js";
|
|
3
3
|
export * from "./tool/interrupt-policy.js";
|
|
4
4
|
export * from "./model/invocation-request.js";
|
|
5
|
-
export * from "./langgraph/presets.js";
|
|
6
|
-
export * from "./langgraph/profiles.js";
|
|
7
5
|
export * from "./model/message-assembly.js";
|
|
8
6
|
export * from "./model/model-providers.js";
|
|
9
7
|
export * from "./compat/openai-compatible.js";
|
|
@@ -2,8 +2,6 @@ export * from "./tool/declared-middleware.js";
|
|
|
2
2
|
export * from "./compat/deepagent-compat.js";
|
|
3
3
|
export * from "./tool/interrupt-policy.js";
|
|
4
4
|
export * from "./model/invocation-request.js";
|
|
5
|
-
export * from "./langgraph/presets.js";
|
|
6
|
-
export * from "./langgraph/profiles.js";
|
|
7
5
|
export * from "./model/message-assembly.js";
|
|
8
6
|
export * from "./model/model-providers.js";
|
|
9
7
|
export * from "./compat/openai-compatible.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { RunResult } from "../../contracts/types.js";
|
|
2
|
+
export type ExecutedToolResult = {
|
|
3
|
+
toolName: string;
|
|
4
|
+
output: unknown;
|
|
5
|
+
isError?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare function finalizeInvocationResult(params: {
|
|
8
|
+
bindingAgentId: string;
|
|
9
|
+
threadId: string;
|
|
10
|
+
runId: string;
|
|
11
|
+
result: Record<string, unknown>;
|
|
12
|
+
executedToolResults: ExecutedToolResult[];
|
|
13
|
+
}): RunResult;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { extractContentBlocks, extractEmptyAssistantMessageFailure, extractOutputContent, extractToolFallbackContext, extractVisibleOutput, isLikelyToolArgsObject, sanitizeVisibleText, tryParseJson, } from "../parsing/output-parsing.js";
|
|
2
|
+
import { buildStateSnapshot } from "./model/message-assembly.js";
|
|
3
|
+
import { asRecord } from "./tool/resolved-tool.js";
|
|
4
|
+
export function finalizeInvocationResult(params) {
|
|
5
|
+
const { bindingAgentId, threadId, runId, result, executedToolResults } = params;
|
|
6
|
+
const interruptContent = Array.isArray(result.__interrupt__) && result.__interrupt__.length > 0 ? JSON.stringify(result.__interrupt__) : undefined;
|
|
7
|
+
const extractedOutput = extractVisibleOutput(result);
|
|
8
|
+
const visibleOutput = extractedOutput && !isLikelyToolArgsObject(tryParseJson(extractedOutput)) ? extractedOutput : "";
|
|
9
|
+
const emptyAssistantMessageFailure = extractEmptyAssistantMessageFailure(result);
|
|
10
|
+
const toolFallback = extractToolFallbackContext(result);
|
|
11
|
+
if (!visibleOutput && !toolFallback && emptyAssistantMessageFailure) {
|
|
12
|
+
throw new Error(emptyAssistantMessageFailure);
|
|
13
|
+
}
|
|
14
|
+
const output = visibleOutput || toolFallback || JSON.stringify(result, null, 2);
|
|
15
|
+
const finalMessageText = sanitizeVisibleText(output);
|
|
16
|
+
const outputContent = extractOutputContent(result);
|
|
17
|
+
const contentBlocks = extractContentBlocks(result);
|
|
18
|
+
const structuredResponse = result.structuredResponse;
|
|
19
|
+
return {
|
|
20
|
+
threadId,
|
|
21
|
+
runId,
|
|
22
|
+
agentId: bindingAgentId,
|
|
23
|
+
state: Array.isArray(result.__interrupt__) && result.__interrupt__.length > 0 ? "waiting_for_approval" : "completed",
|
|
24
|
+
interruptContent,
|
|
25
|
+
output: finalMessageText,
|
|
26
|
+
finalMessageText,
|
|
27
|
+
...(outputContent !== undefined ? { outputContent } : {}),
|
|
28
|
+
...(contentBlocks.length > 0 ? { contentBlocks } : {}),
|
|
29
|
+
...(structuredResponse !== undefined ? { structuredResponse } : {}),
|
|
30
|
+
metadata: {
|
|
31
|
+
...(executedToolResults.length > 0 ? { executedToolResults } : {}),
|
|
32
|
+
...(structuredResponse !== undefined ? { structuredResponse } : {}),
|
|
33
|
+
...(outputContent !== undefined ? { outputContent } : {}),
|
|
34
|
+
...(contentBlocks.length > 0 ? { contentBlocks } : {}),
|
|
35
|
+
...(asRecord(result.files) ? { files: asRecord(result.files) } : {}),
|
|
36
|
+
...(buildStateSnapshot(result) ? { stateSnapshot: buildStateSnapshot(result) } : {}),
|
|
37
|
+
upstreamResult: result,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { LangChainAgentParams } from "../../contracts/types.js";
|
|
2
|
+
export declare function buildLangChainRunnableConfig(params: {
|
|
3
|
+
langchainParams: LangChainAgentParams;
|
|
4
|
+
resolvedModel: unknown;
|
|
5
|
+
resolvedTools: unknown[];
|
|
6
|
+
resolvedMiddleware: unknown[];
|
|
7
|
+
resolvedCheckpointer: unknown;
|
|
8
|
+
resolvedStore: unknown;
|
|
9
|
+
passthroughOverride?: Record<string, unknown>;
|
|
10
|
+
systemPromptOverride?: string;
|
|
11
|
+
}): {
|
|
12
|
+
model: never;
|
|
13
|
+
tools: never;
|
|
14
|
+
systemPrompt: string | undefined;
|
|
15
|
+
stateSchema: never;
|
|
16
|
+
responseFormat: never;
|
|
17
|
+
contextSchema: never;
|
|
18
|
+
middleware: never;
|
|
19
|
+
checkpointer: never;
|
|
20
|
+
store: never;
|
|
21
|
+
includeAgentName: "inline" | undefined;
|
|
22
|
+
version: "v1" | "v2" | undefined;
|
|
23
|
+
name: string | undefined;
|
|
24
|
+
description: string;
|
|
25
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function buildLangChainRunnableConfig(params) {
|
|
2
|
+
const { langchainParams, resolvedModel, resolvedTools, resolvedMiddleware, resolvedCheckpointer, resolvedStore, passthroughOverride, systemPromptOverride, } = params;
|
|
3
|
+
return {
|
|
4
|
+
...(passthroughOverride ?? langchainParams.passthrough ?? {}),
|
|
5
|
+
model: resolvedModel,
|
|
6
|
+
tools: resolvedTools,
|
|
7
|
+
systemPrompt: systemPromptOverride ?? langchainParams.systemPrompt,
|
|
8
|
+
stateSchema: langchainParams.stateSchema,
|
|
9
|
+
responseFormat: langchainParams.responseFormat,
|
|
10
|
+
contextSchema: langchainParams.contextSchema,
|
|
11
|
+
middleware: resolvedMiddleware,
|
|
12
|
+
checkpointer: resolvedCheckpointer,
|
|
13
|
+
store: resolvedStore,
|
|
14
|
+
includeAgentName: langchainParams.includeAgentName,
|
|
15
|
+
version: langchainParams.version,
|
|
16
|
+
name: langchainParams.name,
|
|
17
|
+
description: langchainParams.description,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CompiledAgentBinding, CompiledTool } from "../../contracts/types.js";
|
|
2
|
+
import { type ToolNameMapping } from "./tool/tool-name-mapping.js";
|
|
3
|
+
import type { ExecutedToolResult } from "./invocation-result.js";
|
|
4
|
+
type ExecutableTool = {
|
|
5
|
+
name: string;
|
|
6
|
+
schema: unknown;
|
|
7
|
+
invoke: (input: unknown) => Promise<unknown>;
|
|
8
|
+
};
|
|
9
|
+
type LocalToolInvocationParams = {
|
|
10
|
+
binding: CompiledAgentBinding;
|
|
11
|
+
request: unknown;
|
|
12
|
+
primaryTools: CompiledTool[];
|
|
13
|
+
toolNameMapping: ToolNameMapping;
|
|
14
|
+
executableTools: Map<string, ExecutableTool>;
|
|
15
|
+
builtinExecutableTools: Map<string, ExecutableTool>;
|
|
16
|
+
callRuntimeWithToolParseRecovery: (request: unknown) => Promise<Record<string, unknown>>;
|
|
17
|
+
};
|
|
18
|
+
type LocalToolInvocationResult = {
|
|
19
|
+
result: Record<string, unknown>;
|
|
20
|
+
executedToolResults: ExecutedToolResult[];
|
|
21
|
+
};
|
|
22
|
+
export declare function runLocalToolInvocationLoop({ binding, request, primaryTools, toolNameMapping, executableTools, builtinExecutableTools, callRuntimeWithToolParseRecovery, }: LocalToolInvocationParams): Promise<LocalToolInvocationResult>;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { ToolMessage } from "@langchain/core/messages";
|
|
2
|
+
import { createModelFacingToolNameLookupCandidates, resolveModelFacingToolName } from "./tool/tool-name-mapping.js";
|
|
3
|
+
import { canReplayToolCallsLocally } from "./tool/tool-replay.js";
|
|
4
|
+
import { extractToolCallsFromResult, normalizeToolArgsForSchema, stringifyToolOutput } from "./tool/tool-arguments.js";
|
|
5
|
+
export async function runLocalToolInvocationLoop({ binding, request, primaryTools, toolNameMapping, executableTools, builtinExecutableTools, callRuntimeWithToolParseRecovery, }) {
|
|
6
|
+
const executedToolResults = [];
|
|
7
|
+
let activeRequest = request;
|
|
8
|
+
let currentMessages = Array.isArray(activeRequest.messages) ? [...activeRequest.messages] : [];
|
|
9
|
+
const maxToolIterations = 8;
|
|
10
|
+
let pendingResult;
|
|
11
|
+
let result;
|
|
12
|
+
for (let iteration = 0; iteration < maxToolIterations; iteration += 1) {
|
|
13
|
+
result = pendingResult ?? await callRuntimeWithToolParseRecovery(activeRequest);
|
|
14
|
+
pendingResult = undefined;
|
|
15
|
+
const toolCalls = extractToolCallsFromResult(result);
|
|
16
|
+
if (toolCalls.length === 0) {
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
if (!canReplayToolCallsLocally(binding, toolCalls, primaryTools, toolNameMapping, executableTools, builtinExecutableTools)) {
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
if (iteration + 1 === maxToolIterations) {
|
|
23
|
+
throw new Error(`Tool-calling loop exceeded the maximum of ${maxToolIterations} iterations`);
|
|
24
|
+
}
|
|
25
|
+
const resultMessages = result.messages;
|
|
26
|
+
const nextMessages = Array.isArray(resultMessages)
|
|
27
|
+
? [...resultMessages]
|
|
28
|
+
: [...currentMessages];
|
|
29
|
+
for (let toolIndex = 0; toolIndex < toolCalls.length; toolIndex += 1) {
|
|
30
|
+
const toolCall = toolCalls[toolIndex];
|
|
31
|
+
const resolvedToolName = resolveModelFacingToolName(toolCall.name, toolNameMapping, primaryTools);
|
|
32
|
+
const executable = executableTools.get(toolCall.name) ?? executableTools.get(resolvedToolName);
|
|
33
|
+
const builtinExecutable = builtinExecutableTools.get(toolCall.name) ??
|
|
34
|
+
builtinExecutableTools.get(resolvedToolName) ??
|
|
35
|
+
createModelFacingToolNameLookupCandidates(toolCall.name)
|
|
36
|
+
.map((candidate) => builtinExecutableTools.get(candidate))
|
|
37
|
+
.find((candidate) => candidate !== undefined);
|
|
38
|
+
const activeExecutable = executable ?? builtinExecutable;
|
|
39
|
+
if (!activeExecutable) {
|
|
40
|
+
throw new Error(`Tool ${toolCall.name} is not configured for this agent.`);
|
|
41
|
+
}
|
|
42
|
+
const normalizedArgs = normalizeToolArgsForSchema(toolCall.args, activeExecutable.schema);
|
|
43
|
+
const toolResult = await activeExecutable.invoke(normalizedArgs);
|
|
44
|
+
executedToolResults.push({
|
|
45
|
+
toolName: activeExecutable.name,
|
|
46
|
+
output: toolResult,
|
|
47
|
+
});
|
|
48
|
+
nextMessages.push(new ToolMessage({
|
|
49
|
+
name: activeExecutable.name,
|
|
50
|
+
tool_call_id: toolCall.id ?? `tool-${iteration + 1}-${toolIndex + 1}`,
|
|
51
|
+
content: stringifyToolOutput(toolResult),
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
currentMessages = nextMessages;
|
|
55
|
+
activeRequest = {
|
|
56
|
+
...activeRequest,
|
|
57
|
+
messages: currentMessages,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (!result) {
|
|
61
|
+
throw new Error("Agent invocation returned no result");
|
|
62
|
+
}
|
|
63
|
+
return { result, executedToolResults };
|
|
64
|
+
}
|