@botbotgo/agent-harness 0.0.227 → 0.0.229
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/dist/contracts/workspace.d.ts +17 -1
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/resource/resource-impl.js +59 -2
- package/dist/runtime/adapter/tool/builtin-middleware-tools.d.ts +54 -1
- package/dist/runtime/adapter/tool/builtin-middleware-tools.js +38 -8
- package/dist/runtime/adapter/tool/declared-middleware.js +2 -1
- package/dist/runtime/agent-runtime-adapter.d.ts +3 -2
- package/dist/runtime/agent-runtime-adapter.js +8 -2
- package/dist/runtime/support/compiled-binding.d.ts +2 -1
- package/dist/runtime/support/compiled-binding.js +6 -0
- package/dist/workspace/agent-binding-compiler.js +16 -1
- package/dist/workspace/object-loader.js +33 -0
- package/dist/workspace/validate.js +8 -1
- package/package.json +1 -1
|
@@ -15,10 +15,18 @@ export type ParsedAgentObject = {
|
|
|
15
15
|
memorySources: string[];
|
|
16
16
|
subagentRefs: string[];
|
|
17
17
|
subagentPathRefs: string[];
|
|
18
|
+
asyncSubagents?: ParsedAsyncSubAgent[];
|
|
18
19
|
langchainAgentConfig?: Record<string, unknown>;
|
|
19
20
|
deepAgentConfig?: Record<string, unknown>;
|
|
20
21
|
sourcePath: string;
|
|
21
22
|
};
|
|
23
|
+
export type ParsedAsyncSubAgent = {
|
|
24
|
+
name: string;
|
|
25
|
+
description: string;
|
|
26
|
+
graphId: string;
|
|
27
|
+
url?: string;
|
|
28
|
+
headers?: Record<string, string>;
|
|
29
|
+
};
|
|
22
30
|
export type ParsedAgentToolBinding = {
|
|
23
31
|
ref: string;
|
|
24
32
|
overrides?: Record<string, unknown>;
|
|
@@ -172,6 +180,14 @@ export type CompiledSubAgent = {
|
|
|
172
180
|
responseFormat?: unknown;
|
|
173
181
|
middleware?: Array<Record<string, unknown>>;
|
|
174
182
|
};
|
|
183
|
+
export type CompiledAsyncSubAgent = {
|
|
184
|
+
name: string;
|
|
185
|
+
description: string;
|
|
186
|
+
graphId: string;
|
|
187
|
+
url?: string;
|
|
188
|
+
headers?: Record<string, string>;
|
|
189
|
+
};
|
|
190
|
+
export type CompiledDeepAgentSubAgent = CompiledSubAgent | CompiledAsyncSubAgent;
|
|
175
191
|
export type LangChainAgentParams = {
|
|
176
192
|
model: CompiledModel;
|
|
177
193
|
tools: CompiledTool[];
|
|
@@ -192,7 +208,7 @@ export type DeepAgentParams = {
|
|
|
192
208
|
responseFormat?: unknown;
|
|
193
209
|
contextSchema?: unknown;
|
|
194
210
|
middleware?: Array<Record<string, unknown>>;
|
|
195
|
-
subagents:
|
|
211
|
+
subagents: CompiledDeepAgentSubAgent[];
|
|
196
212
|
interruptOn?: Record<string, boolean | object>;
|
|
197
213
|
backend?: Record<string, unknown>;
|
|
198
214
|
store?: Record<string, unknown>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.228";
|
package/dist/package-version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.228";
|
|
@@ -5,7 +5,7 @@ import path from "node:path";
|
|
|
5
5
|
import { stat } from "node:fs/promises";
|
|
6
6
|
import { readFile } from "node:fs/promises";
|
|
7
7
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
8
|
-
import { CompositeBackend, LocalShellBackend, StateBackend, StoreBackend } from "deepagents";
|
|
8
|
+
import { CompositeBackend, LangSmithSandbox, LocalShellBackend, StateBackend, StoreBackend } from "deepagents";
|
|
9
9
|
import { getBindingBackendConfig, getBindingExecutionView, getBindingPrimaryModel } from "../runtime/support/compiled-binding.js";
|
|
10
10
|
import { resolveCompiledEmbeddingModelRef } from "../runtime/support/embedding-models.js";
|
|
11
11
|
import { createRuntimeEnv } from "../runtime/support/runtime-env.js";
|
|
@@ -133,7 +133,60 @@ class CompatibleCompositeBackend {
|
|
|
133
133
|
return this.composite.downloadFiles(paths);
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
|
-
|
|
136
|
+
function omitKind(config) {
|
|
137
|
+
const { kind: _kind, ...rest } = config ?? {};
|
|
138
|
+
return rest;
|
|
139
|
+
}
|
|
140
|
+
class LazyLangSmithSandbox {
|
|
141
|
+
config;
|
|
142
|
+
sandboxPromise = null;
|
|
143
|
+
constructor(config) {
|
|
144
|
+
this.config = config;
|
|
145
|
+
}
|
|
146
|
+
get id() {
|
|
147
|
+
return "langsmith-pending";
|
|
148
|
+
}
|
|
149
|
+
get isRunning() {
|
|
150
|
+
return this.sandboxPromise !== null;
|
|
151
|
+
}
|
|
152
|
+
getSandbox() {
|
|
153
|
+
if (!this.sandboxPromise) {
|
|
154
|
+
this.sandboxPromise = LangSmithSandbox.create(omitKind(this.config));
|
|
155
|
+
}
|
|
156
|
+
return this.sandboxPromise;
|
|
157
|
+
}
|
|
158
|
+
async read(filePath, offset, limit) {
|
|
159
|
+
return (await this.getSandbox()).read(filePath, offset, limit);
|
|
160
|
+
}
|
|
161
|
+
async edit(filePath, oldString, newString, replaceAll) {
|
|
162
|
+
return (await this.getSandbox()).edit(filePath, oldString, newString, replaceAll);
|
|
163
|
+
}
|
|
164
|
+
async ls(dirPath) {
|
|
165
|
+
return (await this.getSandbox()).ls(dirPath);
|
|
166
|
+
}
|
|
167
|
+
async glob(pattern, searchPath) {
|
|
168
|
+
return (await this.getSandbox()).glob(pattern, searchPath);
|
|
169
|
+
}
|
|
170
|
+
async write(filePath, content) {
|
|
171
|
+
return (await this.getSandbox()).write(filePath, content);
|
|
172
|
+
}
|
|
173
|
+
async execute(command) {
|
|
174
|
+
return (await this.getSandbox()).execute(command);
|
|
175
|
+
}
|
|
176
|
+
async uploadFiles(files) {
|
|
177
|
+
return (await this.getSandbox()).uploadFiles(files);
|
|
178
|
+
}
|
|
179
|
+
async downloadFiles(paths) {
|
|
180
|
+
return (await this.getSandbox()).downloadFiles(paths);
|
|
181
|
+
}
|
|
182
|
+
async close() {
|
|
183
|
+
if (!this.sandboxPromise) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
await (await this.sandboxPromise).close();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
const INLINE_BACKEND_ERROR = 'Unsupported DeepAgent backend kind "%s". Supported inline kinds: LocalShellBackend, VfsSandbox, StateBackend, StoreBackend, CompositeBackend, LangSmithSandbox.';
|
|
137
190
|
function unsupportedInlineBackend(kind) {
|
|
138
191
|
throw new Error(INLINE_BACKEND_ERROR.replace("%s", kind));
|
|
139
192
|
}
|
|
@@ -172,6 +225,8 @@ function createInlineBackendInstance(workspaceRoot, kind, config, runtimeLike) {
|
|
|
172
225
|
return new StateBackend(runtimeLike);
|
|
173
226
|
case "StoreBackend":
|
|
174
227
|
return new StoreBackend(runtimeLike);
|
|
228
|
+
case "LangSmithSandbox":
|
|
229
|
+
return new LazyLangSmithSandbox(config);
|
|
175
230
|
default:
|
|
176
231
|
return unsupportedInlineBackend(kind);
|
|
177
232
|
}
|
|
@@ -193,6 +248,8 @@ function createInlineBackendResolver(workspace) {
|
|
|
193
248
|
return createInlineBackendInstance(workspace.workspaceRoot, "StateBackend", backendConfig, runtimeLike);
|
|
194
249
|
case "StoreBackend":
|
|
195
250
|
return createInlineBackendInstance(workspace.workspaceRoot, "StoreBackend", backendConfig, runtimeLike);
|
|
251
|
+
case "LangSmithSandbox":
|
|
252
|
+
return createInlineBackendInstance(workspace.workspaceRoot, "LangSmithSandbox", backendConfig, runtimeLike);
|
|
196
253
|
case "CompositeBackend": {
|
|
197
254
|
const stateConfig = typeof backendConfig.state === "object" && backendConfig.state
|
|
198
255
|
? backendConfig.state
|
|
@@ -8,7 +8,28 @@ export type BuiltinMiddlewareBackend = {
|
|
|
8
8
|
is_dir?: boolean;
|
|
9
9
|
size?: number;
|
|
10
10
|
}>;
|
|
11
|
-
|
|
11
|
+
ls?: (path: string) => Promise<{
|
|
12
|
+
files?: Array<{
|
|
13
|
+
path: string;
|
|
14
|
+
isDir?: boolean;
|
|
15
|
+
size?: number;
|
|
16
|
+
}>;
|
|
17
|
+
error?: string;
|
|
18
|
+
}> | {
|
|
19
|
+
files?: Array<{
|
|
20
|
+
path: string;
|
|
21
|
+
isDir?: boolean;
|
|
22
|
+
size?: number;
|
|
23
|
+
}>;
|
|
24
|
+
error?: string;
|
|
25
|
+
};
|
|
26
|
+
read?: (filePath: string, offset?: number, limit?: number) => Promise<string | {
|
|
27
|
+
content?: string | Uint8Array;
|
|
28
|
+
error?: string;
|
|
29
|
+
}> | string | {
|
|
30
|
+
content?: string | Uint8Array;
|
|
31
|
+
error?: string;
|
|
32
|
+
};
|
|
12
33
|
write?: (filePath: string, content: string) => Promise<{
|
|
13
34
|
error?: string;
|
|
14
35
|
path?: string;
|
|
@@ -34,6 +55,17 @@ export type BuiltinMiddlewareBackend = {
|
|
|
34
55
|
}>> | Array<{
|
|
35
56
|
path: string;
|
|
36
57
|
}>;
|
|
58
|
+
glob?: (pattern: string, path?: string) => Promise<{
|
|
59
|
+
files?: Array<{
|
|
60
|
+
path: string;
|
|
61
|
+
}>;
|
|
62
|
+
error?: string;
|
|
63
|
+
}> | {
|
|
64
|
+
files?: Array<{
|
|
65
|
+
path: string;
|
|
66
|
+
}>;
|
|
67
|
+
error?: string;
|
|
68
|
+
};
|
|
37
69
|
grepRaw?: (pattern: string, path?: string | null, glob?: string | null) => Promise<Array<{
|
|
38
70
|
path: string;
|
|
39
71
|
line: number;
|
|
@@ -43,6 +75,27 @@ export type BuiltinMiddlewareBackend = {
|
|
|
43
75
|
line: number;
|
|
44
76
|
text: string;
|
|
45
77
|
}> | string;
|
|
78
|
+
grep?: (pattern: string, path?: string | null, glob?: string | null) => Promise<{
|
|
79
|
+
matches?: Array<{
|
|
80
|
+
path: string;
|
|
81
|
+
lineNumber?: number;
|
|
82
|
+
line_number?: number;
|
|
83
|
+
content?: string;
|
|
84
|
+
line?: number;
|
|
85
|
+
text?: string;
|
|
86
|
+
}>;
|
|
87
|
+
error?: string;
|
|
88
|
+
}> | {
|
|
89
|
+
matches?: Array<{
|
|
90
|
+
path: string;
|
|
91
|
+
lineNumber?: number;
|
|
92
|
+
line_number?: number;
|
|
93
|
+
content?: string;
|
|
94
|
+
line?: number;
|
|
95
|
+
text?: string;
|
|
96
|
+
}>;
|
|
97
|
+
error?: string;
|
|
98
|
+
};
|
|
46
99
|
execute?: (command: string) => Promise<{
|
|
47
100
|
output: string;
|
|
48
101
|
exitCode: number | null;
|
|
@@ -2,6 +2,15 @@ import { z } from "zod";
|
|
|
2
2
|
import { isSandboxBackend } from "deepagents";
|
|
3
3
|
import { isRecord } from "../../../utils/object.js";
|
|
4
4
|
import { summarizeBuiltinWriteTodosArgs, truncateLines } from "../runtime-adapter-support.js";
|
|
5
|
+
function toDisplayContent(content) {
|
|
6
|
+
if (typeof content === "string") {
|
|
7
|
+
return content;
|
|
8
|
+
}
|
|
9
|
+
if (content instanceof Uint8Array) {
|
|
10
|
+
return new TextDecoder().decode(content);
|
|
11
|
+
}
|
|
12
|
+
return "";
|
|
13
|
+
}
|
|
5
14
|
export async function createBuiltinMiddlewareTools(backend, options) {
|
|
6
15
|
const tools = new Map();
|
|
7
16
|
tools.set("write_todos", {
|
|
@@ -25,7 +34,14 @@ export async function createBuiltinMiddlewareTools(backend, options) {
|
|
|
25
34
|
schema: z.object({ path: z.string().optional().default("/") }).passthrough(),
|
|
26
35
|
invoke: async (input) => {
|
|
27
36
|
const targetPath = isRecord(input) && typeof input.path === "string" ? input.path : "/";
|
|
28
|
-
const
|
|
37
|
+
const legacyInfos = (await Promise.resolve(backend.lsInfo?.(targetPath))) ?? [];
|
|
38
|
+
const infos = legacyInfos.length > 0
|
|
39
|
+
? legacyInfos
|
|
40
|
+
: ((await Promise.resolve(backend.ls?.(targetPath)))?.files ?? []).map((info) => ({
|
|
41
|
+
path: info.path,
|
|
42
|
+
is_dir: info.isDir,
|
|
43
|
+
size: info.size,
|
|
44
|
+
}));
|
|
29
45
|
if (infos.length === 0) {
|
|
30
46
|
return `No files found in ${targetPath}`;
|
|
31
47
|
}
|
|
@@ -44,7 +60,11 @@ export async function createBuiltinMiddlewareTools(backend, options) {
|
|
|
44
60
|
const filePath = typeof typed.file_path === "string" ? typed.file_path : "";
|
|
45
61
|
const offset = typeof typed.offset === "number" ? typed.offset : 0;
|
|
46
62
|
const limit = typeof typed.limit === "number" ? typed.limit : 500;
|
|
47
|
-
|
|
63
|
+
const result = await Promise.resolve(backend.read?.(filePath, offset, limit));
|
|
64
|
+
if (typeof result === "string") {
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
return toDisplayContent(result?.content);
|
|
48
68
|
},
|
|
49
69
|
});
|
|
50
70
|
tools.set("write_file", {
|
|
@@ -77,7 +97,10 @@ export async function createBuiltinMiddlewareTools(backend, options) {
|
|
|
77
97
|
const typed = isRecord(input) ? input : {};
|
|
78
98
|
const pattern = typeof typed.pattern === "string" ? typed.pattern : "";
|
|
79
99
|
const targetPath = typeof typed.path === "string" ? typed.path : "/";
|
|
80
|
-
const
|
|
100
|
+
const legacyInfos = (await Promise.resolve(backend.globInfo?.(pattern, targetPath))) ?? [];
|
|
101
|
+
const infos = legacyInfos.length > 0
|
|
102
|
+
? legacyInfos
|
|
103
|
+
: ((await Promise.resolve(backend.glob?.(pattern, targetPath)))?.files ?? []);
|
|
81
104
|
if (infos.length === 0) {
|
|
82
105
|
return `No files found matching pattern '${pattern}'`;
|
|
83
106
|
}
|
|
@@ -93,16 +116,23 @@ export async function createBuiltinMiddlewareTools(backend, options) {
|
|
|
93
116
|
}).passthrough(),
|
|
94
117
|
invoke: async (input) => {
|
|
95
118
|
const typed = isRecord(input) ? input : {};
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
119
|
+
const legacyResult = await Promise.resolve(backend.grepRaw?.(typeof typed.pattern === "string" ? typed.pattern : "", typeof typed.path === "string" ? typed.path : "/", typeof typed.glob === "string" ? typed.glob : null));
|
|
120
|
+
const structuredResult = await Promise.resolve(backend.grep?.(typeof typed.pattern === "string" ? typed.pattern : "", typeof typed.path === "string" ? typed.path : "/", typeof typed.glob === "string" ? typed.glob : null));
|
|
121
|
+
const normalizedStructuredMatches = structuredResult?.matches?.map((match) => ({
|
|
122
|
+
path: match.path,
|
|
123
|
+
line: match.lineNumber ?? match.line_number ?? match.line ?? 0,
|
|
124
|
+
text: match.content ?? match.text ?? "",
|
|
125
|
+
}));
|
|
126
|
+
const normalizedResult = legacyResult ?? normalizedStructuredMatches;
|
|
127
|
+
if (typeof normalizedResult === "string") {
|
|
128
|
+
return normalizedResult;
|
|
99
129
|
}
|
|
100
|
-
if (!
|
|
130
|
+
if (!normalizedResult || normalizedResult.length === 0) {
|
|
101
131
|
return `No matches found for pattern '${typeof typed.pattern === "string" ? typed.pattern : ""}'`;
|
|
102
132
|
}
|
|
103
133
|
const lines = [];
|
|
104
134
|
let currentFile = "";
|
|
105
|
-
for (const match of
|
|
135
|
+
for (const match of normalizedResult) {
|
|
106
136
|
if (match.path !== currentFile) {
|
|
107
137
|
currentFile = match.path;
|
|
108
138
|
lines.push(`\n${currentFile}:`);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { anthropicPromptCachingMiddleware, contextEditingMiddleware, dynamicSystemPromptMiddleware, humanInTheLoopMiddleware, llmToolSelectorMiddleware, modelCallLimitMiddleware, modelFallbackMiddleware, modelRetryMiddleware, openAIModerationMiddleware, piiMiddleware, piiRedactionMiddleware, summarizationMiddleware, todoListMiddleware, toolCallLimitMiddleware, toolEmulatorMiddleware, toolRetryMiddleware, } from "langchain";
|
|
2
|
-
import { createFilesystemMiddleware, createPatchToolCallsMiddleware, createSummarizationMiddleware as createDeepAgentSummarizationMiddleware, } from "deepagents";
|
|
2
|
+
import { createCompletionCallbackMiddleware, createFilesystemMiddleware, createPatchToolCallsMiddleware, createSummarizationMiddleware as createDeepAgentSummarizationMiddleware, } from "deepagents";
|
|
3
3
|
function asMiddlewareConfig(value) {
|
|
4
4
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? { ...value } : null;
|
|
5
5
|
}
|
|
@@ -84,6 +84,7 @@ async function createFilesystemDeclarativeMiddleware({ config, resolveFilesystem
|
|
|
84
84
|
return createFilesystemMiddleware(runtimeConfig);
|
|
85
85
|
}
|
|
86
86
|
export const DECLARATIVE_MIDDLEWARE_REGISTRY = {
|
|
87
|
+
completionCallback: async ({ config }) => createCompletionCallbackMiddleware(config),
|
|
87
88
|
filesystem: createFilesystemDeclarativeMiddleware,
|
|
88
89
|
patchToolCalls: async () => createPatchToolCallsMiddleware(),
|
|
89
90
|
summarization: createBindingAwareSummarizationMiddleware,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CompiledAgentBinding, MessageContent, RunResult, RuntimeAdapterOptions, TranscriptMessage } from "../contracts/types.js";
|
|
1
|
+
import type { CompiledAgentBinding, CompiledAsyncSubAgent, MessageContent, RunResult, RuntimeAdapterOptions, TranscriptMessage } from "../contracts/types.js";
|
|
2
2
|
import { type RuntimeStreamChunk } from "./parsing/stream-event-parsing.js";
|
|
3
3
|
import { RuntimeOperationTimeoutError } from "./adapter/runtime-shell.js";
|
|
4
4
|
import { type UpstreamSubagentConfig } from "./adapter/middleware-assembly.js";
|
|
@@ -36,7 +36,7 @@ export declare function buildDeepAgentCreateParams(input: {
|
|
|
36
36
|
resolvedModel: unknown;
|
|
37
37
|
resolvedTools: unknown[];
|
|
38
38
|
resolvedMiddleware: unknown[];
|
|
39
|
-
resolvedSubagents: UpstreamSubagentConfig
|
|
39
|
+
resolvedSubagents: Array<UpstreamSubagentConfig | CompiledAsyncSubAgent>;
|
|
40
40
|
resolvedCheckpointer?: unknown;
|
|
41
41
|
resolvedStore?: unknown;
|
|
42
42
|
resolvedBackend?: unknown;
|
|
@@ -73,6 +73,7 @@ export declare class AgentRuntimeAdapter {
|
|
|
73
73
|
private resolveLangChainRuntimeExtensionMiddleware;
|
|
74
74
|
private resolveMiddleware;
|
|
75
75
|
private resolveSubagents;
|
|
76
|
+
private resolveDeepAgentSubagents;
|
|
76
77
|
private createLangChainRunnable;
|
|
77
78
|
private createRunnable;
|
|
78
79
|
private createDeepAgentRunnable;
|
|
@@ -18,7 +18,7 @@ export { applyDeepAgentDelegationPromptCompatibility, materializeDeepAgentSkillS
|
|
|
18
18
|
export { buildAuthOmittingFetch, normalizeOpenAICompatibleInit } from "./adapter/compat/openai-compatible.js";
|
|
19
19
|
export { buildToolNameMapping, createModelFacingToolNameCandidates, createModelFacingToolNameLookupCandidates, resolveModelFacingToolName, sanitizeToolNameForModel, } from "./adapter/tool/tool-name-mapping.js";
|
|
20
20
|
export { computeRemainingTimeoutMs, isRetryableProviderError, resolveBindingTimeout, resolveProviderRetryPolicy, resolveStreamIdleTimeout, resolveTimeoutMs, } from "./adapter/resilience.js";
|
|
21
|
-
import { getBindingBackendConfig, getBindingAdapterKind, getBindingExecutionKind, getBindingExecutionParams, getBindingFilesystemConfig, getBindingInterruptCompatibilityRules, getBindingMemorySources, getBindingMiddlewareConfigs, getBindingPrimaryModel, getBindingSkills, getBindingStoreConfig,
|
|
21
|
+
import { getBindingBackendConfig, getBindingAdapterKind, getBindingDeepAgentSubagents, getBindingExecutionKind, getBindingExecutionParams, getBindingFilesystemConfig, getBindingInterruptCompatibilityRules, getBindingMemorySources, getBindingMiddlewareConfigs, getBindingPrimaryModel, getBindingSkills, getBindingStoreConfig, getBindingToolCount, getBindingPrimaryTools, getBindingSystemPrompt, isDeepAgentBinding, isLangChainBinding, } from "./support/compiled-binding.js";
|
|
22
22
|
const AGENT_INTERRUPT_SENTINEL_PREFIX = "__agent_harness_interrupt__:";
|
|
23
23
|
const UPSTREAM_BUILTIN_MIDDLEWARE_TOOL_NAMES = Object.freeze([
|
|
24
24
|
"write_todos",
|
|
@@ -372,6 +372,12 @@ export class AgentRuntimeAdapter {
|
|
|
372
372
|
createDeclaredMiddlewareResolverOptions: assembly.createDeclaredMiddlewareResolverOptions,
|
|
373
373
|
});
|
|
374
374
|
}
|
|
375
|
+
async resolveDeepAgentSubagents(subagents, binding) {
|
|
376
|
+
const syncSubagents = subagents.filter((subagent) => !("graphId" in subagent));
|
|
377
|
+
const asyncSubagents = subagents.filter((subagent) => "graphId" in subagent);
|
|
378
|
+
const resolvedSyncSubagents = await this.resolveSubagents(syncSubagents, binding);
|
|
379
|
+
return [...resolvedSyncSubagents, ...asyncSubagents];
|
|
380
|
+
}
|
|
375
381
|
async createLangChainRunnable(binding, options = {}) {
|
|
376
382
|
const executionKind = getBindingExecutionKind(binding);
|
|
377
383
|
const primaryModel = getBindingPrimaryModel(binding);
|
|
@@ -419,7 +425,7 @@ export class AgentRuntimeAdapter {
|
|
|
419
425
|
const resolvedModel = await this.resolveModel(primaryModel);
|
|
420
426
|
const resolvedTools = this.resolveTools(primaryTools, binding);
|
|
421
427
|
const resolvedMiddleware = await this.resolveMiddleware(binding);
|
|
422
|
-
const resolvedSubagents = await this.
|
|
428
|
+
const resolvedSubagents = await this.resolveDeepAgentSubagents(getBindingDeepAgentSubagents(binding), binding);
|
|
423
429
|
const resolvedInterruptOn = resolveRunnableInterruptOn(binding);
|
|
424
430
|
const substrateMode = this.options.deepAgentUpstreamSubstrateMode ?? "minimal";
|
|
425
431
|
const resolvedCheckpointer = substrateMode === "minimal"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CompiledAgentBinding, CompiledExecutionBinding, CompiledModel, CompiledSubAgent, CompiledTool, DeepAgentParams, LegacyDeepAgentParams, LegacyLangChainAgentParams, LangChainAgentParams } from "../../contracts/types.js";
|
|
1
|
+
import type { CompiledAgentBinding, CompiledDeepAgentSubAgent, CompiledExecutionBinding, CompiledModel, CompiledSubAgent, CompiledTool, DeepAgentParams, LegacyDeepAgentParams, LegacyLangChainAgentParams, LangChainAgentParams } from "../../contracts/types.js";
|
|
2
2
|
export type BindingExecutionView = {
|
|
3
3
|
adapterKind: string;
|
|
4
4
|
langchainParams?: LegacyLangChainAgentParams;
|
|
@@ -27,6 +27,7 @@ export declare function withUpdatedBindingExecutionParams(binding: CompiledAgent
|
|
|
27
27
|
export declare function getBindingSkills(binding: CompiledAgentBinding): string[];
|
|
28
28
|
export declare function getBindingMemorySources(binding: CompiledAgentBinding): string[];
|
|
29
29
|
export declare function getBindingSubagents(binding: CompiledAgentBinding): CompiledSubAgent[];
|
|
30
|
+
export declare function getBindingDeepAgentSubagents(binding: CompiledAgentBinding): CompiledDeepAgentSubAgent[];
|
|
30
31
|
export declare function getBindingGeneralPurposeAgent(binding: CompiledAgentBinding): boolean | undefined;
|
|
31
32
|
export declare function getBindingTaskDescription(binding: CompiledAgentBinding): string | undefined;
|
|
32
33
|
export declare function getBindingBackendConfig(binding: CompiledAgentBinding): Record<string, unknown> | undefined;
|
|
@@ -202,6 +202,12 @@ export function getBindingSubagents(binding) {
|
|
|
202
202
|
? (execution.subagents)
|
|
203
203
|
: [];
|
|
204
204
|
}
|
|
205
|
+
export function getBindingDeepAgentSubagents(binding) {
|
|
206
|
+
const execution = getBindingExecutionParams(binding);
|
|
207
|
+
return Array.isArray(execution?.subagents)
|
|
208
|
+
? (execution.subagents)
|
|
209
|
+
: [];
|
|
210
|
+
}
|
|
205
211
|
export function getBindingGeneralPurposeAgent(binding) {
|
|
206
212
|
const langchainGeneralPurposeAgent = binding.harnessRuntime?.langchain?.generalPurposeAgent;
|
|
207
213
|
if (typeof langchainGeneralPurposeAgent === "boolean") {
|
|
@@ -215,6 +215,21 @@ function compileSubagents(agent, agents, workspaceRoot, models, tools, compiledA
|
|
|
215
215
|
return buildSubagent(subagent, workspaceRoot, models, tools, compiledAgentSkills, compiledAgentModel);
|
|
216
216
|
});
|
|
217
217
|
}
|
|
218
|
+
function compileAsyncSubagents(agent) {
|
|
219
|
+
return (agent.asyncSubagents ?? []).map((subagent) => ({
|
|
220
|
+
name: subagent.name,
|
|
221
|
+
description: subagent.description,
|
|
222
|
+
graphId: subagent.graphId,
|
|
223
|
+
...(subagent.url ? { url: subagent.url } : {}),
|
|
224
|
+
...(subagent.headers ? { headers: { ...subagent.headers } } : {}),
|
|
225
|
+
}));
|
|
226
|
+
}
|
|
227
|
+
function compileDeepAgentSubagents(agent, agents, workspaceRoot, models, tools, compiledAgentSkills, compiledAgentModel) {
|
|
228
|
+
return [
|
|
229
|
+
...compileSubagents(agent, agents, workspaceRoot, models, tools, compiledAgentSkills, compiledAgentModel),
|
|
230
|
+
...compileAsyncSubagents(agent),
|
|
231
|
+
];
|
|
232
|
+
}
|
|
218
233
|
function compileExecutionCore(agent, models, tools) {
|
|
219
234
|
return {
|
|
220
235
|
model: requireModel(models, agent.modelRef, agent.id),
|
|
@@ -420,7 +435,7 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
|
|
|
420
435
|
responseFormat: executionCore.responseFormat,
|
|
421
436
|
contextSchema: executionCore.contextSchema,
|
|
422
437
|
middleware: executionCore.middleware,
|
|
423
|
-
subagents:
|
|
438
|
+
subagents: compileDeepAgentSubagents(agent, agents, workspaceRoot, models, tools, compiledAgentSkills, compiledAgentModel),
|
|
424
439
|
interruptOn: resolveInterruptOn(agent),
|
|
425
440
|
...(backend ? { backend: backend.config } : {}),
|
|
426
441
|
...(store ? { store: store.config } : {}),
|
|
@@ -87,6 +87,37 @@ function readRefArray(items) {
|
|
|
87
87
|
: undefined)
|
|
88
88
|
.filter((item) => Boolean(item));
|
|
89
89
|
}
|
|
90
|
+
function readStringRecord(value) {
|
|
91
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
const entries = Object.entries(value)
|
|
95
|
+
.filter((entry) => typeof entry[1] === "string");
|
|
96
|
+
return entries.length > 0 ? Object.fromEntries(entries) : undefined;
|
|
97
|
+
}
|
|
98
|
+
function readAsyncSubAgentArray(items) {
|
|
99
|
+
return toArray(items)
|
|
100
|
+
.flatMap((item) => {
|
|
101
|
+
if (typeof item !== "object" || item === null || Array.isArray(item)) {
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
const typed = item;
|
|
105
|
+
const name = typeof typed.name === "string" ? typed.name.trim() : "";
|
|
106
|
+
const description = typeof typed.description === "string" ? typed.description.trim() : "";
|
|
107
|
+
const graphId = typeof typed.graphId === "string" ? typed.graphId.trim() : "";
|
|
108
|
+
if (!name || !description || !graphId) {
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
const headers = readStringRecord(typed.headers);
|
|
112
|
+
return [{
|
|
113
|
+
name,
|
|
114
|
+
description,
|
|
115
|
+
graphId,
|
|
116
|
+
...(typeof typed.url === "string" && typed.url.trim().length > 0 ? { url: typed.url.trim() } : {}),
|
|
117
|
+
...(headers ? { headers } : {}),
|
|
118
|
+
}];
|
|
119
|
+
});
|
|
120
|
+
}
|
|
90
121
|
function readPrefixedRefArray(items, prefix) {
|
|
91
122
|
return toArray(items)
|
|
92
123
|
.map((item) => {
|
|
@@ -472,6 +503,7 @@ export function parseAgentItem(item, sourcePath) {
|
|
|
472
503
|
const subagentPathRefs = readExecutionValue(normalizedItem, "subagents", readPathArray)
|
|
473
504
|
.filter((entry) => path.isAbsolute(entry) || entry.startsWith("./") || entry.startsWith("../"))
|
|
474
505
|
.map((entry) => resolveModuleRelativePath(entry, moduleRoot));
|
|
506
|
+
const asyncSubagents = readExecutionValue(normalizedItem, "subagents", readAsyncSubAgentArray);
|
|
475
507
|
const executionMode = String(resolveExecutionBackend(normalizedItem) ?? "deepagent");
|
|
476
508
|
const runtime = readRuntimeConfig(normalizedItem);
|
|
477
509
|
return {
|
|
@@ -492,6 +524,7 @@ export function parseAgentItem(item, sourcePath) {
|
|
|
492
524
|
memorySources: readExecutionValue(normalizedItem, "memory", readPathArray).map((entry) => resolveModuleRelativePath(entry, moduleRoot)),
|
|
493
525
|
subagentRefs,
|
|
494
526
|
subagentPathRefs,
|
|
527
|
+
asyncSubagents,
|
|
495
528
|
langchainAgentConfig: normalizeModuleAgentConfig(readAgentConfig(normalizedItem, { includeDelegationControls: true }), moduleRoot),
|
|
496
529
|
deepAgentConfig: normalizeModuleAgentConfig(readAgentConfig(normalizedItem, {
|
|
497
530
|
includeObjectBackend: true,
|
|
@@ -39,6 +39,9 @@ function validateMiddlewareConfig(agent) {
|
|
|
39
39
|
if (kind === "humanInTheLoop" && typeof typed.interruptOn !== "object") {
|
|
40
40
|
throw new Error(`Agent ${agent.id} humanInTheLoop middleware requires interruptOn`);
|
|
41
41
|
}
|
|
42
|
+
if (kind === "completionCallback" && typeof typed.callbackGraphId !== "string") {
|
|
43
|
+
throw new Error(`Agent ${agent.id} completionCallback middleware requires callbackGraphId`);
|
|
44
|
+
}
|
|
42
45
|
if (kind === "filesystem" && agent.executionMode === "deepagent") {
|
|
43
46
|
throw new Error(`Agent ${agent.id} cannot use filesystem middleware with DeepAgents; configure filesystem behavior through the deepagent backend instead`);
|
|
44
47
|
}
|
|
@@ -48,6 +51,7 @@ function validateMiddlewareConfig(agent) {
|
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
53
|
export function validateAgent(agent) {
|
|
54
|
+
const asyncSubagents = agent.asyncSubagents ?? [];
|
|
51
55
|
if (!agent.id) {
|
|
52
56
|
throw new Error(`Agent id is required in ${agent.sourcePath}`);
|
|
53
57
|
}
|
|
@@ -60,9 +64,12 @@ export function validateAgent(agent) {
|
|
|
60
64
|
if (!isMemoryCapableAgent(agent) && agent.memorySources.length > 0) {
|
|
61
65
|
throw new Error(`Agent ${agent.id} cannot define memory unless it uses a memory-capable backend`);
|
|
62
66
|
}
|
|
63
|
-
if ((agent.subagentRefs.length > 0 || agent.subagentPathRefs.length > 0) && !isDelegationCapableAgent(agent)) {
|
|
67
|
+
if ((agent.subagentRefs.length > 0 || agent.subagentPathRefs.length > 0 || asyncSubagents.length > 0) && !isDelegationCapableAgent(agent)) {
|
|
64
68
|
throw new Error(`Agent ${agent.id} must use a delegation-capable backend when subagents are defined`);
|
|
65
69
|
}
|
|
70
|
+
if (asyncSubagents.length > 0 && agent.executionMode !== "deepagent") {
|
|
71
|
+
throw new Error(`Agent ${agent.id} async subagents require backend=deepagent`);
|
|
72
|
+
}
|
|
66
73
|
validateCheckpointerConfig(agent);
|
|
67
74
|
validateMiddlewareConfig(agent);
|
|
68
75
|
}
|