@botbotgo/agent-harness 0.0.124 → 0.0.126
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 +12 -12
- package/README.zh.md +11 -11
- package/dist/api.d.ts +49 -11
- package/dist/api.js +131 -15
- package/dist/benchmark/upstream-runtime-ab-benchmark.d.ts +32 -2
- package/dist/benchmark/upstream-runtime-ab-benchmark.js +58 -2
- package/dist/contracts/runtime.d.ts +46 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/runtime/agent-runtime-adapter.d.ts +3 -3
- package/dist/runtime/agent-runtime-adapter.js +31 -7
- package/dist/runtime/harness/run/helpers.d.ts +1 -1
- package/dist/runtime/harness/run/helpers.js +1 -1
- package/dist/runtime/harness/run/stream-run.js +1 -8
- package/dist/runtime/harness/run/thread-records.d.ts +1 -1
- package/dist/runtime/harness/run/thread-records.js +10 -7
- package/dist/runtime/harness.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -281,9 +281,9 @@ const result = await run(runtime, {
|
|
|
281
281
|
});
|
|
282
282
|
```
|
|
283
283
|
|
|
284
|
-
`run(runtime, { ... })` creates or continues a persisted
|
|
284
|
+
`run(runtime, { ... })` creates or continues a persisted session and returns `sessionId`, `requestId`, `state`, and compact text `output`. Richer upstream result shapes stay available through `outputContent`, `contentBlocks`, and `structuredResponse`.
|
|
285
285
|
|
|
286
|
-
Use `
|
|
286
|
+
Use `listRequests(runtime)` and `getRequest(runtime, requestId)` when a product needs a request-centric operations surface such as a review queue or execution dashboard.
|
|
287
287
|
|
|
288
288
|
Use `invocation` as the runtime-facing request envelope:
|
|
289
289
|
|
|
@@ -334,19 +334,19 @@ The runtime event stream includes:
|
|
|
334
334
|
- `approval.resolved`
|
|
335
335
|
- `output.delta`
|
|
336
336
|
|
|
337
|
-
### Inspect
|
|
337
|
+
### Inspect Sessions And Approvals
|
|
338
338
|
|
|
339
339
|
```ts
|
|
340
340
|
import {
|
|
341
|
+
getSession,
|
|
341
342
|
getApproval,
|
|
342
|
-
|
|
343
|
+
listSessions,
|
|
343
344
|
listApprovals,
|
|
344
|
-
listThreads,
|
|
345
345
|
resolveApproval,
|
|
346
346
|
} from "@botbotgo/agent-harness";
|
|
347
347
|
|
|
348
|
-
const
|
|
349
|
-
const
|
|
348
|
+
const sessions = await listSessions(runtime);
|
|
349
|
+
const session = await getSession(runtime, sessions[0]!.sessionId);
|
|
350
350
|
const approvals = await listApprovals(runtime, { status: "pending" });
|
|
351
351
|
const approval = approvals[0] ? await getApproval(runtime, approvals[0].approvalId) : null;
|
|
352
352
|
|
|
@@ -690,11 +690,11 @@ Primary exports:
|
|
|
690
690
|
- `run`
|
|
691
691
|
- `resolveApproval`
|
|
692
692
|
- `subscribe`
|
|
693
|
-
- `
|
|
694
|
-
- `
|
|
695
|
-
- `
|
|
696
|
-
- `
|
|
697
|
-
- `
|
|
693
|
+
- `listRequests`
|
|
694
|
+
- `getRequest`
|
|
695
|
+
- `listSessions`
|
|
696
|
+
- `getSession`
|
|
697
|
+
- `deleteSession`
|
|
698
698
|
- `listApprovals`
|
|
699
699
|
- `getApproval`
|
|
700
700
|
- `createToolMcpServer`
|
package/README.zh.md
CHANGED
|
@@ -281,9 +281,9 @@ const result = await run(runtime, {
|
|
|
281
281
|
});
|
|
282
282
|
```
|
|
283
283
|
|
|
284
|
-
`run(runtime, { ... })`
|
|
284
|
+
`run(runtime, { ... })` 会创建或延续持久化会话,并返回 `sessionId`、`requestId`、`state` 以及紧凑文本 `output`。更丰富的上游结果形态仍可通过 `outputContent`、`contentBlocks`、`structuredResponse` 等获得。
|
|
285
285
|
|
|
286
|
-
如果产品需要
|
|
286
|
+
如果产品需要 request 视角的操作界面,例如 review queue 或执行看板,可使用 `listRequests(runtime)` 与 `getRequest(runtime, requestId)`。
|
|
287
287
|
|
|
288
288
|
将 `invocation` 作为面向运行时的请求信封:
|
|
289
289
|
|
|
@@ -339,14 +339,14 @@ const result = await run(runtime, {
|
|
|
339
339
|
```ts
|
|
340
340
|
import {
|
|
341
341
|
getApproval,
|
|
342
|
-
|
|
342
|
+
getSession,
|
|
343
343
|
listApprovals,
|
|
344
|
-
|
|
344
|
+
listSessions,
|
|
345
345
|
resolveApproval,
|
|
346
346
|
} from "@botbotgo/agent-harness";
|
|
347
347
|
|
|
348
|
-
const
|
|
349
|
-
const
|
|
348
|
+
const sessions = await listSessions(runtime);
|
|
349
|
+
const session = await getSession(runtime, sessions[0]!.sessionId);
|
|
350
350
|
const approvals = await listApprovals(runtime, { status: "pending" });
|
|
351
351
|
const approval = approvals[0] ? await getApproval(runtime, approvals[0].approvalId) : null;
|
|
352
352
|
|
|
@@ -687,11 +687,11 @@ spec:
|
|
|
687
687
|
- `run`
|
|
688
688
|
- `resolveApproval`
|
|
689
689
|
- `subscribe`
|
|
690
|
-
- `
|
|
691
|
-
- `
|
|
692
|
-
- `
|
|
693
|
-
- `
|
|
694
|
-
- `
|
|
690
|
+
- `listRequests`
|
|
691
|
+
- `getRequest`
|
|
692
|
+
- `listSessions`
|
|
693
|
+
- `getSession`
|
|
694
|
+
- `deleteSession`
|
|
695
695
|
- `listApprovals`
|
|
696
696
|
- `getApproval`
|
|
697
697
|
- `createToolMcpServer`
|
package/dist/api.d.ts
CHANGED
|
@@ -1,10 +1,39 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CancelOptions, RequestRecord, RequestSummary, ResumeOptions, RunDecisionOptions, RunResult, RunStartOptions, RuntimeHealthSnapshot, RuntimeAdapterOptions, SessionRecord, SessionSummary, WorkspaceLoadOptions } from "./contracts/types.js";
|
|
2
2
|
import { AgentHarnessRuntime } from "./runtime/harness.js";
|
|
3
3
|
import type { InventoryAgentRecord, InventorySkillRecord } from "./runtime/harness/system/inventory.js";
|
|
4
4
|
import type { RequirementAssessmentOptions } from "./runtime/harness/system/skill-requirements.js";
|
|
5
5
|
import type { ToolMcpServerOptions } from "./mcp.js";
|
|
6
6
|
export { AgentHarnessRuntime } from "./runtime/harness.js";
|
|
7
7
|
export { createUpstreamTimelineReducer } from "./upstream-events.js";
|
|
8
|
+
type PublicApprovalRecord = {
|
|
9
|
+
approvalId: string;
|
|
10
|
+
pendingActionId: string;
|
|
11
|
+
sessionId: string;
|
|
12
|
+
requestId: string;
|
|
13
|
+
toolName: string;
|
|
14
|
+
status: "pending" | "approved" | "edited" | "rejected" | "expired";
|
|
15
|
+
requestedAt: string;
|
|
16
|
+
resolvedAt: string | null;
|
|
17
|
+
allowedDecisions: Array<"approve" | "edit" | "reject">;
|
|
18
|
+
inputPreview: Record<string, unknown>;
|
|
19
|
+
};
|
|
20
|
+
type PublicApprovalFilter = {
|
|
21
|
+
status?: PublicApprovalRecord["status"];
|
|
22
|
+
sessionId?: string;
|
|
23
|
+
requestId?: string;
|
|
24
|
+
};
|
|
25
|
+
type PublicRunStartOptions = Omit<RunStartOptions, "threadId"> & {
|
|
26
|
+
sessionId?: string;
|
|
27
|
+
};
|
|
28
|
+
type PublicRunDecisionOptions = Omit<RunDecisionOptions, "threadId" | "runId"> & {
|
|
29
|
+
sessionId: string;
|
|
30
|
+
requestId?: string;
|
|
31
|
+
};
|
|
32
|
+
type PublicRunOptions = PublicRunStartOptions | PublicRunDecisionOptions;
|
|
33
|
+
type PublicRunResult = Omit<RunResult, "threadId" | "runId"> & {
|
|
34
|
+
sessionId: string;
|
|
35
|
+
requestId: string;
|
|
36
|
+
};
|
|
8
37
|
type CreateAgentHarnessOptions = {
|
|
9
38
|
/**
|
|
10
39
|
* Workspace loading behavior.
|
|
@@ -15,23 +44,32 @@ type CreateAgentHarnessOptions = {
|
|
|
15
44
|
};
|
|
16
45
|
export declare function createAgentHarness(): Promise<AgentHarnessRuntime>;
|
|
17
46
|
export declare function createAgentHarness(workspaceRoot: string, options?: CreateAgentHarnessOptions): Promise<AgentHarnessRuntime>;
|
|
18
|
-
export declare function run(runtime: AgentHarnessRuntime, options:
|
|
47
|
+
export declare function run(runtime: AgentHarnessRuntime, options: PublicRunOptions): Promise<PublicRunResult>;
|
|
19
48
|
export declare function subscribe(runtime: AgentHarnessRuntime, listener: Parameters<AgentHarnessRuntime["subscribe"]>[0]): () => void;
|
|
20
|
-
export declare function
|
|
21
|
-
export declare function
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
export declare function
|
|
49
|
+
export declare function listSessions(runtime: AgentHarnessRuntime, filter?: Parameters<AgentHarnessRuntime["listThreads"]>[0]): Promise<SessionSummary[]>;
|
|
50
|
+
export declare function listRequests(runtime: AgentHarnessRuntime, filter?: {
|
|
51
|
+
agentId?: string;
|
|
52
|
+
sessionId?: string;
|
|
53
|
+
state?: RequestSummary["state"];
|
|
54
|
+
}): Promise<RequestSummary[]>;
|
|
55
|
+
export declare function getSession(runtime: AgentHarnessRuntime, sessionId: string): Promise<SessionRecord | null>;
|
|
56
|
+
export declare function getRequest(runtime: AgentHarnessRuntime, requestId: string): Promise<RequestRecord | null>;
|
|
57
|
+
export declare function deleteSession(runtime: AgentHarnessRuntime, sessionId: string): Promise<boolean>;
|
|
58
|
+
export declare function listApprovals(runtime: AgentHarnessRuntime, filter?: PublicApprovalFilter): Promise<PublicApprovalRecord[]>;
|
|
59
|
+
export declare function getApproval(runtime: AgentHarnessRuntime, approvalId: string): Promise<PublicApprovalRecord | null>;
|
|
27
60
|
export declare function getHealth(runtime: AgentHarnessRuntime): Promise<RuntimeHealthSnapshot>;
|
|
28
61
|
export declare function listAgentSkills(runtime: AgentHarnessRuntime, agentId: string, options?: RequirementAssessmentOptions): InventorySkillRecord[];
|
|
29
62
|
export declare function describeInventory(runtime: AgentHarnessRuntime, options?: RequirementAssessmentOptions): {
|
|
30
63
|
workspaceRoot: string;
|
|
31
64
|
agents: InventoryAgentRecord[];
|
|
32
65
|
};
|
|
33
|
-
export declare function resolveApproval(runtime: AgentHarnessRuntime, options: ResumeOptions
|
|
34
|
-
|
|
66
|
+
export declare function resolveApproval(runtime: AgentHarnessRuntime, options: ResumeOptions & {
|
|
67
|
+
sessionId?: string;
|
|
68
|
+
requestId?: string;
|
|
69
|
+
}): Promise<PublicRunResult>;
|
|
70
|
+
export declare function cancelRun(runtime: AgentHarnessRuntime, options: CancelOptions & {
|
|
71
|
+
requestId?: string;
|
|
72
|
+
}): Promise<RunResult>;
|
|
35
73
|
export declare function stop(runtime: AgentHarnessRuntime): Promise<void>;
|
|
36
74
|
export declare function createToolMcpServer(runtime: AgentHarnessRuntime, options: ToolMcpServerOptions): Promise<import("@modelcontextprotocol/sdk/server/mcp.js").McpServer>;
|
|
37
75
|
export declare function serveToolsOverStdio(runtime: AgentHarnessRuntime, options: ToolMcpServerOptions): Promise<import("@modelcontextprotocol/sdk/server/mcp.js").McpServer>;
|
package/dist/api.js
CHANGED
|
@@ -2,6 +2,108 @@ import { AgentHarnessRuntime } from "./runtime/harness.js";
|
|
|
2
2
|
import { loadWorkspace } from "./workspace/compile.js";
|
|
3
3
|
export { AgentHarnessRuntime } from "./runtime/harness.js";
|
|
4
4
|
export { createUpstreamTimelineReducer } from "./upstream-events.js";
|
|
5
|
+
function toSessionSummary(summary) {
|
|
6
|
+
return {
|
|
7
|
+
agentId: summary.agentId,
|
|
8
|
+
sessionId: summary.threadId,
|
|
9
|
+
latestRequestId: summary.latestRunId,
|
|
10
|
+
createdAt: summary.createdAt,
|
|
11
|
+
updatedAt: summary.updatedAt,
|
|
12
|
+
status: summary.status,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function toRequestSummary(summary) {
|
|
16
|
+
return {
|
|
17
|
+
requestId: summary.runId,
|
|
18
|
+
sessionId: summary.threadId,
|
|
19
|
+
agentId: summary.agentId,
|
|
20
|
+
executionMode: summary.executionMode,
|
|
21
|
+
adapterKind: summary.adapterKind,
|
|
22
|
+
createdAt: summary.createdAt,
|
|
23
|
+
updatedAt: summary.updatedAt,
|
|
24
|
+
state: summary.state,
|
|
25
|
+
checkpointRef: summary.checkpointRef,
|
|
26
|
+
resumable: summary.resumable,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function toSessionRecord(record) {
|
|
30
|
+
return {
|
|
31
|
+
sessionId: record.threadId,
|
|
32
|
+
entryAgentId: record.entryAgentId,
|
|
33
|
+
currentState: record.currentState,
|
|
34
|
+
latestRequestId: record.latestRunId,
|
|
35
|
+
createdAt: record.createdAt,
|
|
36
|
+
updatedAt: record.updatedAt,
|
|
37
|
+
messages: record.messages,
|
|
38
|
+
requests: record.runs.map(toRequestSummary),
|
|
39
|
+
pendingDecision: record.pendingDecision,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function toRequestRecord(record) {
|
|
43
|
+
return toRequestSummary(record);
|
|
44
|
+
}
|
|
45
|
+
function toApprovalRecord(record) {
|
|
46
|
+
return {
|
|
47
|
+
approvalId: record.approvalId,
|
|
48
|
+
pendingActionId: record.pendingActionId,
|
|
49
|
+
sessionId: record.threadId,
|
|
50
|
+
requestId: record.runId,
|
|
51
|
+
toolName: record.toolName,
|
|
52
|
+
status: record.status,
|
|
53
|
+
requestedAt: record.requestedAt,
|
|
54
|
+
resolvedAt: record.resolvedAt,
|
|
55
|
+
allowedDecisions: record.allowedDecisions,
|
|
56
|
+
inputPreview: record.inputPreview,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function toPublicRunResult(result) {
|
|
60
|
+
return {
|
|
61
|
+
sessionId: result.threadId,
|
|
62
|
+
requestId: result.runId,
|
|
63
|
+
state: result.state,
|
|
64
|
+
output: result.output,
|
|
65
|
+
finalMessageText: result.finalMessageText,
|
|
66
|
+
outputContent: result.outputContent,
|
|
67
|
+
contentBlocks: result.contentBlocks,
|
|
68
|
+
structuredResponse: result.structuredResponse,
|
|
69
|
+
interruptContent: result.interruptContent,
|
|
70
|
+
agentId: result.agentId,
|
|
71
|
+
approvalId: result.approvalId,
|
|
72
|
+
pendingActionId: result.pendingActionId,
|
|
73
|
+
delegationId: result.delegationId,
|
|
74
|
+
artifacts: result.artifacts,
|
|
75
|
+
metadata: result.metadata,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function toInternalRunOptions(options) {
|
|
79
|
+
if ("decision" in options) {
|
|
80
|
+
return {
|
|
81
|
+
approvalId: options.approvalId,
|
|
82
|
+
decision: options.decision,
|
|
83
|
+
editedInput: options.editedInput,
|
|
84
|
+
listeners: options.listeners,
|
|
85
|
+
runId: options.requestId,
|
|
86
|
+
threadId: options.sessionId,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
agentId: options.agentId,
|
|
91
|
+
input: options.input,
|
|
92
|
+
invocation: options.invocation,
|
|
93
|
+
listeners: options.listeners,
|
|
94
|
+
priority: options.priority,
|
|
95
|
+
threadId: options.sessionId,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function toInternalResumeOptions(options) {
|
|
99
|
+
return {
|
|
100
|
+
approvalId: options.approvalId,
|
|
101
|
+
decision: options.decision,
|
|
102
|
+
editedInput: options.editedInput,
|
|
103
|
+
runId: options.requestId ?? options.runId,
|
|
104
|
+
threadId: options.sessionId ?? options.threadId,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
5
107
|
export async function createAgentHarness(workspaceRoot = process.cwd(), options = {}) {
|
|
6
108
|
const workspace = await loadWorkspace(workspaceRoot, options.load ?? {});
|
|
7
109
|
const harness = new AgentHarnessRuntime(workspace, options.adapter ?? {});
|
|
@@ -9,31 +111,42 @@ export async function createAgentHarness(workspaceRoot = process.cwd(), options
|
|
|
9
111
|
return harness;
|
|
10
112
|
}
|
|
11
113
|
export async function run(runtime, options) {
|
|
12
|
-
return runtime.run(options);
|
|
114
|
+
return toPublicRunResult(await runtime.run(toInternalRunOptions(options)));
|
|
13
115
|
}
|
|
14
116
|
export function subscribe(runtime, listener) {
|
|
15
117
|
return runtime.subscribe(listener);
|
|
16
118
|
}
|
|
17
|
-
export async function
|
|
18
|
-
return runtime.listThreads(filter);
|
|
119
|
+
export async function listSessions(runtime, filter) {
|
|
120
|
+
return (await runtime.listThreads(filter)).map(toSessionSummary);
|
|
19
121
|
}
|
|
20
|
-
export async function
|
|
21
|
-
return runtime.listRuns(
|
|
122
|
+
export async function listRequests(runtime, filter) {
|
|
123
|
+
return (await runtime.listRuns({
|
|
124
|
+
agentId: filter?.agentId,
|
|
125
|
+
state: filter?.state,
|
|
126
|
+
threadId: filter?.sessionId,
|
|
127
|
+
})).map(toRequestSummary);
|
|
22
128
|
}
|
|
23
|
-
export async function
|
|
24
|
-
|
|
129
|
+
export async function getSession(runtime, sessionId) {
|
|
130
|
+
const record = await runtime.getThread(sessionId);
|
|
131
|
+
return record ? toSessionRecord(record) : null;
|
|
25
132
|
}
|
|
26
|
-
export async function
|
|
27
|
-
|
|
133
|
+
export async function getRequest(runtime, requestId) {
|
|
134
|
+
const record = await runtime.getRun(requestId);
|
|
135
|
+
return record ? toRequestRecord(record) : null;
|
|
28
136
|
}
|
|
29
|
-
export async function
|
|
30
|
-
return runtime.deleteThread(
|
|
137
|
+
export async function deleteSession(runtime, sessionId) {
|
|
138
|
+
return runtime.deleteThread(sessionId);
|
|
31
139
|
}
|
|
32
140
|
export async function listApprovals(runtime, filter) {
|
|
33
|
-
return runtime.listApprovals(
|
|
141
|
+
return (await runtime.listApprovals({
|
|
142
|
+
runId: filter?.requestId,
|
|
143
|
+
status: filter?.status,
|
|
144
|
+
threadId: filter?.sessionId,
|
|
145
|
+
})).map(toApprovalRecord);
|
|
34
146
|
}
|
|
35
147
|
export async function getApproval(runtime, approvalId) {
|
|
36
|
-
|
|
148
|
+
const record = await runtime.getApproval(approvalId);
|
|
149
|
+
return record ? toApprovalRecord(record) : null;
|
|
37
150
|
}
|
|
38
151
|
export async function getHealth(runtime) {
|
|
39
152
|
return runtime.getHealth();
|
|
@@ -45,10 +158,13 @@ export function describeInventory(runtime, options) {
|
|
|
45
158
|
return runtime.describeWorkspaceInventory(options);
|
|
46
159
|
}
|
|
47
160
|
export async function resolveApproval(runtime, options) {
|
|
48
|
-
return runtime.resume(options);
|
|
161
|
+
return toPublicRunResult(await runtime.resume(toInternalResumeOptions(options)));
|
|
49
162
|
}
|
|
50
163
|
export async function cancelRun(runtime, options) {
|
|
51
|
-
return runtime.cancelRun(
|
|
164
|
+
return runtime.cancelRun({
|
|
165
|
+
...options,
|
|
166
|
+
runId: options.requestId ?? options.runId,
|
|
167
|
+
});
|
|
52
168
|
}
|
|
53
169
|
export async function stop(runtime) {
|
|
54
170
|
return runtime.stop();
|
|
@@ -1,15 +1,23 @@
|
|
|
1
|
-
export declare const DEFAULT_UPSTREAM_BENCHMARK_PATHS: readonly ["harness", "raw-langchain-v1", "raw-deepagent"];
|
|
1
|
+
export declare const DEFAULT_UPSTREAM_BENCHMARK_PATHS: readonly ["harness", "harness-minimal-upstream", "raw-langchain-v1", "raw-deepagent"];
|
|
2
2
|
export declare const DEFAULT_UPSTREAM_BENCHMARK_WORKLOAD: "tool";
|
|
3
|
+
export declare const DEFAULT_UPSTREAM_BENCHMARK_SCENARIOS: readonly ["normal", "complex", "extreme"];
|
|
3
4
|
export type UpstreamBenchmarkPath = (typeof DEFAULT_UPSTREAM_BENCHMARK_PATHS)[number];
|
|
4
5
|
export type UpstreamBenchmarkWorkload = "tool" | "no-tool";
|
|
6
|
+
export type UpstreamBenchmarkScenario = (typeof DEFAULT_UPSTREAM_BENCHMARK_SCENARIOS)[number];
|
|
5
7
|
export type UpstreamBenchmarkRunSummary = {
|
|
6
8
|
providerLabel: string;
|
|
7
9
|
model: string;
|
|
10
|
+
scenario: UpstreamBenchmarkScenario;
|
|
8
11
|
path: UpstreamBenchmarkPath;
|
|
9
12
|
runNumber: number;
|
|
10
13
|
status: "completed" | "failed";
|
|
11
14
|
totalMs: number;
|
|
12
15
|
firstTokenMs: number | null;
|
|
16
|
+
setupMs: number | null;
|
|
17
|
+
firstToolMs: number | null;
|
|
18
|
+
lastToolMs: number | null;
|
|
19
|
+
finalOutputMs: number | null;
|
|
20
|
+
cleanupMs: number | null;
|
|
13
21
|
outputLength: number;
|
|
14
22
|
normalizedOutputLength: number;
|
|
15
23
|
toolCallCount: number;
|
|
@@ -19,6 +27,7 @@ export type UpstreamBenchmarkRunSummary = {
|
|
|
19
27
|
export type UpstreamBenchmarkAggregateSummary = {
|
|
20
28
|
providerLabel: string;
|
|
21
29
|
model: string;
|
|
30
|
+
scenario: UpstreamBenchmarkScenario;
|
|
22
31
|
path: UpstreamBenchmarkPath;
|
|
23
32
|
repetitions: number;
|
|
24
33
|
successCount: number;
|
|
@@ -31,6 +40,11 @@ export type UpstreamBenchmarkAggregateSummary = {
|
|
|
31
40
|
trimmedAvgFirstTokenMs: number | null;
|
|
32
41
|
medianFirstTokenMs: number | null;
|
|
33
42
|
p95FirstTokenMs: number | null;
|
|
43
|
+
avgSetupMs: number | null;
|
|
44
|
+
avgFirstToolMs: number | null;
|
|
45
|
+
avgLastToolMs: number | null;
|
|
46
|
+
avgFinalOutputMs: number | null;
|
|
47
|
+
avgCleanupMs: number | null;
|
|
34
48
|
avgOutputLength: number | null;
|
|
35
49
|
avgNormalizedOutputLength: number | null;
|
|
36
50
|
avgToolCallCount: number | null;
|
|
@@ -44,8 +58,24 @@ export type UpstreamBenchmarkComparison = {
|
|
|
44
58
|
avgFirstTokenMsDelta: number | null;
|
|
45
59
|
avgFirstTokenMsOverheadPct: number | null;
|
|
46
60
|
};
|
|
61
|
+
export type UpstreamBenchmarkPhaseCheckpoint = {
|
|
62
|
+
label: string;
|
|
63
|
+
atMs: number | null;
|
|
64
|
+
};
|
|
65
|
+
export type UpstreamBenchmarkTemperature = "cold" | "warm";
|
|
66
|
+
export type UpstreamBenchmarkDurationSummary = {
|
|
67
|
+
count: number;
|
|
68
|
+
totalMs: number;
|
|
69
|
+
avgMs: number | null;
|
|
70
|
+
maxMs: number | null;
|
|
71
|
+
};
|
|
47
72
|
export declare function resolveUpstreamBenchmarkPaths(rawValue?: string): readonly UpstreamBenchmarkPath[];
|
|
48
73
|
export declare function resolveUpstreamBenchmarkWorkload(rawValue?: string): UpstreamBenchmarkWorkload;
|
|
74
|
+
export declare function resolveUpstreamBenchmarkScenarios(rawValue?: string): readonly UpstreamBenchmarkScenario[];
|
|
49
75
|
export declare function extractLastMatchingToken(output: string, prefixes: readonly string[]): string;
|
|
50
|
-
export declare function aggregateUpstreamBenchmarkRuns(providerLabel: string, model: string, path: UpstreamBenchmarkPath, runs: UpstreamBenchmarkRunSummary[]): UpstreamBenchmarkAggregateSummary;
|
|
76
|
+
export declare function aggregateUpstreamBenchmarkRuns(providerLabel: string, model: string, scenario: UpstreamBenchmarkScenario, path: UpstreamBenchmarkPath, runs: UpstreamBenchmarkRunSummary[]): UpstreamBenchmarkAggregateSummary;
|
|
77
|
+
export declare function withUpstreamBenchmarkCleanup(summary: UpstreamBenchmarkRunSummary, cleanupMs: number | null): UpstreamBenchmarkRunSummary;
|
|
78
|
+
export declare function summarizeUpstreamBenchmarkPhases(checkpoints: readonly UpstreamBenchmarkPhaseCheckpoint[]): Record<string, number | null>;
|
|
79
|
+
export declare function selectUpstreamBenchmarkRunsByTemperature(runs: readonly UpstreamBenchmarkRunSummary[], temperature: UpstreamBenchmarkTemperature): UpstreamBenchmarkRunSummary[];
|
|
80
|
+
export declare function summarizeUpstreamBenchmarkDurations(values: readonly number[]): UpstreamBenchmarkDurationSummary;
|
|
51
81
|
export declare function compareUpstreamBenchmarkPaths(baseline: UpstreamBenchmarkAggregateSummary, candidate: UpstreamBenchmarkAggregateSummary): UpstreamBenchmarkComparison;
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
export const DEFAULT_UPSTREAM_BENCHMARK_PATHS = Object.freeze([
|
|
2
2
|
"harness",
|
|
3
|
+
"harness-minimal-upstream",
|
|
3
4
|
"raw-langchain-v1",
|
|
4
5
|
"raw-deepagent",
|
|
5
6
|
]);
|
|
6
7
|
export const DEFAULT_UPSTREAM_BENCHMARK_WORKLOAD = "tool";
|
|
8
|
+
export const DEFAULT_UPSTREAM_BENCHMARK_SCENARIOS = Object.freeze([
|
|
9
|
+
"normal",
|
|
10
|
+
"complex",
|
|
11
|
+
"extreme",
|
|
12
|
+
]);
|
|
7
13
|
function average(values) {
|
|
8
14
|
return Number((values.reduce((sum, value) => sum + value, 0) / values.length).toFixed(2));
|
|
9
15
|
}
|
|
@@ -47,12 +53,25 @@ export function resolveUpstreamBenchmarkPaths(rawValue) {
|
|
|
47
53
|
const parsed = rawValue
|
|
48
54
|
.split(",")
|
|
49
55
|
.map((value) => value.trim().toLowerCase())
|
|
50
|
-
.filter((value) => value === "harness" ||
|
|
56
|
+
.filter((value) => value === "harness" ||
|
|
57
|
+
value === "harness-minimal-upstream" ||
|
|
58
|
+
value === "raw-langchain-v1" ||
|
|
59
|
+
value === "raw-deepagent");
|
|
51
60
|
return parsed.length > 0 ? parsed : [...DEFAULT_UPSTREAM_BENCHMARK_PATHS];
|
|
52
61
|
}
|
|
53
62
|
export function resolveUpstreamBenchmarkWorkload(rawValue) {
|
|
54
63
|
return rawValue?.trim().toLowerCase() === "no-tool" ? "no-tool" : DEFAULT_UPSTREAM_BENCHMARK_WORKLOAD;
|
|
55
64
|
}
|
|
65
|
+
export function resolveUpstreamBenchmarkScenarios(rawValue) {
|
|
66
|
+
if (!rawValue) {
|
|
67
|
+
return [...DEFAULT_UPSTREAM_BENCHMARK_SCENARIOS];
|
|
68
|
+
}
|
|
69
|
+
const parsed = rawValue
|
|
70
|
+
.split(",")
|
|
71
|
+
.map((value) => value.trim().toLowerCase())
|
|
72
|
+
.filter((value) => value === "normal" || value === "complex" || value === "extreme");
|
|
73
|
+
return parsed.length > 0 ? parsed : [...DEFAULT_UPSTREAM_BENCHMARK_SCENARIOS];
|
|
74
|
+
}
|
|
56
75
|
export function extractLastMatchingToken(output, prefixes) {
|
|
57
76
|
const normalized = output.replace(/\s+/g, " ").trim();
|
|
58
77
|
let matched = "";
|
|
@@ -69,7 +88,7 @@ export function extractLastMatchingToken(output, prefixes) {
|
|
|
69
88
|
}
|
|
70
89
|
return matched || normalized;
|
|
71
90
|
}
|
|
72
|
-
export function aggregateUpstreamBenchmarkRuns(providerLabel, model, path, runs) {
|
|
91
|
+
export function aggregateUpstreamBenchmarkRuns(providerLabel, model, scenario, path, runs) {
|
|
73
92
|
const successfulRuns = runs.filter((run) => run.status === "completed");
|
|
74
93
|
const totalValues = successfulRuns.map((run) => run.totalMs);
|
|
75
94
|
const firstTokenValues = successfulRuns
|
|
@@ -78,6 +97,7 @@ export function aggregateUpstreamBenchmarkRuns(providerLabel, model, path, runs)
|
|
|
78
97
|
return {
|
|
79
98
|
providerLabel,
|
|
80
99
|
model,
|
|
100
|
+
scenario,
|
|
81
101
|
path,
|
|
82
102
|
repetitions: runs.length,
|
|
83
103
|
successCount: successfulRuns.length,
|
|
@@ -90,12 +110,48 @@ export function aggregateUpstreamBenchmarkRuns(providerLabel, model, path, runs)
|
|
|
90
110
|
trimmedAvgFirstTokenMs: trimmedAverageOrNull(firstTokenValues, 0.1),
|
|
91
111
|
medianFirstTokenMs: medianOrNull(firstTokenValues),
|
|
92
112
|
p95FirstTokenMs: percentileOrNull(firstTokenValues, 0.95),
|
|
113
|
+
avgSetupMs: averageOrNull(successfulRuns.map((run) => run.setupMs).filter((value) => value !== null)),
|
|
114
|
+
avgFirstToolMs: averageOrNull(successfulRuns.map((run) => run.firstToolMs).filter((value) => value !== null)),
|
|
115
|
+
avgLastToolMs: averageOrNull(successfulRuns.map((run) => run.lastToolMs).filter((value) => value !== null)),
|
|
116
|
+
avgFinalOutputMs: averageOrNull(successfulRuns.map((run) => run.finalOutputMs).filter((value) => value !== null)),
|
|
117
|
+
avgCleanupMs: averageOrNull(successfulRuns.map((run) => run.cleanupMs).filter((value) => value !== null)),
|
|
93
118
|
avgOutputLength: averageOrNull(successfulRuns.map((run) => run.outputLength)),
|
|
94
119
|
avgNormalizedOutputLength: averageOrNull(successfulRuns.map((run) => run.normalizedOutputLength)),
|
|
95
120
|
avgToolCallCount: averageOrNull(successfulRuns.map((run) => run.toolCallCount)),
|
|
96
121
|
exactOutputMatchCount: successfulRuns.filter((run) => run.exactOutputMatch).length,
|
|
97
122
|
};
|
|
98
123
|
}
|
|
124
|
+
export function withUpstreamBenchmarkCleanup(summary, cleanupMs) {
|
|
125
|
+
return {
|
|
126
|
+
...summary,
|
|
127
|
+
cleanupMs,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
export function summarizeUpstreamBenchmarkPhases(checkpoints) {
|
|
131
|
+
let previousAtMs = 0;
|
|
132
|
+
const durations = {};
|
|
133
|
+
for (const checkpoint of checkpoints) {
|
|
134
|
+
const key = `${checkpoint.label}Ms`;
|
|
135
|
+
if (checkpoint.atMs === null) {
|
|
136
|
+
durations[key] = null;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
durations[key] = Number((checkpoint.atMs - previousAtMs).toFixed(2));
|
|
140
|
+
previousAtMs = checkpoint.atMs;
|
|
141
|
+
}
|
|
142
|
+
return durations;
|
|
143
|
+
}
|
|
144
|
+
export function selectUpstreamBenchmarkRunsByTemperature(runs, temperature) {
|
|
145
|
+
return runs.filter((run) => (temperature === "cold" ? run.runNumber === 1 : run.runNumber > 1));
|
|
146
|
+
}
|
|
147
|
+
export function summarizeUpstreamBenchmarkDurations(values) {
|
|
148
|
+
return {
|
|
149
|
+
count: values.length,
|
|
150
|
+
totalMs: Number(values.reduce((sum, value) => sum + value, 0).toFixed(2)),
|
|
151
|
+
avgMs: values.length > 0 ? average(values) : null,
|
|
152
|
+
maxMs: values.length > 0 ? Number(Math.max(...values).toFixed(2)) : null,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
99
155
|
function computeOverhead(candidate, baseline) {
|
|
100
156
|
if (candidate === null || baseline === null) {
|
|
101
157
|
return { delta: null, pct: null };
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { RunState } from "./core.js";
|
|
2
2
|
import type { CompiledAgentBinding, CompiledModel, CompiledTool, ParsedAgentObject, ParsedToolObject, WorkspaceBundle } from "./workspace.js";
|
|
3
|
+
/**
|
|
4
|
+
* Persisted runtime summary for an inspectable conversation thread.
|
|
5
|
+
* This projects upstream session/thread execution state into a stable runtime
|
|
6
|
+
* inspection surface.
|
|
7
|
+
*/
|
|
3
8
|
export type ThreadSummary = {
|
|
4
9
|
agentId: string;
|
|
5
10
|
threadId: string;
|
|
@@ -8,9 +13,17 @@ export type ThreadSummary = {
|
|
|
8
13
|
updatedAt: string;
|
|
9
14
|
status: RunState;
|
|
10
15
|
};
|
|
11
|
-
export type
|
|
16
|
+
export type SessionSummary = Omit<ThreadSummary, "threadId" | "latestRunId"> & {
|
|
17
|
+
sessionId: string;
|
|
18
|
+
latestRequestId: string;
|
|
19
|
+
};
|
|
12
20
|
export type KnownHarnessEventType = "run.created" | "run.queued" | "run.dequeued" | "run.state.changed" | "run.resumed" | "approval.requested" | "approval.resolved" | "artifact.created" | "output.delta" | "runtime.health.changed" | "runtime.synthetic_fallback";
|
|
13
21
|
export type HarnessEventType = KnownHarnessEventType | (string & {});
|
|
22
|
+
/**
|
|
23
|
+
* Persisted runtime event recorded by the harness runtime.
|
|
24
|
+
* Event payload semantics should stay aligned with upstream/runtime behavior
|
|
25
|
+
* rather than introducing a second execution protocol.
|
|
26
|
+
*/
|
|
14
27
|
export type HarnessEvent = {
|
|
15
28
|
eventId: string;
|
|
16
29
|
eventType: HarnessEventType;
|
|
@@ -45,6 +58,10 @@ export type RuntimeHealthSymptom = {
|
|
|
45
58
|
firstSeenAt: string;
|
|
46
59
|
lastSeenAt: string;
|
|
47
60
|
};
|
|
61
|
+
/**
|
|
62
|
+
* Harness-operated operational state built from persisted records and runtime telemetry.
|
|
63
|
+
* This is runtime ops state, not an upstream execution semantic.
|
|
64
|
+
*/
|
|
48
65
|
export type RuntimeHealthSnapshot = {
|
|
49
66
|
status: HealthStatus;
|
|
50
67
|
updatedAt: string;
|
|
@@ -153,8 +170,20 @@ export type ThreadRunRecord = {
|
|
|
153
170
|
checkpointRef: string | null;
|
|
154
171
|
resumable: boolean;
|
|
155
172
|
};
|
|
173
|
+
/**
|
|
174
|
+
* Persisted run summary projected from upstream execution state plus runtime lifecycle metadata.
|
|
175
|
+
*/
|
|
156
176
|
export type RunSummary = ThreadRunRecord;
|
|
157
177
|
export type RunRecord = RunSummary;
|
|
178
|
+
export type RequestSummary = Omit<RunSummary, "threadId" | "runId"> & {
|
|
179
|
+
sessionId: string;
|
|
180
|
+
requestId: string;
|
|
181
|
+
};
|
|
182
|
+
export type RequestRecord = RequestSummary;
|
|
183
|
+
/**
|
|
184
|
+
* Persisted thread inspection record assembled from runtime records.
|
|
185
|
+
* This is an inspectable projection, not a second thread semantic model.
|
|
186
|
+
*/
|
|
158
187
|
export type ThreadRecord = {
|
|
159
188
|
threadId: string;
|
|
160
189
|
entryAgentId: string;
|
|
@@ -172,6 +201,11 @@ export type ThreadRecord = {
|
|
|
172
201
|
requestedAt: string;
|
|
173
202
|
};
|
|
174
203
|
};
|
|
204
|
+
export type SessionRecord = Omit<ThreadRecord, "threadId" | "latestRunId" | "runs"> & {
|
|
205
|
+
sessionId: string;
|
|
206
|
+
latestRequestId: string;
|
|
207
|
+
requests: RequestSummary[];
|
|
208
|
+
};
|
|
175
209
|
export type ResumeOptions = {
|
|
176
210
|
threadId?: string;
|
|
177
211
|
runId?: string;
|
|
@@ -188,6 +222,11 @@ export type RestartConversationOptions = {
|
|
|
188
222
|
mode: "restart-in-thread" | "restart-new-thread";
|
|
189
223
|
input: string;
|
|
190
224
|
};
|
|
225
|
+
/**
|
|
226
|
+
* Persisted approval inspection record.
|
|
227
|
+
* Approval decision semantics should stay aligned with upstream interrupt/approval
|
|
228
|
+
* behavior even though the record is stored and resolved through harness persistence.
|
|
229
|
+
*/
|
|
191
230
|
export type ApprovalRecord = {
|
|
192
231
|
approvalId: string;
|
|
193
232
|
pendingActionId: string;
|
|
@@ -240,6 +279,12 @@ export type RuntimeAdapterOptions = {
|
|
|
240
279
|
checkpointerResolver?: RuntimeCheckpointerResolver;
|
|
241
280
|
storeResolver?: RuntimeStoreResolver;
|
|
242
281
|
backendResolver?: RuntimeBackendResolver;
|
|
282
|
+
/**
|
|
283
|
+
* DeepAgent execution semantics stay upstream-owned.
|
|
284
|
+
* `minimal` keeps harness runtime persistence/ops active while only attaching
|
|
285
|
+
* upstream substrate objects when the binding explicitly needs them.
|
|
286
|
+
*/
|
|
287
|
+
deepAgentUpstreamSubstrateMode?: "full" | "minimal";
|
|
243
288
|
};
|
|
244
289
|
export type ToolKindAdapter = {
|
|
245
290
|
type: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { AgentHarnessRuntime, cancelRun, createAgentHarness, createUpstreamTimelineReducer, createToolMcpServer,
|
|
1
|
+
export { AgentHarnessRuntime, cancelRun, createAgentHarness, createUpstreamTimelineReducer, createToolMcpServer, deleteSession, describeInventory, getApproval, getRequest, getHealth, getSession, listAgentSkills, listApprovals, listRequests, listSessions, resolveApproval, run, serveToolsOverStdio, subscribe, stop, } from "./api.js";
|
|
2
2
|
export type { ToolMcpServerOptions } from "./mcp.js";
|
|
3
3
|
export { tool } from "./tools.js";
|
|
4
4
|
export type { UpstreamTimelineProjection, UpstreamTimelineReducer } from "./upstream-events.js";
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { AgentHarnessRuntime, cancelRun, createAgentHarness, createUpstreamTimelineReducer, createToolMcpServer,
|
|
1
|
+
export { AgentHarnessRuntime, cancelRun, createAgentHarness, createUpstreamTimelineReducer, createToolMcpServer, deleteSession, describeInventory, getApproval, getRequest, getHealth, getSession, listAgentSkills, listApprovals, listRequests, listSessions, resolveApproval, run, serveToolsOverStdio, subscribe, stop, } from "./api.js";
|
|
2
2
|
export { tool } from "./tools.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.125";
|
package/dist/package-version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.125";
|
|
@@ -32,9 +32,9 @@ export declare function buildDeepAgentCreateParams(input: {
|
|
|
32
32
|
resolvedTools: unknown[];
|
|
33
33
|
resolvedMiddleware: unknown[];
|
|
34
34
|
resolvedSubagents: UpstreamSubagentConfig[];
|
|
35
|
-
resolvedCheckpointer
|
|
36
|
-
resolvedStore
|
|
37
|
-
resolvedBackend
|
|
35
|
+
resolvedCheckpointer?: unknown;
|
|
36
|
+
resolvedStore?: unknown;
|
|
37
|
+
resolvedBackend?: unknown;
|
|
38
38
|
resolvedInterruptOn?: Record<string, {
|
|
39
39
|
allowedDecisions: Array<"approve" | "edit" | "reject">;
|
|
40
40
|
}>;
|
|
@@ -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 { getBindingAdapterKind, getBindingExecutionKind, getBindingExecutionParams, getBindingFilesystemConfig, getBindingInterruptCompatibilityRules, getBindingPrimaryModel, getBindingSkills, getBindingSubagents, getBindingToolCount, getBindingPrimaryTools, getBindingSystemPrompt, isDeepAgentBinding, isLangChainBinding, } from "./support/compiled-binding.js";
|
|
21
|
+
import { getBindingBackendConfig, getBindingAdapterKind, getBindingExecutionKind, getBindingExecutionParams, getBindingFilesystemConfig, getBindingInterruptCompatibilityRules, getBindingMemorySources, getBindingMiddlewareConfigs, getBindingPrimaryModel, getBindingSkills, getBindingStoreConfig, getBindingSubagents, 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",
|
|
@@ -116,13 +116,28 @@ export function buildDeepAgentCreateParams(input) {
|
|
|
116
116
|
model: input.resolvedModel,
|
|
117
117
|
tools: input.resolvedTools,
|
|
118
118
|
middleware: input.resolvedMiddleware,
|
|
119
|
-
checkpointer: input.resolvedCheckpointer,
|
|
120
|
-
store: input.resolvedStore,
|
|
121
119
|
subagents: input.resolvedSubagents,
|
|
122
|
-
backend: input.resolvedBackend,
|
|
123
120
|
interruptOn: input.resolvedInterruptOn,
|
|
121
|
+
...(input.resolvedCheckpointer !== undefined ? { checkpointer: input.resolvedCheckpointer } : {}),
|
|
122
|
+
...(input.resolvedStore !== undefined ? { store: input.resolvedStore } : {}),
|
|
123
|
+
...(input.resolvedBackend !== undefined ? { backend: input.resolvedBackend } : {}),
|
|
124
124
|
};
|
|
125
125
|
}
|
|
126
|
+
function shouldAttachMinimalDeepAgentCheckpointer(binding, resolvedInterruptOn) {
|
|
127
|
+
if (binding.harnessRuntime.checkpointer !== undefined) {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
return resolvedInterruptOn !== undefined && Object.keys(resolvedInterruptOn).length > 0;
|
|
131
|
+
}
|
|
132
|
+
function shouldAttachMinimalDeepAgentStore(binding) {
|
|
133
|
+
return getBindingStoreConfig(binding) !== undefined || getBindingMemorySources(binding).length > 0;
|
|
134
|
+
}
|
|
135
|
+
function shouldAttachMinimalDeepAgentBackend(binding) {
|
|
136
|
+
return (getBindingBackendConfig(binding) !== undefined ||
|
|
137
|
+
getBindingMemorySources(binding).length > 0 ||
|
|
138
|
+
getBindingSkills(binding).length > 0 ||
|
|
139
|
+
(getBindingMiddlewareConfigs(binding)?.length ?? 0) > 0);
|
|
140
|
+
}
|
|
126
141
|
export class AgentRuntimeAdapter {
|
|
127
142
|
options;
|
|
128
143
|
modelCache = new Map();
|
|
@@ -351,10 +366,19 @@ export class AgentRuntimeAdapter {
|
|
|
351
366
|
const resolvedTools = this.resolveTools(primaryTools, binding);
|
|
352
367
|
const resolvedMiddleware = await this.resolveMiddleware(binding);
|
|
353
368
|
const resolvedSubagents = await this.resolveSubagents(getBindingSubagents(binding), binding);
|
|
354
|
-
const resolvedCheckpointer = resolveRunnableCheckpointer(this.options, binding);
|
|
355
|
-
const resolvedStore = this.options.storeResolver?.(binding);
|
|
356
|
-
const resolvedBackend = this.options.backendResolver?.(binding);
|
|
357
369
|
const resolvedInterruptOn = resolveRunnableInterruptOn(binding);
|
|
370
|
+
const substrateMode = this.options.deepAgentUpstreamSubstrateMode ?? "minimal";
|
|
371
|
+
const resolvedCheckpointer = substrateMode === "minimal"
|
|
372
|
+
? (shouldAttachMinimalDeepAgentCheckpointer(binding, resolvedInterruptOn)
|
|
373
|
+
? resolveRunnableCheckpointer(this.options, binding)
|
|
374
|
+
: undefined)
|
|
375
|
+
: resolveRunnableCheckpointer(this.options, binding);
|
|
376
|
+
const resolvedStore = substrateMode === "minimal"
|
|
377
|
+
? (shouldAttachMinimalDeepAgentStore(binding) ? this.options.storeResolver?.(binding) : undefined)
|
|
378
|
+
: this.options.storeResolver?.(binding);
|
|
379
|
+
const resolvedBackend = substrateMode === "minimal"
|
|
380
|
+
? (shouldAttachMinimalDeepAgentBackend(binding) ? this.options.backendResolver?.(binding) : undefined)
|
|
381
|
+
: this.options.backendResolver?.(binding);
|
|
358
382
|
const resolvedSkills = resolveDeepAgentSkillSourcePaths({
|
|
359
383
|
workspaceRoot: binding.harnessRuntime.workspaceRoot,
|
|
360
384
|
runRoot: binding.harnessRuntime.runRoot,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ApprovalRecord, HarnessEvent, InternalApprovalRecord, InvocationEnvelope, RunListeners, RunOptions, RunResult, RunStartOptions, MessageContent } from "../../../contracts/types.js";
|
|
2
|
-
export declare function
|
|
2
|
+
export declare function toInspectableApprovalRecord(approval: InternalApprovalRecord): ApprovalRecord;
|
|
3
3
|
export declare function normalizeInvocationEnvelope(options: RunStartOptions): {
|
|
4
4
|
context?: Record<string, unknown>;
|
|
5
5
|
state?: Record<string, unknown>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { normalizeMessageContent } from "../../../utils/message-content.js";
|
|
2
|
-
export function
|
|
2
|
+
export function toInspectableApprovalRecord(approval) {
|
|
3
3
|
const { toolCallId: _toolCallId, checkpointRef: _checkpointRef, eventRefs: _eventRefs, ...publicApproval } = approval;
|
|
4
4
|
return publicApproval;
|
|
5
5
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AGENT_INTERRUPT_SENTINEL_PREFIX, RuntimeOperationTimeoutError } from "../../agent-runtime-adapter.js";
|
|
2
2
|
import { renderRuntimeFailure, renderToolFailure } from "../../support/harness-support.js";
|
|
3
|
-
import { createContentBlocksItem, createToolResultKey,
|
|
3
|
+
import { createContentBlocksItem, createToolResultKey, } from "../events/streaming.js";
|
|
4
4
|
function normalizeStreamChunk(chunk) {
|
|
5
5
|
if (typeof chunk === "string") {
|
|
6
6
|
if (chunk.startsWith(AGENT_INTERRUPT_SENTINEL_PREFIX)) {
|
|
@@ -33,7 +33,6 @@ export async function* streamHarnessRun(options) {
|
|
|
33
33
|
let releaseRunSlot = async () => undefined;
|
|
34
34
|
let emitted = false;
|
|
35
35
|
let streamActivityObserved = false;
|
|
36
|
-
const emitOutputDelta = (content) => emitOutputDeltaAndCreateItem(options.emit, options.threadId, options.runId, options.selectedAgentId, content);
|
|
37
36
|
try {
|
|
38
37
|
const [priorHistory, acquiredReleaseRunSlot] = await Promise.all([
|
|
39
38
|
priorHistoryPromise,
|
|
@@ -114,12 +113,10 @@ export async function* streamHarnessRun(options) {
|
|
|
114
113
|
}
|
|
115
114
|
emitted = true;
|
|
116
115
|
assistantOutput += normalizedChunk.content;
|
|
117
|
-
yield await emitOutputDelta(normalizedChunk.content);
|
|
118
116
|
}
|
|
119
117
|
if (!assistantOutput && toolErrors.length > 0) {
|
|
120
118
|
assistantOutput = toolErrors.join("\n\n");
|
|
121
119
|
emitted = true;
|
|
122
|
-
yield await emitOutputDelta(assistantOutput);
|
|
123
120
|
}
|
|
124
121
|
if (!assistantOutput) {
|
|
125
122
|
const actual = await options.invokeWithHistory(options.binding, options.input, options.threadId, options.runId);
|
|
@@ -129,7 +126,6 @@ export async function* streamHarnessRun(options) {
|
|
|
129
126
|
if (actual.output) {
|
|
130
127
|
assistantOutput = actual.output;
|
|
131
128
|
emitted = true;
|
|
132
|
-
yield await emitOutputDelta(actual.output);
|
|
133
129
|
}
|
|
134
130
|
}
|
|
135
131
|
await options.appendAssistantMessage(options.threadId, options.runId, assistantOutput);
|
|
@@ -216,9 +212,6 @@ export async function* streamHarnessRun(options) {
|
|
|
216
212
|
if (Array.isArray(actual.contentBlocks) && actual.contentBlocks.length > 0) {
|
|
217
213
|
yield createContentBlocksItem(options.threadId, options.runId, options.selectedAgentId, actual.contentBlocks);
|
|
218
214
|
}
|
|
219
|
-
if (actual.output) {
|
|
220
|
-
yield await emitOutputDelta(actual.output);
|
|
221
|
-
}
|
|
222
215
|
yield {
|
|
223
216
|
type: "result",
|
|
224
217
|
result: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ApprovalRecord, ThreadRecord, ThreadSummary } from "../../../contracts/types.js";
|
|
2
2
|
import type { RuntimePersistence } from "../../../persistence/types.js";
|
|
3
|
-
export declare function
|
|
3
|
+
export declare function buildThreadInspectionRecord(input: {
|
|
4
4
|
persistence: RuntimePersistence;
|
|
5
5
|
getSession: (threadId: string) => Promise<ThreadSummary | null>;
|
|
6
6
|
}, threadId: string): Promise<ThreadRecord | null>;
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import { isTerminalRunState,
|
|
2
|
-
|
|
1
|
+
import { isTerminalRunState, toInspectableApprovalRecord } from "./helpers.js";
|
|
2
|
+
function selectLatestPendingApproval(approvals) {
|
|
3
|
+
return approvals
|
|
4
|
+
.filter((approval) => approval.status === "pending")
|
|
5
|
+
.sort((left, right) => right.requestedAt.localeCompare(left.requestedAt))[0];
|
|
6
|
+
}
|
|
7
|
+
export async function buildThreadInspectionRecord(input, threadId) {
|
|
3
8
|
const [threadSummary, meta, messages, runs] = await Promise.all([
|
|
4
9
|
input.getSession(threadId),
|
|
5
10
|
input.persistence.getThreadMeta(threadId),
|
|
@@ -11,9 +16,7 @@ export async function getThreadRecord(input, threadId) {
|
|
|
11
16
|
}
|
|
12
17
|
const latestRunId = threadSummary.latestRunId;
|
|
13
18
|
const latestApprovals = await input.persistence.getRunApprovals(threadId, latestRunId);
|
|
14
|
-
const pendingApproval = latestApprovals
|
|
15
|
-
.filter((approval) => approval.status === "pending")
|
|
16
|
-
.sort((left, right) => right.requestedAt.localeCompare(left.requestedAt))[0];
|
|
19
|
+
const pendingApproval = selectLatestPendingApproval(latestApprovals);
|
|
17
20
|
return {
|
|
18
21
|
threadId,
|
|
19
22
|
entryAgentId: meta.entryAgentId,
|
|
@@ -36,11 +39,11 @@ export async function getThreadRecord(input, threadId) {
|
|
|
36
39
|
}
|
|
37
40
|
export async function listPublicApprovals(input, filter) {
|
|
38
41
|
const approvals = await input.persistence.listApprovals(filter);
|
|
39
|
-
return approvals.map((approval) =>
|
|
42
|
+
return approvals.map((approval) => toInspectableApprovalRecord(approval));
|
|
40
43
|
}
|
|
41
44
|
export async function getPublicApproval(input, approvalId) {
|
|
42
45
|
const approval = await input.persistence.getApproval(approvalId);
|
|
43
|
-
return approval ?
|
|
46
|
+
return approval ? toInspectableApprovalRecord(approval) : null;
|
|
44
47
|
}
|
|
45
48
|
export async function deleteThreadRecord(input, threadId) {
|
|
46
49
|
const thread = await input.getThread(threadId);
|
package/dist/runtime/harness.js
CHANGED
|
@@ -29,7 +29,7 @@ import { resolveRuntimeAdapterOptions } from "./support/runtime-adapter-options.
|
|
|
29
29
|
import { initializeHarnessRuntime, reclaimExpiredClaimedRuns as reclaimHarnessExpiredClaimedRuns, recoverStartupRuns as recoverHarnessStartupRuns, isStaleRunningRun as isHarnessStaleRunningRun, } from "./harness/run/startup-runtime.js";
|
|
30
30
|
import { streamHarnessRun } from "./harness/run/stream-run.js";
|
|
31
31
|
import { defaultRequestedAgentId, prepareRunStart } from "./harness/run/start-run.js";
|
|
32
|
-
import { deleteThreadRecord, getPublicApproval,
|
|
32
|
+
import { buildThreadInspectionRecord, deleteThreadRecord, getPublicApproval, listPublicApprovals, } from "./harness/run/thread-records.js";
|
|
33
33
|
export class AgentHarnessRuntime {
|
|
34
34
|
workspace;
|
|
35
35
|
runtimeAdapterOptions;
|
|
@@ -199,7 +199,7 @@ export class AgentHarnessRuntime {
|
|
|
199
199
|
return this.persistence.getSession(threadId);
|
|
200
200
|
}
|
|
201
201
|
async getThread(threadId) {
|
|
202
|
-
return
|
|
202
|
+
return buildThreadInspectionRecord({
|
|
203
203
|
persistence: this.persistence,
|
|
204
204
|
getSession: (currentThreadId) => this.getSession(currentThreadId),
|
|
205
205
|
}, threadId);
|