@botbotgo/agent-harness 0.0.156 → 0.0.158
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 +36 -0
- package/README.zh.md +28 -0
- package/dist/acp.d.ts +86 -0
- package/dist/acp.js +208 -0
- package/dist/api.d.ts +15 -2
- package/dist/api.js +11 -0
- package/dist/contracts/runtime.d.ts +55 -0
- package/dist/flow/build-flow-graph.d.ts +2 -0
- package/dist/flow/build-flow-graph.js +737 -0
- package/dist/flow/export-mermaid.d.ts +2 -0
- package/dist/flow/export-mermaid.js +96 -0
- package/dist/flow/export-sequence-mermaid.d.ts +3 -0
- package/dist/flow/export-sequence-mermaid.js +169 -0
- package/dist/flow/index.d.ts +4 -0
- package/dist/flow/index.js +3 -0
- package/dist/flow/types.d.ts +75 -0
- package/dist/flow/types.js +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +1 -1
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/persistence/file-store.d.ts +1 -0
- package/dist/persistence/file-store.js +10 -1
- package/dist/persistence/types.d.ts +2 -0
- package/dist/runtime/adapter/tool/resolved-tool.d.ts +1 -1
- package/dist/runtime/agent-runtime-adapter.d.ts +5 -1
- package/dist/runtime/agent-runtime-adapter.js +61 -24
- package/dist/runtime/harness/events/streaming.js +6 -0
- package/dist/runtime/harness/run/governance.d.ts +2 -0
- package/dist/runtime/harness/run/governance.js +76 -0
- package/dist/runtime/harness/run/inspection.js +4 -0
- package/dist/runtime/harness/run/stream-run.js +1 -1
- package/dist/runtime/harness/system/policy-engine.d.ts +2 -1
- package/dist/runtime/harness/system/policy-engine.js +5 -1
- package/dist/runtime/harness.d.ts +5 -1
- package/dist/runtime/harness.js +82 -0
- package/dist/workspace/agent-binding-compiler.js +7 -1
- package/package.json +11 -2
|
@@ -159,7 +159,7 @@ function shouldAttachMinimalDeepAgentBackend(binding) {
|
|
|
159
159
|
export class AgentRuntimeAdapter {
|
|
160
160
|
options;
|
|
161
161
|
modelCache = new Map();
|
|
162
|
-
runnableCache = new
|
|
162
|
+
runnableCache = new Map();
|
|
163
163
|
toolNameMappingCache = new WeakMap();
|
|
164
164
|
constructor(options = {}) {
|
|
165
165
|
this.options = options;
|
|
@@ -213,7 +213,12 @@ export class AgentRuntimeAdapter {
|
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
215
|
invalidateBindingRuntimeCaches(binding) {
|
|
216
|
-
|
|
216
|
+
const prefix = `${binding.agent.sourcePath}::`;
|
|
217
|
+
for (const key of Array.from(this.runnableCache.keys())) {
|
|
218
|
+
if (key.startsWith(prefix)) {
|
|
219
|
+
this.runnableCache.delete(key);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
217
222
|
this.modelCache.clear();
|
|
218
223
|
}
|
|
219
224
|
resolveTools(tools, binding) {
|
|
@@ -232,15 +237,19 @@ export class AgentRuntimeAdapter {
|
|
|
232
237
|
this.toolNameMappingCache.set(binding, resolved);
|
|
233
238
|
return resolved;
|
|
234
239
|
}
|
|
235
|
-
resolveFilesystemBackend(binding) {
|
|
240
|
+
resolveFilesystemBackend(binding, options = {}) {
|
|
236
241
|
const filesystemConfig = getBindingFilesystemConfig(binding);
|
|
242
|
+
const sessionStorage = typeof filesystemConfig?.sessionStorage === "object" && filesystemConfig.sessionStorage
|
|
243
|
+
? filesystemConfig.sessionStorage
|
|
244
|
+
: undefined;
|
|
237
245
|
const configuredRootDir = typeof filesystemConfig?.rootDir === "string" && filesystemConfig.rootDir.trim().length > 0
|
|
238
246
|
? filesystemConfig.rootDir
|
|
239
247
|
: undefined;
|
|
240
248
|
const workspaceRoot = binding.harnessRuntime.workspaceRoot;
|
|
241
|
-
const
|
|
249
|
+
const baseRootDir = configuredRootDir
|
|
242
250
|
? (path.isAbsolute(configuredRootDir) ? configuredRootDir : path.resolve(workspaceRoot ?? process.cwd(), configuredRootDir))
|
|
243
251
|
: workspaceRoot ?? process.cwd();
|
|
252
|
+
const rootDir = this.resolveFilesystemRootDir(baseRootDir, binding, sessionStorage, options.threadId);
|
|
244
253
|
return new FilesystemBackend({
|
|
245
254
|
rootDir,
|
|
246
255
|
virtualMode: filesystemConfig?.virtualMode === true,
|
|
@@ -249,6 +258,25 @@ export class AgentRuntimeAdapter {
|
|
|
249
258
|
: 10,
|
|
250
259
|
});
|
|
251
260
|
}
|
|
261
|
+
resolveFilesystemRootDir(baseRootDir, binding, sessionStorage, threadId) {
|
|
262
|
+
const enabled = sessionStorage?.enabled === true;
|
|
263
|
+
if (!enabled || !threadId) {
|
|
264
|
+
return baseRootDir;
|
|
265
|
+
}
|
|
266
|
+
const workspaceRoot = binding.harnessRuntime.workspaceRoot ?? process.cwd();
|
|
267
|
+
const runRoot = binding.harnessRuntime.runRoot;
|
|
268
|
+
const configuredRootDir = typeof sessionStorage.rootDir === "string" && sessionStorage.rootDir.trim().length > 0
|
|
269
|
+
? sessionStorage.rootDir.trim()
|
|
270
|
+
: "{runRoot}/threads/{threadId}/filesystem";
|
|
271
|
+
const rendered = configuredRootDir
|
|
272
|
+
.replaceAll("{threadId}", threadId)
|
|
273
|
+
.replaceAll("{sessionId}", threadId)
|
|
274
|
+
.replaceAll("{agentId}", binding.agent.id)
|
|
275
|
+
.replaceAll("{runRoot}", runRoot)
|
|
276
|
+
.replaceAll("{workspaceRoot}", workspaceRoot)
|
|
277
|
+
.replaceAll("{baseRootDir}", baseRootDir);
|
|
278
|
+
return path.isAbsolute(rendered) ? rendered : path.resolve(workspaceRoot, rendered);
|
|
279
|
+
}
|
|
252
280
|
resolveBuiltinMiddlewareBackend(binding, options = {}) {
|
|
253
281
|
return resolveBuiltinMiddlewareBackendHelper({
|
|
254
282
|
binding,
|
|
@@ -257,7 +285,7 @@ export class AgentRuntimeAdapter {
|
|
|
257
285
|
options,
|
|
258
286
|
});
|
|
259
287
|
}
|
|
260
|
-
createDeclaredMiddlewareResolverOptions(binding) {
|
|
288
|
+
createDeclaredMiddlewareResolverOptions(binding, options = {}) {
|
|
261
289
|
return {
|
|
262
290
|
resolveModel: (model) => this.resolveModel(model),
|
|
263
291
|
resolveBackend: (resolvedBinding) => {
|
|
@@ -266,7 +294,7 @@ export class AgentRuntimeAdapter {
|
|
|
266
294
|
},
|
|
267
295
|
resolveFilesystemBackend: (resolvedBinding) => {
|
|
268
296
|
const targetBinding = resolvedBinding ?? binding;
|
|
269
|
-
return targetBinding ? this.resolveFilesystemBackend(targetBinding) : undefined;
|
|
297
|
+
return targetBinding ? this.resolveFilesystemBackend(targetBinding, { threadId: options.threadId }) : undefined;
|
|
270
298
|
},
|
|
271
299
|
resolveCustom: this.options.declaredMiddlewareResolver,
|
|
272
300
|
binding,
|
|
@@ -276,8 +304,8 @@ export class AgentRuntimeAdapter {
|
|
|
276
304
|
return {
|
|
277
305
|
resolveModel: (model) => this.resolveModel(model),
|
|
278
306
|
resolveTools: (tools, currentBinding) => this.resolveTools(tools, currentBinding),
|
|
279
|
-
resolveFilesystemBackend: (currentBinding) => this.resolveFilesystemBackend(currentBinding),
|
|
280
|
-
createDeclaredMiddlewareResolverOptions: (currentBinding) => this.createDeclaredMiddlewareResolverOptions(currentBinding),
|
|
307
|
+
resolveFilesystemBackend: (currentBinding) => this.resolveFilesystemBackend(currentBinding, { threadId: options.threadId }),
|
|
308
|
+
createDeclaredMiddlewareResolverOptions: (currentBinding) => this.createDeclaredMiddlewareResolverOptions(currentBinding, options),
|
|
281
309
|
resolveBuiltinMiddlewareBackend: (currentBinding, currentOptions = {}) => this.resolveBuiltinMiddlewareBackend(currentBinding, currentOptions),
|
|
282
310
|
resolveSubagents: (subagents, currentBinding) => this.resolveSubagents(subagents, currentBinding),
|
|
283
311
|
invokeBuiltinTaskTool: (currentBinding, toolInput, currentOptions = {}) => this.invokeBuiltinTaskTool(currentBinding, toolInput, currentOptions),
|
|
@@ -313,8 +341,8 @@ export class AgentRuntimeAdapter {
|
|
|
313
341
|
createDeclaredMiddlewareResolverOptions: assembly.createDeclaredMiddlewareResolverOptions,
|
|
314
342
|
});
|
|
315
343
|
}
|
|
316
|
-
async resolveLangChainRuntimeExtensionMiddleware(binding) {
|
|
317
|
-
const assembly = this.createAssemblyResolvers(binding);
|
|
344
|
+
async resolveLangChainRuntimeExtensionMiddleware(binding, options = {}) {
|
|
345
|
+
const assembly = this.createAssemblyResolvers(binding, options);
|
|
318
346
|
return resolveLangChainRuntimeExtensionMiddlewareHelper({
|
|
319
347
|
binding,
|
|
320
348
|
materializeAutomaticSummarizationMiddleware: (currentBinding) => this.materializeAutomaticSummarizationMiddleware(currentBinding),
|
|
@@ -324,14 +352,14 @@ export class AgentRuntimeAdapter {
|
|
|
324
352
|
resolveSubagents: assembly.resolveSubagents,
|
|
325
353
|
});
|
|
326
354
|
}
|
|
327
|
-
async resolveMiddleware(binding, interruptOn) {
|
|
328
|
-
const assembly = this.createAssemblyResolvers(binding);
|
|
355
|
+
async resolveMiddleware(binding, interruptOn, options = {}) {
|
|
356
|
+
const assembly = this.createAssemblyResolvers(binding, options);
|
|
329
357
|
return resolveMiddlewareHelper({
|
|
330
358
|
binding,
|
|
331
359
|
interruptOn,
|
|
332
360
|
runtimeAdapterOptions: this.options,
|
|
333
361
|
createDeclaredMiddlewareResolverOptions: assembly.createDeclaredMiddlewareResolverOptions,
|
|
334
|
-
resolveLangChainRuntimeExtensionMiddleware: (currentBinding) => this.resolveLangChainRuntimeExtensionMiddleware(currentBinding),
|
|
362
|
+
resolveLangChainRuntimeExtensionMiddleware: (currentBinding) => this.resolveLangChainRuntimeExtensionMiddleware(currentBinding, options),
|
|
335
363
|
});
|
|
336
364
|
}
|
|
337
365
|
async resolveSubagents(subagents, binding) {
|
|
@@ -354,7 +382,7 @@ export class AgentRuntimeAdapter {
|
|
|
354
382
|
const interruptOn = resolveRunnableInterruptOn(binding);
|
|
355
383
|
const resolvedModel = await this.resolveModel(primaryModel);
|
|
356
384
|
const resolvedTools = this.resolveTools(primaryTools, binding);
|
|
357
|
-
const resolvedMiddleware = await this.resolveMiddleware(binding, interruptOn);
|
|
385
|
+
const resolvedMiddleware = await this.resolveMiddleware(binding, interruptOn, { threadId: options.threadId });
|
|
358
386
|
const resolvedCheckpointer = resolveRunnableCheckpointer(this.options, binding);
|
|
359
387
|
const resolvedStore = this.options.storeResolver?.(binding);
|
|
360
388
|
const model = resolvedModel;
|
|
@@ -372,12 +400,12 @@ export class AgentRuntimeAdapter {
|
|
|
372
400
|
systemPromptOverride: options.systemPromptOverride,
|
|
373
401
|
}));
|
|
374
402
|
}
|
|
375
|
-
async createRunnable(binding) {
|
|
403
|
+
async createRunnable(binding, options = {}) {
|
|
376
404
|
if (getBindingAdapterKind(binding) === "langgraph") {
|
|
377
405
|
throw new Error(`Agent ${binding.agent.id} uses removed backend langgraph; use langchain-v1 or deepagent`);
|
|
378
406
|
}
|
|
379
407
|
if (isLangChainBinding(binding)) {
|
|
380
|
-
return this.createLangChainRunnable(binding);
|
|
408
|
+
return this.createLangChainRunnable(binding, { threadId: options.threadId });
|
|
381
409
|
}
|
|
382
410
|
return this.createDeepAgentRunnable(binding);
|
|
383
411
|
}
|
|
@@ -425,25 +453,34 @@ export class AgentRuntimeAdapter {
|
|
|
425
453
|
});
|
|
426
454
|
return createDeepAgent(deepAgentConfig);
|
|
427
455
|
}
|
|
428
|
-
|
|
429
|
-
const
|
|
456
|
+
buildRunnableCacheKey(binding, threadId) {
|
|
457
|
+
const filesystemConfig = getBindingFilesystemConfig(binding);
|
|
458
|
+
const sessionStorage = typeof filesystemConfig?.sessionStorage === "object" && filesystemConfig.sessionStorage
|
|
459
|
+
? filesystemConfig.sessionStorage
|
|
460
|
+
: undefined;
|
|
461
|
+
const sessionScoped = sessionStorage?.enabled === true;
|
|
462
|
+
return `${binding.agent.sourcePath}::${sessionScoped ? (threadId ?? "__default__") : "__binding__"}`;
|
|
463
|
+
}
|
|
464
|
+
async create(binding, options = {}) {
|
|
465
|
+
const cacheKey = this.buildRunnableCacheKey(binding, options.threadId);
|
|
466
|
+
const cached = this.runnableCache.get(cacheKey);
|
|
430
467
|
if (cached) {
|
|
431
468
|
return cached;
|
|
432
469
|
}
|
|
433
|
-
const pending = this.createRunnable(binding);
|
|
434
|
-
this.runnableCache.set(
|
|
470
|
+
const pending = this.createRunnable(binding, options);
|
|
471
|
+
this.runnableCache.set(cacheKey, pending);
|
|
435
472
|
try {
|
|
436
473
|
return await pending;
|
|
437
474
|
}
|
|
438
475
|
catch (error) {
|
|
439
|
-
this.runnableCache.delete(
|
|
476
|
+
this.runnableCache.delete(cacheKey);
|
|
440
477
|
throw error;
|
|
441
478
|
}
|
|
442
479
|
}
|
|
443
480
|
async invoke(binding, input, threadId, runId, resumePayload, history = [], options = {}) {
|
|
444
481
|
const callRuntime = async (activeBinding, activeRequest) => {
|
|
445
482
|
return this.invokeWithProviderRetry(activeBinding, async () => {
|
|
446
|
-
const runnable = await this.create(activeBinding);
|
|
483
|
+
const runnable = await this.create(activeBinding, { threadId });
|
|
447
484
|
return (await this.withTimeout(() => runnable.invoke(activeRequest, resolveLangChainInvocationConfig(activeBinding, {
|
|
448
485
|
threadId,
|
|
449
486
|
runId,
|
|
@@ -469,7 +506,7 @@ export class AgentRuntimeAdapter {
|
|
|
469
506
|
invokeOptions: options,
|
|
470
507
|
resolveTools: (tools, currentBinding) => this.resolveTools(tools, currentBinding),
|
|
471
508
|
getToolNameMapping: (currentBinding) => this.getToolNameMapping(currentBinding),
|
|
472
|
-
resolveBuiltinMiddlewareTools: (currentBinding, currentOptions) => this.resolveBuiltinMiddlewareTools(currentBinding, currentOptions),
|
|
509
|
+
resolveBuiltinMiddlewareTools: (currentBinding, currentOptions) => this.resolveBuiltinMiddlewareTools(currentBinding, { ...currentOptions, threadId }),
|
|
473
510
|
callRuntimeWithToolParseRecovery,
|
|
474
511
|
});
|
|
475
512
|
}
|
|
@@ -494,7 +531,7 @@ export class AgentRuntimeAdapter {
|
|
|
494
531
|
forceInvokeFallback,
|
|
495
532
|
canUseDirectModelStream,
|
|
496
533
|
langChainStreamModel,
|
|
497
|
-
createRunnable: () => this.create(binding),
|
|
534
|
+
createRunnable: () => this.create(binding, { threadId }),
|
|
498
535
|
withTimeout: (producer, timeoutMs, operation, stage) => this.withTimeout(producer, timeoutMs, operation, stage),
|
|
499
536
|
iterateWithTimeout: (iterable, timeoutMs, operation, deadlineAt, deadlineTimeoutMs) => this.iterateWithTimeout(iterable, timeoutMs, operation, deadlineAt, deadlineTimeoutMs),
|
|
500
537
|
invokeTimeoutMs: computeRemainingTimeoutMs(streamDeadlineAt, invokeTimeoutMs),
|
|
@@ -42,6 +42,12 @@ export async function dispatchRunListeners(stream, listeners, options) {
|
|
|
42
42
|
}
|
|
43
43
|
if (item.type === "upstream-event") {
|
|
44
44
|
await options.notifyListener(listeners.onUpstreamEvent, item.event);
|
|
45
|
+
await options.notifyListener(listeners.onUpstreamItem, {
|
|
46
|
+
threadId: item.threadId,
|
|
47
|
+
runId: item.runId,
|
|
48
|
+
agentId: item.agentId,
|
|
49
|
+
event: item.event,
|
|
50
|
+
});
|
|
45
51
|
continue;
|
|
46
52
|
}
|
|
47
53
|
if (item.type === "result") {
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { getBindingPrimaryTools } from "../../support/compiled-binding.js";
|
|
2
|
+
import { toolRequiresRuntimeApproval } from "../../adapter/tool/tool-hitl.js";
|
|
3
|
+
const WRITE_LIKE_PATTERN = /\b(write|edit|delete|create|update|append|insert|push|commit|publish|send|post|apply|merge|sync|upload|save)\b/i;
|
|
4
|
+
function inputHints(binding, tool) {
|
|
5
|
+
const hints = new Set();
|
|
6
|
+
const target = `${tool.name} ${tool.description}`.toLowerCase();
|
|
7
|
+
if (/(path|file|dir|directory|folder|workspace|repo|repository)/.test(target)) {
|
|
8
|
+
hints.add("filesystem-scope");
|
|
9
|
+
}
|
|
10
|
+
if (/(memory|knowledge|store|recall)/.test(target)) {
|
|
11
|
+
hints.add("memory-scope");
|
|
12
|
+
}
|
|
13
|
+
if (tool.config?.mcp) {
|
|
14
|
+
hints.add("remote-mcp");
|
|
15
|
+
}
|
|
16
|
+
if (binding.agent.executionMode === "deepagent") {
|
|
17
|
+
hints.add("delegated-runtime");
|
|
18
|
+
}
|
|
19
|
+
return Array.from(hints);
|
|
20
|
+
}
|
|
21
|
+
function classifyRisk(policy) {
|
|
22
|
+
if (policy.requiresApproval) {
|
|
23
|
+
return "high";
|
|
24
|
+
}
|
|
25
|
+
const target = `${policy.toolName} ${policy.description}`;
|
|
26
|
+
if (policy.toolType === "mcp" && WRITE_LIKE_PATTERN.test(target)) {
|
|
27
|
+
return "high";
|
|
28
|
+
}
|
|
29
|
+
if (policy.toolType === "backend" || policy.toolType === "mcp") {
|
|
30
|
+
return "medium";
|
|
31
|
+
}
|
|
32
|
+
return "low";
|
|
33
|
+
}
|
|
34
|
+
function toCategory(toolType) {
|
|
35
|
+
if (toolType === "mcp") {
|
|
36
|
+
return "mcp";
|
|
37
|
+
}
|
|
38
|
+
if (toolType === "backend") {
|
|
39
|
+
return "backend";
|
|
40
|
+
}
|
|
41
|
+
if (toolType === "provider") {
|
|
42
|
+
return "provider-native";
|
|
43
|
+
}
|
|
44
|
+
return "local";
|
|
45
|
+
}
|
|
46
|
+
export function buildRuntimeGovernanceBundles(binding) {
|
|
47
|
+
const toolPolicies = getBindingPrimaryTools(binding).map((tool) => {
|
|
48
|
+
const requiresApproval = toolRequiresRuntimeApproval(tool);
|
|
49
|
+
return {
|
|
50
|
+
toolName: tool.name,
|
|
51
|
+
toolId: tool.id,
|
|
52
|
+
toolType: tool.type,
|
|
53
|
+
category: toCategory(tool.type),
|
|
54
|
+
risk: classifyRisk({
|
|
55
|
+
toolType: tool.type,
|
|
56
|
+
requiresApproval,
|
|
57
|
+
toolName: tool.name,
|
|
58
|
+
description: tool.description,
|
|
59
|
+
config: tool.config,
|
|
60
|
+
}),
|
|
61
|
+
requiresApproval,
|
|
62
|
+
approvalPolicy: tool.hitl?.enabled === true ? "explicit-hitl" : requiresApproval ? "runtime-default" : "none",
|
|
63
|
+
hasInputSchema: typeof tool.inputSchemaRef === "string" && tool.inputSchemaRef.trim().length > 0,
|
|
64
|
+
inputRiskHints: inputHints(binding, tool),
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
if (toolPolicies.length === 0) {
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
return [{
|
|
71
|
+
bundleId: `governance/${binding.agent.id}`,
|
|
72
|
+
title: "Runtime tool governance",
|
|
73
|
+
summary: `${toolPolicies.filter((tool) => tool.requiresApproval).length} of ${toolPolicies.length} tool(s) require approval`,
|
|
74
|
+
toolPolicies,
|
|
75
|
+
}];
|
|
76
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readSkillMetadata } from "../../support/skill-metadata.js";
|
|
2
2
|
import { getBindingMemorySources, getBindingPrimaryModel, getBindingPrimaryTools, getBindingSkills, getBindingSubagents, } from "../../support/compiled-binding.js";
|
|
3
|
+
import { buildRuntimeGovernanceBundles } from "./governance.js";
|
|
3
4
|
function asObject(value) {
|
|
4
5
|
return typeof value === "object" && value !== null ? value : null;
|
|
5
6
|
}
|
|
@@ -67,6 +68,9 @@ export function buildRunRuntimeSnapshot(binding, options) {
|
|
|
67
68
|
};
|
|
68
69
|
}),
|
|
69
70
|
memory: getBindingMemorySources(binding),
|
|
71
|
+
governance: {
|
|
72
|
+
bundles: buildRuntimeGovernanceBundles(binding),
|
|
73
|
+
},
|
|
70
74
|
...(tracing ? { tracing } : {}),
|
|
71
75
|
};
|
|
72
76
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { CompiledAgentBinding } from "../../../contracts/types.js";
|
|
1
|
+
import type { CompiledAgentBinding, RuntimeGovernanceBundle } from "../../../contracts/types.js";
|
|
2
2
|
export type PolicyEngineDecision = {
|
|
3
3
|
allowed: boolean;
|
|
4
4
|
reasons: string[];
|
|
5
|
+
bundles?: RuntimeGovernanceBundle[];
|
|
5
6
|
};
|
|
6
7
|
export declare class PolicyEngine {
|
|
7
8
|
/**
|
|
@@ -7,6 +7,7 @@ export class PolicyEngine {
|
|
|
7
7
|
*/
|
|
8
8
|
evaluate(binding) {
|
|
9
9
|
const reasons = [];
|
|
10
|
+
const bundles = [];
|
|
10
11
|
let allowed = true;
|
|
11
12
|
for (const evaluator of getPolicyEvaluators()) {
|
|
12
13
|
const decision = evaluator.evaluate(binding);
|
|
@@ -17,8 +18,11 @@ export class PolicyEngine {
|
|
|
17
18
|
allowed = false;
|
|
18
19
|
}
|
|
19
20
|
reasons.push(...decision.reasons);
|
|
21
|
+
if (Array.isArray(decision.bundles)) {
|
|
22
|
+
bundles.push(...decision.bundles);
|
|
23
|
+
}
|
|
20
24
|
}
|
|
21
|
-
return { allowed, reasons };
|
|
25
|
+
return bundles.length > 0 ? { allowed, reasons, bundles } : { allowed, reasons };
|
|
22
26
|
}
|
|
23
27
|
}
|
|
24
28
|
export { PolicyEngine as GovernanceEngine, };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ApprovalRecord, CancelOptions, HarnessEvent, HarnessStreamItem, RuntimeHealthSnapshot, ListMemoriesInput, ListMemoriesResult, MessageContent, RemoveMemoryInput, RunRecord, RunStartOptions, RestartConversationOptions, RuntimeAdapterOptions, ResumeOptions, RunOptions, RunResult, RunSummary, MemoryRecord, MemorizeInput, MemorizeResult, RecallInput, RecallResult, UpdateMemoryInput, ThreadSummary, ThreadRecord, WorkspaceBundle } from "../contracts/types.js";
|
|
1
|
+
import type { ApprovalRecord, ArtifactListing, CancelOptions, HarnessEvent, HarnessStreamItem, RuntimeHealthSnapshot, ListMemoriesInput, ListMemoriesResult, MessageContent, RemoveMemoryInput, RunRecord, RunStartOptions, RestartConversationOptions, RuntimeAdapterOptions, RuntimeEvaluationExport, RuntimeEvaluationExportInput, ResumeOptions, RunOptions, RunResult, RunSummary, MemoryRecord, MemorizeInput, MemorizeResult, RecallInput, RecallResult, UpdateMemoryInput, ThreadSummary, ThreadRecord, WorkspaceBundle } from "../contracts/types.js";
|
|
2
2
|
import { type ToolMcpServerOptions } from "../mcp.js";
|
|
3
3
|
import { type InventoryAgentRecord, type InventorySkillRecord } from "./harness/system/inventory.js";
|
|
4
4
|
import type { RequirementAssessmentOptions } from "./harness/system/skill-requirements.js";
|
|
@@ -82,6 +82,10 @@ export declare class AgentHarnessRuntime {
|
|
|
82
82
|
runId?: string;
|
|
83
83
|
}): Promise<ApprovalRecord[]>;
|
|
84
84
|
getApproval(approvalId: string): Promise<ApprovalRecord | null>;
|
|
85
|
+
listArtifacts(threadId: string, runId: string): Promise<ArtifactListing>;
|
|
86
|
+
readArtifact(threadId: string, runId: string, artifactPath: string): Promise<unknown>;
|
|
87
|
+
listRunEvents(threadId: string, runId: string): Promise<HarnessEvent[]>;
|
|
88
|
+
exportEvaluationBundle(input: RuntimeEvaluationExportInput): Promise<RuntimeEvaluationExport>;
|
|
85
89
|
listAgentSkills(agentId: string, options?: RequirementAssessmentOptions): InventorySkillRecord[];
|
|
86
90
|
getAgent(agentId: string, options?: RequirementAssessmentOptions): InventoryAgentRecord | null;
|
|
87
91
|
describeWorkspaceInventory(options?: RequirementAssessmentOptions): {
|
package/dist/runtime/harness.js
CHANGED
|
@@ -475,6 +475,51 @@ export class AgentHarnessRuntime {
|
|
|
475
475
|
persistence: this.persistence,
|
|
476
476
|
}, approvalId);
|
|
477
477
|
}
|
|
478
|
+
async listArtifacts(threadId, runId) {
|
|
479
|
+
return this.persistence.listArtifacts(threadId, runId);
|
|
480
|
+
}
|
|
481
|
+
async readArtifact(threadId, runId, artifactPath) {
|
|
482
|
+
return this.persistence.readArtifact(threadId, runId, artifactPath);
|
|
483
|
+
}
|
|
484
|
+
async listRunEvents(threadId, runId) {
|
|
485
|
+
return this.persistence.listRunEvents(threadId, runId);
|
|
486
|
+
}
|
|
487
|
+
async exportEvaluationBundle(input) {
|
|
488
|
+
const thread = await this.getThread(input.sessionId);
|
|
489
|
+
const run = await this.getRun(input.requestId);
|
|
490
|
+
const approvals = await this.listApprovals({ threadId: input.sessionId, runId: input.requestId });
|
|
491
|
+
const transcript = await this.persistence.listThreadMessages(input.sessionId, 500);
|
|
492
|
+
const events = await this.persistence.listRunEvents(input.sessionId, input.requestId);
|
|
493
|
+
const runtimeHealth = await this.getHealth();
|
|
494
|
+
const artifactsListing = input.includeArtifacts === false
|
|
495
|
+
? { items: [] }
|
|
496
|
+
: await this.persistence.listArtifacts(input.sessionId, input.requestId);
|
|
497
|
+
const artifacts = await Promise.all(artifactsListing.items.map(async (artifact) => ({
|
|
498
|
+
...artifact,
|
|
499
|
+
...(input.includeArtifactContents === true
|
|
500
|
+
? { content: await this.persistence.readArtifact(input.sessionId, input.requestId, artifact.path) }
|
|
501
|
+
: {}),
|
|
502
|
+
})));
|
|
503
|
+
return {
|
|
504
|
+
session: thread ? toSessionRecord(thread) : null,
|
|
505
|
+
request: run ? toRequestRecord(run) : null,
|
|
506
|
+
approvals,
|
|
507
|
+
transcript,
|
|
508
|
+
events,
|
|
509
|
+
artifacts,
|
|
510
|
+
runtimeHealth,
|
|
511
|
+
...(typeof input.expectedOutput === "string" && input.expectedOutput.trim().length > 0
|
|
512
|
+
? { expectedOutput: input.expectedOutput.trim() }
|
|
513
|
+
: {}),
|
|
514
|
+
rubric: Array.isArray(input.rubric)
|
|
515
|
+
? input.rubric.filter((item) => typeof item === "string" && item.trim().length > 0).map((item) => item.trim())
|
|
516
|
+
: [],
|
|
517
|
+
tags: Array.isArray(input.tags)
|
|
518
|
+
? input.tags.filter((item) => typeof item === "string" && item.trim().length > 0).map((item) => item.trim())
|
|
519
|
+
: [],
|
|
520
|
+
...(input.metadata ? { metadata: { ...input.metadata } } : {}),
|
|
521
|
+
};
|
|
522
|
+
}
|
|
478
523
|
listAgentSkills(agentId, options = {}) {
|
|
479
524
|
return listWorkspaceAgentSkills(this.workspace, agentId, {
|
|
480
525
|
assessRequirements: isInventoryEnabled(this.workspace),
|
|
@@ -1393,3 +1438,40 @@ export class AgentHarnessRuntime {
|
|
|
1393
1438
|
}, thread, nowMs);
|
|
1394
1439
|
}
|
|
1395
1440
|
}
|
|
1441
|
+
function toRequestSummary(summary) {
|
|
1442
|
+
return {
|
|
1443
|
+
requestId: summary.runId,
|
|
1444
|
+
sessionId: summary.threadId,
|
|
1445
|
+
agentId: summary.agentId,
|
|
1446
|
+
executionMode: summary.executionMode,
|
|
1447
|
+
adapterKind: summary.adapterKind,
|
|
1448
|
+
createdAt: summary.createdAt,
|
|
1449
|
+
updatedAt: summary.updatedAt,
|
|
1450
|
+
state: summary.state,
|
|
1451
|
+
checkpointRef: summary.checkpointRef,
|
|
1452
|
+
resumable: summary.resumable,
|
|
1453
|
+
startedAt: summary.startedAt,
|
|
1454
|
+
endedAt: summary.endedAt,
|
|
1455
|
+
lastActivityAt: summary.lastActivityAt,
|
|
1456
|
+
currentAgentId: summary.currentAgentId,
|
|
1457
|
+
delegationChain: summary.delegationChain,
|
|
1458
|
+
runtimeSnapshot: summary.runtimeSnapshot,
|
|
1459
|
+
};
|
|
1460
|
+
}
|
|
1461
|
+
function toSessionRecord(record) {
|
|
1462
|
+
return {
|
|
1463
|
+
sessionId: record.threadId,
|
|
1464
|
+
entryAgentId: record.entryAgentId,
|
|
1465
|
+
currentAgentId: record.currentAgentId,
|
|
1466
|
+
currentState: record.currentState,
|
|
1467
|
+
latestRequestId: record.latestRunId,
|
|
1468
|
+
createdAt: record.createdAt,
|
|
1469
|
+
updatedAt: record.updatedAt,
|
|
1470
|
+
messages: record.messages,
|
|
1471
|
+
requests: record.runs.map(toRequestSummary),
|
|
1472
|
+
pendingDecision: record.pendingDecision,
|
|
1473
|
+
};
|
|
1474
|
+
}
|
|
1475
|
+
function toRequestRecord(record) {
|
|
1476
|
+
return toRequestSummary(record);
|
|
1477
|
+
}
|
|
@@ -337,6 +337,12 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
|
|
|
337
337
|
const store = resolveStoreConfig(agent, refs);
|
|
338
338
|
const checkpointer = resolveCheckpointerConfig(agent, refs);
|
|
339
339
|
const runtimeMemory = resolveRuntimeMemoryConfig(agent, refs);
|
|
340
|
+
const runtimeFilesystemDefaults = agent.executionMode === "langchain-v1"
|
|
341
|
+
? asObject(runtimeDefaults?.filesystem)
|
|
342
|
+
: undefined;
|
|
343
|
+
const compiledFilesystemConfig = agent.executionMode === "langchain-v1"
|
|
344
|
+
? mergeConfigObjects(runtimeFilesystemDefaults, getAgentExecutionObject(agent, "filesystem", { executionMode: "langchain-v1" }))
|
|
345
|
+
: undefined;
|
|
340
346
|
const runRoot = typeof agent.runRoot === "string" && agent.runRoot.trim().length > 0
|
|
341
347
|
? path.resolve(workspaceRoot, agent.runRoot)
|
|
342
348
|
: typeof runtimeDefaults?.runRoot === "string" && runtimeDefaults.runRoot.trim().length > 0
|
|
@@ -362,7 +368,7 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
|
|
|
362
368
|
langchain: {
|
|
363
369
|
passthrough,
|
|
364
370
|
interruptOn: resolveInterruptOn(agent),
|
|
365
|
-
filesystem:
|
|
371
|
+
filesystem: compiledFilesystemConfig,
|
|
366
372
|
subagents: compileSubagents(agent, agents, workspaceRoot, models, tools, compiledAgentSkills, compiledAgentModel),
|
|
367
373
|
memory: compiledAgentMemory,
|
|
368
374
|
skills: compiledAgentSkills,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@botbotgo/agent-harness",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.158",
|
|
4
4
|
"description": "Workspace runtime for multi-agent applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "npm@10.9.2",
|
|
@@ -28,6 +28,11 @@
|
|
|
28
28
|
"import": "./dist/index.js",
|
|
29
29
|
"default": "./dist/index.js"
|
|
30
30
|
},
|
|
31
|
+
"./acp": {
|
|
32
|
+
"types": "./dist/acp.d.ts",
|
|
33
|
+
"import": "./dist/acp.js",
|
|
34
|
+
"default": "./dist/acp.js"
|
|
35
|
+
},
|
|
31
36
|
"./tools": {
|
|
32
37
|
"types": "./dist/tools.d.ts",
|
|
33
38
|
"import": "./dist/tools.js",
|
|
@@ -54,7 +59,7 @@
|
|
|
54
59
|
"mem0ai": "^2.4.4",
|
|
55
60
|
"mustache": "^4.2.0",
|
|
56
61
|
"yaml": "^2.8.1",
|
|
57
|
-
"zod": "^3.
|
|
62
|
+
"zod": "^4.3.6"
|
|
58
63
|
},
|
|
59
64
|
"scripts": {
|
|
60
65
|
"build": "rm -rf dist tsconfig.tsbuildinfo && tsc -p tsconfig.json && cp -R config dist/",
|
|
@@ -70,5 +75,9 @@
|
|
|
70
75
|
"@types/node": "^24.6.0",
|
|
71
76
|
"typescript": "^5.9.3",
|
|
72
77
|
"vitest": "^3.2.4"
|
|
78
|
+
},
|
|
79
|
+
"overrides": {
|
|
80
|
+
"@browserbasehq/stagehand": "3.2.0",
|
|
81
|
+
"openai": "6.33.0"
|
|
73
82
|
}
|
|
74
83
|
}
|