@botbotgo/agent-harness 0.0.359 → 0.0.362
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 +2 -0
- package/README.zh.md +2 -0
- package/dist/config/catalogs/response-formats.yaml +43 -0
- package/dist/config/runtime/workspace.yaml +8 -0
- package/dist/contracts/runtime-requests.d.ts +19 -0
- package/dist/contracts/workspace.d.ts +6 -0
- package/dist/package-version.d.ts +2 -2
- package/dist/package-version.js +2 -2
- package/dist/projections/request-events.d.ts +1 -0
- package/dist/projections/request-events.js +97 -45
- package/dist/protocol/acp/harness-client.js +2 -3
- package/dist/runtime/adapter/flow/invocation-flow.js +26 -1
- package/dist/runtime/adapter/flow/stream-runtime.js +117 -94
- package/dist/runtime/adapter/invocation-result.js +15 -0
- package/dist/runtime/adapter/middleware-assembly.js +25 -3
- package/dist/runtime/adapter/tool/builtin-middleware-tools.d.ts +5 -0
- package/dist/runtime/adapter/tool/builtin-middleware-tools.js +30 -6
- package/dist/runtime/agent-runtime-adapter.d.ts +1 -0
- package/dist/runtime/agent-runtime-adapter.js +174 -28
- package/dist/runtime/harness/events/streaming.js +2 -3
- package/dist/workspace/agent-binding-compiler.js +90 -12
- package/dist/workspace/compile.js +1 -0
- package/dist/workspace/framework-contract-validation.d.ts +2 -1
- package/dist/workspace/framework-contract-validation.js +77 -5
- package/dist/workspace/object-loader.js +9 -0
- package/dist/workspace/support/workspace-ref-utils.d.ts +1 -0
- package/dist/workspace/support/workspace-ref-utils.js +40 -0
- package/dist/workspace/yaml-object-reader.js +13 -9
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { validateSkillMetadata } from "../runtime/skills/skill-metadata.js";
|
|
3
3
|
import { getAgentExecutionConfigValue } from "./support/agent-execution-config.js";
|
|
4
|
-
import { resolvePromptValue } from "./support/workspace-ref-utils.js";
|
|
4
|
+
import { getRuntimeAgentDefaults, getWorkspaceObject, resolvePromptValue } from "./support/workspace-ref-utils.js";
|
|
5
5
|
const FORBIDDEN_GENERAL_PURPOSE_SUBAGENT_NAME = "general-purpose";
|
|
6
6
|
const FRAMEWORK_AGENT_TOOL_NAMES = new Set(["task"]);
|
|
7
7
|
const FRAMEWORK_EXECUTION_TOOL_NAMES = new Set(["write_todos", "read_todos"]);
|
|
@@ -87,6 +87,78 @@ function readObject(value) {
|
|
|
87
87
|
? value
|
|
88
88
|
: undefined;
|
|
89
89
|
}
|
|
90
|
+
function normalizeResponseFormatRef(ref) {
|
|
91
|
+
return ref.startsWith("response-format/") ? ref : `response-format/${ref}`;
|
|
92
|
+
}
|
|
93
|
+
function resolveResponseFormatRef(refs, ref) {
|
|
94
|
+
if (!refs || !ref) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
const object = getWorkspaceObject(refs, normalizeResponseFormatRef(ref));
|
|
98
|
+
if (!object || object.kind !== "response-format") {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
return object.value.format;
|
|
102
|
+
}
|
|
103
|
+
function mergeResponseFormats(base, override) {
|
|
104
|
+
if (override === undefined) {
|
|
105
|
+
return base;
|
|
106
|
+
}
|
|
107
|
+
if (typeof base === "object" &&
|
|
108
|
+
base &&
|
|
109
|
+
typeof override === "object" &&
|
|
110
|
+
override &&
|
|
111
|
+
!Array.isArray(base) &&
|
|
112
|
+
!Array.isArray(override)) {
|
|
113
|
+
const merged = { ...base };
|
|
114
|
+
for (const [key, value] of Object.entries(override)) {
|
|
115
|
+
if (key === "required" && Array.isArray(merged.required) && Array.isArray(value)) {
|
|
116
|
+
merged.required = Array.from(new Set([...merged.required, ...value]));
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (key === "properties" &&
|
|
120
|
+
typeof merged.properties === "object" &&
|
|
121
|
+
merged.properties &&
|
|
122
|
+
!Array.isArray(merged.properties) &&
|
|
123
|
+
typeof value === "object" &&
|
|
124
|
+
value &&
|
|
125
|
+
!Array.isArray(value)) {
|
|
126
|
+
merged.properties = {
|
|
127
|
+
...merged.properties,
|
|
128
|
+
...value,
|
|
129
|
+
};
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
merged[key] = key in merged ? mergeResponseFormats(merged[key], value) : value;
|
|
133
|
+
}
|
|
134
|
+
return merged;
|
|
135
|
+
}
|
|
136
|
+
return override;
|
|
137
|
+
}
|
|
138
|
+
function resolveInheritedResponseFormat(agent, refs) {
|
|
139
|
+
if (!refs) {
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
const defaults = getRuntimeAgentDefaults(refs);
|
|
143
|
+
if (defaults && "responseFormat" in defaults) {
|
|
144
|
+
return defaults.responseFormat === null ? undefined : defaults.responseFormat;
|
|
145
|
+
}
|
|
146
|
+
const defaultRef = typeof defaults?.responseFormatRef === "string" ? defaults.responseFormatRef.trim() : "";
|
|
147
|
+
return defaultRef ? resolveResponseFormatRef(refs, defaultRef) : undefined;
|
|
148
|
+
}
|
|
149
|
+
function resolveEffectiveResponseFormat(agent, refs) {
|
|
150
|
+
const explicitResponseFormat = getAgentExecutionConfigValue(agent, "responseFormat");
|
|
151
|
+
if (explicitResponseFormat !== undefined) {
|
|
152
|
+
return explicitResponseFormat === null
|
|
153
|
+
? undefined
|
|
154
|
+
: mergeResponseFormats(resolveInheritedResponseFormat(agent, refs), explicitResponseFormat);
|
|
155
|
+
}
|
|
156
|
+
const explicitRef = getAgentExecutionConfigValue(agent, "responseFormatRef");
|
|
157
|
+
if (typeof explicitRef === "string" && explicitRef.trim().length > 0) {
|
|
158
|
+
return resolveResponseFormatRef(refs, explicitRef.trim());
|
|
159
|
+
}
|
|
160
|
+
return resolveInheritedResponseFormat(agent, refs);
|
|
161
|
+
}
|
|
90
162
|
function validateResponseFormatTerminalStatus(agent, responseFormat, issues) {
|
|
91
163
|
const schema = readObject(responseFormat);
|
|
92
164
|
const properties = readObject(schema?.properties);
|
|
@@ -101,7 +173,7 @@ function validateResponseFormatTerminalStatus(agent, responseFormat, issues) {
|
|
|
101
173
|
addIssue(issues, "agent.response_format.incomplete_terminal_status_enum", `Agent ${agent.id} responseFormat status enum must include completed, blocked, failed, and refused.`);
|
|
102
174
|
}
|
|
103
175
|
}
|
|
104
|
-
function validateAgentContract(agent, referencedSubagentIds, tools, issues) {
|
|
176
|
+
function validateAgentContract(agent, referencedSubagentIds, tools, refs, issues) {
|
|
105
177
|
const description = agent.description.trim();
|
|
106
178
|
const systemPrompt = resolvePromptValue(getAgentExecutionConfigValue(agent, "systemPrompt"), path.dirname(agent.sourcePath));
|
|
107
179
|
const ownsDelegation = agent.subagentRefs.length > 0 || agent.subagentPathRefs.length > 0 || (agent.asyncSubagents?.length ?? 0) > 0;
|
|
@@ -109,7 +181,7 @@ function validateAgentContract(agent, referencedSubagentIds, tools, issues) {
|
|
|
109
181
|
const hasTools = agent.toolRefs.length > 0
|
|
110
182
|
|| (agent.toolBindings?.length ?? 0) > 0
|
|
111
183
|
|| (agent.inlineTools?.length ?? 0) > 0;
|
|
112
|
-
const responseFormat =
|
|
184
|
+
const responseFormat = resolveEffectiveResponseFormat(agent, refs);
|
|
113
185
|
const builtinTools = readBuiltinToolsConfig(agent);
|
|
114
186
|
const executionContract = readExecutionContractConfig(agent);
|
|
115
187
|
const localSubagentNames = [
|
|
@@ -156,7 +228,7 @@ function validateAgentContract(agent, referencedSubagentIds, tools, issues) {
|
|
|
156
228
|
addIssue(issues, "agent.subagent.missing_prompt", `Subagent ${agent.id} should define a systemPrompt that makes its operating boundary and output contract explicit.`);
|
|
157
229
|
}
|
|
158
230
|
if (agent.executionMode === "deepagent" && hasTools && responseFormat === undefined) {
|
|
159
|
-
addIssue(issues, "agent.subagent.deepagent.missing_response_format", `DeepAgents subagent ${agent.id} exposes tools, so it should define
|
|
231
|
+
addIssue(issues, "agent.subagent.deepagent.missing_response_format", `DeepAgents subagent ${agent.id} exposes tools, so it should inherit or define a responseFormat to guarantee a stable task result for its parent agent.`);
|
|
160
232
|
}
|
|
161
233
|
if (agent.executionMode === "deepagent" && hasTools && responseFormat !== undefined) {
|
|
162
234
|
validateResponseFormatTerminalStatus(agent, responseFormat, issues);
|
|
@@ -200,7 +272,7 @@ export function validateFrameworkContracts(input) {
|
|
|
200
272
|
if (!isWorkspaceOwnedPath(agent.sourcePath, input.ownedRoots)) {
|
|
201
273
|
continue;
|
|
202
274
|
}
|
|
203
|
-
validateAgentContract(agent, referencedSubagentIds, input.tools, issues);
|
|
275
|
+
validateAgentContract(agent, referencedSubagentIds, input.tools, input.refs, issues);
|
|
204
276
|
}
|
|
205
277
|
for (const [skillName, skillRoot] of input.skillRegistry) {
|
|
206
278
|
if (!isWorkspaceOwnedPath(skillRoot, input.ownedRoots)) {
|
|
@@ -16,6 +16,7 @@ const CONSUMED_AGENT_CONFIG_KEYS = [
|
|
|
16
16
|
"interruptOn",
|
|
17
17
|
"stateSchema",
|
|
18
18
|
"responseFormat",
|
|
19
|
+
"responseFormatRef",
|
|
19
20
|
"contextSchema",
|
|
20
21
|
"includeAgentName",
|
|
21
22
|
"version",
|
|
@@ -56,6 +57,7 @@ const MIGRATED_AGENT_CONFIG_KEYS = [
|
|
|
56
57
|
"interruptOn",
|
|
57
58
|
"stateSchema",
|
|
58
59
|
"responseFormat",
|
|
60
|
+
"responseFormatRef",
|
|
59
61
|
"contextSchema",
|
|
60
62
|
"includeAgentName",
|
|
61
63
|
"version",
|
|
@@ -264,6 +266,13 @@ function readSharedAgentConfig(config) {
|
|
|
264
266
|
...(typeof config.interruptOn === "object" && config.interruptOn ? { interruptOn: config.interruptOn } : {}),
|
|
265
267
|
...(config.stateSchema !== undefined ? { stateSchema: config.stateSchema } : {}),
|
|
266
268
|
...(config.responseFormat !== undefined ? { responseFormat: config.responseFormat } : {}),
|
|
269
|
+
...(typeof config.responseFormatRef === "string" && config.responseFormatRef.trim()
|
|
270
|
+
? {
|
|
271
|
+
responseFormatRef: config.responseFormatRef.startsWith("response-format/")
|
|
272
|
+
? config.responseFormatRef
|
|
273
|
+
: `response-format/${config.responseFormatRef.trim()}`,
|
|
274
|
+
}
|
|
275
|
+
: {}),
|
|
267
276
|
...(config.contextSchema !== undefined ? { contextSchema: config.contextSchema } : {}),
|
|
268
277
|
...(config.interactionMode === "stream" || config.interactionMode === "invoke" ? { interactionMode: config.interactionMode } : {}),
|
|
269
278
|
...(config.includeAgentName === "inline" ? { includeAgentName: "inline" } : {}),
|
|
@@ -37,6 +37,7 @@ export type ToolModuleDiscoveryConfig = {
|
|
|
37
37
|
};
|
|
38
38
|
export declare function getWorkspaceObject(refs: Map<string, WorkspaceObject | ParsedAgentObject>, ref: string | undefined): WorkspaceObject | undefined;
|
|
39
39
|
export declare function getRuntimeDefaults(refs: Map<string, WorkspaceObject | ParsedAgentObject>): Record<string, unknown> | undefined;
|
|
40
|
+
export declare function getRuntimeAgentDefaults(refs: Map<string, WorkspaceObject | ParsedAgentObject>): Record<string, unknown> | undefined;
|
|
40
41
|
export type RuntimeStorageRoots = {
|
|
41
42
|
applicationRoot: string;
|
|
42
43
|
dataRoot: string;
|
|
@@ -27,6 +27,46 @@ export function getRuntimeDefaults(refs) {
|
|
|
27
27
|
}
|
|
28
28
|
return runtimes[0].value;
|
|
29
29
|
}
|
|
30
|
+
function mergeConfigValue(base, override) {
|
|
31
|
+
if (override === undefined) {
|
|
32
|
+
return base;
|
|
33
|
+
}
|
|
34
|
+
if (typeof base === "object" &&
|
|
35
|
+
base &&
|
|
36
|
+
typeof override === "object" &&
|
|
37
|
+
override &&
|
|
38
|
+
!Array.isArray(base) &&
|
|
39
|
+
!Array.isArray(override)) {
|
|
40
|
+
const merged = { ...base };
|
|
41
|
+
for (const [key, value] of Object.entries(override)) {
|
|
42
|
+
merged[key] = key in merged ? mergeConfigValue(merged[key], value) : value;
|
|
43
|
+
}
|
|
44
|
+
return merged;
|
|
45
|
+
}
|
|
46
|
+
return override;
|
|
47
|
+
}
|
|
48
|
+
export function getRuntimeAgentDefaults(refs) {
|
|
49
|
+
const runtimeDefaults = getRuntimeDefaults(refs);
|
|
50
|
+
const defaults = typeof runtimeDefaults?.defaults === "object" && runtimeDefaults.defaults && !Array.isArray(runtimeDefaults.defaults)
|
|
51
|
+
? runtimeDefaults.defaults
|
|
52
|
+
: undefined;
|
|
53
|
+
const agentDefaults = typeof defaults?.agent === "object" && defaults.agent && !Array.isArray(defaults.agent)
|
|
54
|
+
? defaults.agent
|
|
55
|
+
: undefined;
|
|
56
|
+
const agentConfig = typeof agentDefaults?.config === "object" && agentDefaults.config && !Array.isArray(agentDefaults.config)
|
|
57
|
+
? agentDefaults.config
|
|
58
|
+
: undefined;
|
|
59
|
+
const inlineAgentDefaults = typeof runtimeDefaults?.agent === "object" && runtimeDefaults.agent && !Array.isArray(runtimeDefaults.agent)
|
|
60
|
+
? runtimeDefaults.agent
|
|
61
|
+
: undefined;
|
|
62
|
+
const inlineAgentConfig = typeof inlineAgentDefaults?.config === "object" && inlineAgentDefaults.config && !Array.isArray(inlineAgentDefaults.config)
|
|
63
|
+
? inlineAgentDefaults.config
|
|
64
|
+
: undefined;
|
|
65
|
+
const merged = mergeConfigValue(agentConfig, inlineAgentConfig);
|
|
66
|
+
return typeof merged === "object" && merged && !Array.isArray(merged)
|
|
67
|
+
? merged
|
|
68
|
+
: undefined;
|
|
69
|
+
}
|
|
30
70
|
function asNonEmptyString(value) {
|
|
31
71
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
|
32
72
|
}
|
|
@@ -155,6 +155,8 @@ function normalizeKind(kind) {
|
|
|
155
155
|
return "embedding-model";
|
|
156
156
|
case "VectorStore":
|
|
157
157
|
return "vector-store";
|
|
158
|
+
case "ResponseFormat":
|
|
159
|
+
return "response-format";
|
|
158
160
|
case "Backend":
|
|
159
161
|
return "backend";
|
|
160
162
|
case "Store":
|
|
@@ -219,15 +221,17 @@ async function objectItemsFromDocument(document, sourcePath) {
|
|
|
219
221
|
? normalizeCatalogSpec(document, { defaultKind: "EmbeddingModel" })
|
|
220
222
|
: catalogKind === "VectorStores"
|
|
221
223
|
? normalizeCatalogSpec(document, { defaultKind: "VectorStore" })
|
|
222
|
-
: catalogKind === "
|
|
223
|
-
? normalizeCatalogSpec(document)
|
|
224
|
-
: catalogKind === "
|
|
225
|
-
? normalizeCatalogSpec(document
|
|
226
|
-
: catalogKind === "
|
|
227
|
-
? normalizeCatalogSpec(document, { defaultKind: "
|
|
228
|
-
: catalogKind === "
|
|
229
|
-
? normalizeCatalogSpec(document, { defaultKind: "
|
|
230
|
-
:
|
|
224
|
+
: catalogKind === "ResponseFormats"
|
|
225
|
+
? normalizeCatalogSpec(document, { defaultKind: "ResponseFormat" })
|
|
226
|
+
: catalogKind === "Stores"
|
|
227
|
+
? normalizeCatalogSpec(document)
|
|
228
|
+
: catalogKind === "Backends"
|
|
229
|
+
? normalizeCatalogSpec(document, { defaultKind: "Backend" })
|
|
230
|
+
: catalogKind === "Tools" || catalogKind === "ToolSets"
|
|
231
|
+
? normalizeCatalogSpec(document, { defaultKind: "Tool" })
|
|
232
|
+
: catalogKind === "McpServers"
|
|
233
|
+
? normalizeCatalogSpec(document, { defaultKind: "McpServer" })
|
|
234
|
+
: [];
|
|
231
235
|
if (catalogItems.length > 0) {
|
|
232
236
|
return catalogItems;
|
|
233
237
|
}
|