@botbotgo/agent-harness 0.0.290 → 0.0.291
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 +20 -20
- package/README.zh.md +14 -14
- package/dist/acp.d.ts +5 -5
- package/dist/acp.js +3 -3
- package/dist/api.d.ts +20 -21
- package/dist/api.js +38 -50
- package/dist/cli.js +47 -43
- package/dist/config/agents/orchestra.yaml +3 -3
- package/dist/config/knowledge/knowledge-runtime.yaml +4 -4
- package/dist/config/runtime/runtime-memory.yaml +7 -7
- package/dist/config/runtime/workspace.yaml +7 -7
- package/dist/contracts/core.d.ts +1 -1
- package/dist/contracts/runtime.d.ts +35 -40
- package/dist/contracts/workspace.d.ts +2 -2
- package/dist/flow/build-flow-graph.js +20 -33
- package/dist/flow/export-sequence-mermaid.js +4 -4
- package/dist/flow/types.d.ts +2 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -1
- package/dist/init-project.js +10 -10
- package/dist/knowledge/module.js +37 -45
- package/dist/mcp.d.ts +9 -9
- package/dist/mcp.js +6 -6
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/persistence/file-store.d.ts +69 -69
- package/dist/persistence/file-store.js +224 -221
- package/dist/persistence/sqlite-request-context-store.d.ts +22 -0
- package/dist/persistence/sqlite-request-context-store.js +64 -0
- package/dist/persistence/sqlite-request-queue-store.d.ts +41 -0
- package/dist/persistence/sqlite-request-queue-store.js +120 -0
- package/dist/persistence/sqlite-store.d.ts +72 -72
- package/dist/persistence/sqlite-store.js +361 -361
- package/dist/persistence/types.d.ts +84 -84
- package/dist/protocol/a2a/http.js +79 -74
- package/dist/protocol/ag-ui/http.d.ts +7 -7
- package/dist/protocol/ag-ui/http.js +20 -20
- package/dist/resource/resource-impl.js +1 -1
- package/dist/runtime/adapter/compat/deepagent-compat.d.ts +2 -2
- package/dist/runtime/adapter/flow/invocation-flow.d.ts +6 -5
- package/dist/runtime/adapter/flow/invocation-flow.js +6 -5
- package/dist/runtime/adapter/flow/stream-runtime.d.ts +3 -3
- package/dist/runtime/adapter/flow/stream-runtime.js +5 -4
- package/dist/runtime/adapter/invocation-result.d.ts +6 -5
- package/dist/runtime/adapter/invocation-result.js +5 -4
- package/dist/runtime/adapter/middleware-assembly.js +3 -2
- package/dist/runtime/adapter/tool/tool-hitl.js +1 -1
- package/dist/runtime/adapter/upstream-configurable-keys.d.ts +2 -0
- package/dist/runtime/adapter/upstream-configurable-keys.js +2 -0
- package/dist/runtime/agent-runtime-adapter.d.ts +11 -8
- package/dist/runtime/agent-runtime-adapter.js +36 -32
- package/dist/runtime/harness/events/events.d.ts +8 -8
- package/dist/runtime/harness/events/events.js +25 -19
- package/dist/runtime/harness/events/listener-runtime.d.ts +5 -4
- package/dist/runtime/harness/events/listener-runtime.js +7 -3
- package/dist/runtime/harness/events/runtime-event-operations.d.ts +7 -7
- package/dist/runtime/harness/events/runtime-event-operations.js +5 -5
- package/dist/runtime/harness/events/streaming.d.ts +8 -7
- package/dist/runtime/harness/events/streaming.js +20 -19
- package/dist/runtime/harness/events/timeline.js +6 -6
- package/dist/runtime/harness/index.d.ts +1 -1
- package/dist/runtime/harness/index.js +1 -1
- package/dist/runtime/harness/run/helpers.d.ts +14 -11
- package/dist/runtime/harness/run/helpers.js +10 -7
- package/dist/runtime/harness/run/inspection.d.ts +3 -2
- package/dist/runtime/harness/run/inspection.js +7 -7
- package/dist/runtime/harness/run/operator-overview.d.ts +2 -2
- package/dist/runtime/harness/run/operator-overview.js +18 -17
- package/dist/runtime/harness/run/queue-diagnostics.js +6 -6
- package/dist/runtime/harness/run/recovery.d.ts +15 -15
- package/dist/runtime/harness/run/recovery.js +53 -50
- package/dist/runtime/harness/run/resources.d.ts +2 -2
- package/dist/runtime/harness/run/resources.js +8 -8
- package/dist/runtime/harness/run/resume.d.ts +3 -3
- package/dist/runtime/harness/run/resume.js +4 -4
- package/dist/runtime/harness/run/routing.d.ts +4 -4
- package/dist/runtime/harness/run/routing.js +8 -8
- package/dist/runtime/harness/run/run-lifecycle.d.ts +12 -12
- package/dist/runtime/harness/run/run-lifecycle.js +26 -26
- package/dist/runtime/harness/run/run-operations.d.ts +45 -45
- package/dist/runtime/harness/run/run-operations.js +79 -78
- package/dist/runtime/harness/run/run-queue.d.ts +8 -8
- package/dist/runtime/harness/run/run-queue.js +16 -16
- package/dist/runtime/harness/run/run-slot-acquisition.d.ts +32 -32
- package/dist/runtime/harness/run/run-slot-acquisition.js +41 -41
- package/dist/runtime/harness/run/{thread-records.d.ts → session-records.d.ts} +6 -13
- package/dist/runtime/harness/run/{thread-records.js → session-records.js} +14 -60
- package/dist/runtime/harness/run/start-run.d.ts +36 -36
- package/dist/runtime/harness/run/start-run.js +55 -36
- package/dist/runtime/harness/run/startup-runtime.d.ts +9 -9
- package/dist/runtime/harness/run/startup-runtime.js +22 -20
- package/dist/runtime/harness/run/stream-run.d.ts +18 -18
- package/dist/runtime/harness/run/stream-run.js +52 -52
- package/dist/runtime/harness/runtime-defaults.d.ts +2 -2
- package/dist/runtime/harness/runtime-defaults.js +7 -7
- package/dist/runtime/harness/system/health-monitor.d.ts +3 -3
- package/dist/runtime/harness/system/health-monitor.js +18 -18
- package/dist/runtime/harness/system/mem0-ingestion-sync.d.ts +6 -6
- package/dist/runtime/harness/system/mem0-ingestion-sync.js +36 -27
- package/dist/runtime/harness/system/runtime-memory-candidates.js +2 -2
- package/dist/runtime/harness/system/runtime-memory-manager.d.ts +13 -13
- package/dist/runtime/harness/system/runtime-memory-manager.js +41 -38
- package/dist/runtime/harness/system/runtime-memory-policy.d.ts +1 -1
- package/dist/runtime/harness/system/runtime-memory-policy.js +1 -1
- package/dist/runtime/harness/system/runtime-memory-records.d.ts +4 -2
- package/dist/runtime/harness/system/runtime-memory-records.js +21 -8
- package/dist/runtime/harness/system/runtime-memory-sync.d.ts +6 -6
- package/dist/runtime/harness/system/runtime-memory-sync.js +47 -44
- package/dist/runtime/harness/system/{thread-memory-sync.d.ts → session-memory-sync.d.ts} +7 -7
- package/dist/runtime/harness/system/{thread-memory-sync.js → session-memory-sync.js} +28 -28
- package/dist/runtime/harness.d.ts +33 -45
- package/dist/runtime/harness.js +273 -291
- package/dist/runtime/maintenance/checkpoint-maintenance.js +2 -2
- package/dist/runtime/maintenance/file-checkpoint-saver.d.ts +1 -1
- package/dist/runtime/maintenance/file-checkpoint-saver.js +6 -6
- package/dist/runtime/maintenance/runtime-record-maintenance.d.ts +1 -1
- package/dist/runtime/maintenance/runtime-record-maintenance.js +33 -33
- package/dist/runtime/maintenance/sqlite-checkpoint-saver.d.ts +1 -1
- package/dist/runtime/maintenance/sqlite-checkpoint-saver.js +30 -10
- package/dist/runtime/support/harness-support.d.ts +2 -2
- package/dist/runtime/support/harness-support.js +7 -7
- package/dist/runtime/support/runtime-adapter-options.d.ts +2 -2
- package/dist/runtime/support/runtime-adapter-options.js +3 -3
- package/dist/runtime/support/runtime-factories.d.ts +2 -2
- package/dist/runtime/support/runtime-factories.js +10 -10
- package/dist/workspace/agent-binding-compiler.js +3 -3
- package/dist/workspace/object-loader.js +1 -1
- package/dist/workspace/support/workspace-ref-utils.d.ts +4 -3
- package/dist/workspace/support/workspace-ref-utils.js +5 -4
- package/package.json +1 -1
- package/dist/persistence/sqlite-run-context-store.d.ts +0 -22
- package/dist/persistence/sqlite-run-context-store.js +0 -64
- package/dist/persistence/sqlite-run-queue-store.d.ts +0 -41
- package/dist/persistence/sqlite-run-queue-store.js +0 -120
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export async function
|
|
3
|
-
const {
|
|
1
|
+
import { shiftNextPendingRequestSlot } from "./run-queue.js";
|
|
2
|
+
export async function acquireRequestSlot(runtime, options = {}) {
|
|
3
|
+
const { sessionId, requestId } = options;
|
|
4
4
|
const activeState = options.activeState ?? "running";
|
|
5
5
|
const priority = options.priority ?? 0;
|
|
6
6
|
let stopHeartbeat = () => undefined;
|
|
7
7
|
const beginLease = async (mode) => {
|
|
8
|
-
if (!
|
|
8
|
+
if (!sessionId || !requestId) {
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
11
11
|
const claimedAt = new Date().toISOString();
|
|
12
12
|
const leaseExpiresAt = new Date(Date.now() + runtime.concurrencyConfig.leaseMs).toISOString();
|
|
13
13
|
if (mode === "queue-claim") {
|
|
14
|
-
await runtime.persistence.
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
await runtime.persistence.claimQueuedRequest({
|
|
15
|
+
sessionId,
|
|
16
|
+
requestId,
|
|
17
17
|
workerId: runtime.workerId,
|
|
18
18
|
claimedAt,
|
|
19
19
|
leaseExpiresAt,
|
|
20
20
|
});
|
|
21
21
|
}
|
|
22
22
|
else {
|
|
23
|
-
await runtime.persistence.
|
|
24
|
-
|
|
23
|
+
await runtime.persistence.renewRequestLease({
|
|
24
|
+
requestId,
|
|
25
25
|
workerId: runtime.workerId,
|
|
26
26
|
heartbeatAt: claimedAt,
|
|
27
27
|
leaseExpiresAt,
|
|
@@ -31,8 +31,8 @@ export async function acquireRunSlot(runtime, options = {}) {
|
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
33
|
const timer = setInterval(() => {
|
|
34
|
-
void runtime.persistence.
|
|
35
|
-
|
|
34
|
+
void runtime.persistence.renewRequestLease({
|
|
35
|
+
requestId,
|
|
36
36
|
workerId: runtime.workerId,
|
|
37
37
|
heartbeatAt: new Date().toISOString(),
|
|
38
38
|
leaseExpiresAt: new Date(Date.now() + runtime.concurrencyConfig.leaseMs).toISOString(),
|
|
@@ -45,13 +45,13 @@ export async function acquireRunSlot(runtime, options = {}) {
|
|
|
45
45
|
};
|
|
46
46
|
const releaseLease = async () => {
|
|
47
47
|
stopHeartbeat();
|
|
48
|
-
if (
|
|
49
|
-
await runtime.persistence.
|
|
48
|
+
if (requestId) {
|
|
49
|
+
await runtime.persistence.releaseRequestClaim(requestId);
|
|
50
50
|
}
|
|
51
51
|
};
|
|
52
52
|
const releaseAndAdvance = async (shiftNext) => {
|
|
53
53
|
await releaseLease();
|
|
54
|
-
runtime.
|
|
54
|
+
runtime.setActiveRequestSlots(Math.max(0, runtime.getActiveRequestSlots() - 1));
|
|
55
55
|
const next = shiftNext();
|
|
56
56
|
void next?.activate();
|
|
57
57
|
};
|
|
@@ -62,12 +62,12 @@ export async function acquireRunSlot(runtime, options = {}) {
|
|
|
62
62
|
await releaseLease();
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
|
-
const canActivateImmediately = runtime.
|
|
65
|
+
const canActivateImmediately = runtime.getActiveRequestSlots() < maxConcurrentRuns;
|
|
66
66
|
const useDirectHeartbeatFastPath = canActivateImmediately && maxConcurrentRuns > 1;
|
|
67
67
|
if (canActivateImmediately) {
|
|
68
|
-
runtime.
|
|
69
|
-
if (
|
|
70
|
-
await runtime.persistence.
|
|
68
|
+
runtime.setActiveRequestSlots(runtime.getActiveRequestSlots() + 1);
|
|
69
|
+
if (sessionId && requestId && !useDirectHeartbeatFastPath) {
|
|
70
|
+
await runtime.persistence.enqueueRequest({ sessionId, requestId, priority });
|
|
71
71
|
}
|
|
72
72
|
await beginLease(useDirectHeartbeatFastPath ? "direct-heartbeat" : "queue-claim");
|
|
73
73
|
let released = false;
|
|
@@ -76,39 +76,39 @@ export async function acquireRunSlot(runtime, options = {}) {
|
|
|
76
76
|
return;
|
|
77
77
|
}
|
|
78
78
|
released = true;
|
|
79
|
-
await releaseAndAdvance(() =>
|
|
79
|
+
await releaseAndAdvance(() => shiftNextPendingRequestSlot(runtime.pendingRequestSlots));
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
|
-
const
|
|
83
|
-
const
|
|
84
|
-
if (
|
|
82
|
+
const activateQueuedRequest = async () => {
|
|
83
|
+
const currentRequest = requestId ? await runtime.persistence.getRequest(requestId) : null;
|
|
84
|
+
if (currentRequest?.state === "cancelled") {
|
|
85
85
|
return "abort";
|
|
86
86
|
}
|
|
87
|
-
runtime.
|
|
88
|
-
if (
|
|
89
|
-
await runtime.emit(
|
|
87
|
+
runtime.setActiveRequestSlots(runtime.getActiveRequestSlots() + 1);
|
|
88
|
+
if (sessionId && requestId) {
|
|
89
|
+
await runtime.emit(sessionId, requestId, 4, "request.dequeued", {
|
|
90
90
|
queuePosition: 0,
|
|
91
|
-
|
|
91
|
+
activeRequestCount: runtime.getActiveRequestSlots(),
|
|
92
92
|
maxConcurrentRuns,
|
|
93
93
|
priority,
|
|
94
94
|
});
|
|
95
|
-
await runtime.
|
|
95
|
+
await runtime.setRequestStateAndEmit(sessionId, requestId, 5, activeState, {
|
|
96
96
|
previousState: "queued",
|
|
97
97
|
});
|
|
98
98
|
await beginLease("queue-claim");
|
|
99
99
|
}
|
|
100
100
|
return "activate";
|
|
101
101
|
};
|
|
102
|
-
if (
|
|
103
|
-
await runtime.persistence.
|
|
102
|
+
if (sessionId && requestId) {
|
|
103
|
+
await runtime.persistence.enqueueRequest({ sessionId, requestId, priority });
|
|
104
104
|
const slotAcquisition = new Promise((resolve, reject) => {
|
|
105
|
-
const displacedEntries = runtime.
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
const displacedEntries = runtime.enqueuePendingRequestSlot({
|
|
106
|
+
sessionId,
|
|
107
|
+
requestId,
|
|
108
108
|
priority,
|
|
109
109
|
activate: async () => {
|
|
110
110
|
try {
|
|
111
|
-
resolve(await
|
|
111
|
+
resolve(await activateQueuedRequest());
|
|
112
112
|
}
|
|
113
113
|
catch (error) {
|
|
114
114
|
reject(error);
|
|
@@ -116,20 +116,20 @@ export async function acquireRunSlot(runtime, options = {}) {
|
|
|
116
116
|
},
|
|
117
117
|
abort: () => resolve("abort"),
|
|
118
118
|
});
|
|
119
|
-
void Promise.all(displacedEntries.map((candidate) => runtime.emit(candidate.
|
|
119
|
+
void Promise.all(displacedEntries.map((candidate) => runtime.emit(candidate.sessionId, candidate.requestId, 3, "request.queued", {
|
|
120
120
|
queuePosition: candidate.queuePosition,
|
|
121
|
-
|
|
121
|
+
activeRequestCount: runtime.getActiveRequestSlots(),
|
|
122
122
|
maxConcurrentRuns,
|
|
123
123
|
priority: candidate.priority,
|
|
124
124
|
})));
|
|
125
125
|
});
|
|
126
|
-
const queuePosition = runtime.
|
|
127
|
-
await runtime.
|
|
126
|
+
const queuePosition = runtime.pendingRequestSlots.findIndex((entry) => entry.requestId === requestId) + 1;
|
|
127
|
+
await runtime.setRequestStateAndEmit(sessionId, requestId, 2, "queued", {
|
|
128
128
|
previousState: activeState,
|
|
129
129
|
});
|
|
130
|
-
await runtime.emit(
|
|
130
|
+
await runtime.emit(sessionId, requestId, 3, "request.queued", {
|
|
131
131
|
queuePosition,
|
|
132
|
-
|
|
132
|
+
activeRequestCount: runtime.getActiveRequestSlots(),
|
|
133
133
|
maxConcurrentRuns,
|
|
134
134
|
priority,
|
|
135
135
|
});
|
|
@@ -143,7 +143,7 @@ export async function acquireRunSlot(runtime, options = {}) {
|
|
|
143
143
|
return;
|
|
144
144
|
}
|
|
145
145
|
released = true;
|
|
146
|
-
await releaseAndAdvance(() => runtime.
|
|
146
|
+
await releaseAndAdvance(() => runtime.pendingRequestSlots.shift());
|
|
147
147
|
};
|
|
148
148
|
}
|
|
149
149
|
let released = false;
|
|
@@ -152,6 +152,6 @@ export async function acquireRunSlot(runtime, options = {}) {
|
|
|
152
152
|
return;
|
|
153
153
|
}
|
|
154
154
|
released = true;
|
|
155
|
-
await releaseAndAdvance(() =>
|
|
155
|
+
await releaseAndAdvance(() => shiftNextPendingRequestSlot(runtime.pendingRequestSlots));
|
|
156
156
|
};
|
|
157
157
|
}
|
|
@@ -1,29 +1,22 @@
|
|
|
1
|
-
import type { ApprovalRecord, RequestRecord, SessionRecord, SessionSummary,
|
|
1
|
+
import type { ApprovalRecord, RequestRecord, SessionRecord, SessionSummary, RequestSummary } from "../../../contracts/types.js";
|
|
2
2
|
import type { RuntimePersistence } from "../../../persistence/types.js";
|
|
3
|
-
export declare function buildRequestInspectionRecord(persistence: RuntimePersistence, request:
|
|
3
|
+
export declare function buildRequestInspectionRecord(persistence: RuntimePersistence, request: RequestSummary): Promise<RequestRecord>;
|
|
4
4
|
export declare function buildSessionInspectionRecord(input: {
|
|
5
5
|
persistence: RuntimePersistence;
|
|
6
6
|
getSession: (sessionId: string) => Promise<SessionSummary | null>;
|
|
7
7
|
}, sessionId: string): Promise<SessionRecord | null>;
|
|
8
|
-
export declare function buildThreadInspectionRecord(input: {
|
|
9
|
-
persistence: RuntimePersistence;
|
|
10
|
-
getSession: (threadId: string) => Promise<ThreadSummary | null>;
|
|
11
|
-
}, threadId: string): Promise<ThreadRecord | null>;
|
|
12
8
|
export declare function listPublicApprovals(input: {
|
|
13
9
|
persistence: RuntimePersistence;
|
|
14
10
|
}, filter?: {
|
|
15
11
|
status?: ApprovalRecord["status"];
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
sessionId?: string;
|
|
13
|
+
requestId?: string;
|
|
14
|
+
legacySessionId?: string;
|
|
15
|
+
legacyRunId?: string;
|
|
18
16
|
}): Promise<ApprovalRecord[]>;
|
|
19
17
|
export declare function getPublicApproval(input: {
|
|
20
18
|
persistence: RuntimePersistence;
|
|
21
19
|
}, approvalId: string): Promise<ApprovalRecord | null>;
|
|
22
|
-
export declare function deleteThreadRecord(input: {
|
|
23
|
-
getThread: (threadId: string) => Promise<ThreadRecord | null>;
|
|
24
|
-
deleteThread: (threadId: string) => Promise<boolean>;
|
|
25
|
-
deleteThreadCheckpoints: (threadId: string) => Promise<void>;
|
|
26
|
-
}, threadId: string): Promise<boolean>;
|
|
27
20
|
export declare function deleteSessionRecord(input: {
|
|
28
21
|
getSession: (sessionId: string) => Promise<SessionRecord | null>;
|
|
29
22
|
deleteSession: (sessionId: string) => Promise<boolean>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isTerminalRequestState, toInspectableApprovalRecord } from "./helpers.js";
|
|
2
2
|
import { projectRuntimeTimeline } from "../events/timeline.js";
|
|
3
3
|
function selectLatestPendingApproval(approvals) {
|
|
4
4
|
return approvals
|
|
@@ -6,13 +6,13 @@ function selectLatestPendingApproval(approvals) {
|
|
|
6
6
|
.sort((left, right) => right.requestedAt.localeCompare(left.requestedAt))[0];
|
|
7
7
|
}
|
|
8
8
|
export async function buildRequestInspectionRecord(persistence, request) {
|
|
9
|
-
const inspection = await persistence.
|
|
10
|
-
const runtimeEvents = await persistence.
|
|
9
|
+
const inspection = await persistence.getRequestInspection(request.sessionId, request.requestId);
|
|
10
|
+
const runtimeEvents = await persistence.listRequestEvents(request.sessionId, request.requestId);
|
|
11
11
|
return {
|
|
12
12
|
requestId: request.requestId,
|
|
13
13
|
sessionId: request.sessionId,
|
|
14
14
|
agentId: request.agentId,
|
|
15
|
-
|
|
15
|
+
parentRequestId: request.parentRequestId,
|
|
16
16
|
executionMode: request.executionMode,
|
|
17
17
|
adapterKind: request.adapterKind,
|
|
18
18
|
createdAt: request.createdAt,
|
|
@@ -33,42 +33,19 @@ export async function buildRequestInspectionRecord(persistence, request) {
|
|
|
33
33
|
}),
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
|
-
function toRunRecord(request) {
|
|
37
|
-
return {
|
|
38
|
-
requestId: request.requestId,
|
|
39
|
-
sessionId: request.sessionId,
|
|
40
|
-
agentId: request.agentId,
|
|
41
|
-
parentRunId: request.parentRunId,
|
|
42
|
-
executionMode: request.executionMode,
|
|
43
|
-
adapterKind: request.adapterKind,
|
|
44
|
-
createdAt: request.createdAt,
|
|
45
|
-
updatedAt: request.updatedAt,
|
|
46
|
-
state: request.state,
|
|
47
|
-
checkpointRef: request.checkpointRef,
|
|
48
|
-
resumable: request.resumable,
|
|
49
|
-
startedAt: request.startedAt,
|
|
50
|
-
endedAt: request.endedAt,
|
|
51
|
-
lastActivityAt: request.lastActivityAt,
|
|
52
|
-
currentAgentId: request.currentAgentId,
|
|
53
|
-
delegationChain: request.delegationChain,
|
|
54
|
-
runtimeSnapshot: request.runtimeSnapshot,
|
|
55
|
-
traceItems: request.traceItems,
|
|
56
|
-
runtimeTimeline: request.runtimeTimeline,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
36
|
export async function buildSessionInspectionRecord(input, sessionId) {
|
|
60
37
|
const [sessionSummary, meta, messages, requestSummaries] = await Promise.all([
|
|
61
38
|
input.getSession(sessionId),
|
|
62
|
-
input.persistence.
|
|
63
|
-
input.persistence.
|
|
64
|
-
input.persistence.
|
|
39
|
+
input.persistence.getSessionMeta(sessionId),
|
|
40
|
+
input.persistence.listSessionMessages(sessionId, 200),
|
|
41
|
+
input.persistence.listSessionRequests(sessionId),
|
|
65
42
|
]);
|
|
66
43
|
if (!sessionSummary || !meta) {
|
|
67
44
|
return null;
|
|
68
45
|
}
|
|
69
46
|
const latestRequestId = sessionSummary.latestRequestId;
|
|
70
47
|
const requests = await Promise.all(requestSummaries.map((request) => buildRequestInspectionRecord(input.persistence, request)));
|
|
71
|
-
const latestApprovals = await input.persistence.
|
|
48
|
+
const latestApprovals = await input.persistence.getRequestApprovals(sessionId, latestRequestId);
|
|
72
49
|
const pendingApproval = selectLatestPendingApproval(latestApprovals);
|
|
73
50
|
return {
|
|
74
51
|
sessionId,
|
|
@@ -91,47 +68,24 @@ export async function buildSessionInspectionRecord(input, sessionId) {
|
|
|
91
68
|
: undefined,
|
|
92
69
|
};
|
|
93
70
|
}
|
|
94
|
-
export async function buildThreadInspectionRecord(input, threadId) {
|
|
95
|
-
const session = await buildSessionInspectionRecord({
|
|
96
|
-
persistence: input.persistence,
|
|
97
|
-
getSession: async (sessionId) => {
|
|
98
|
-
const summary = await input.getSession(sessionId);
|
|
99
|
-
return summary
|
|
100
|
-
? { ...summary }
|
|
101
|
-
: null;
|
|
102
|
-
},
|
|
103
|
-
}, threadId);
|
|
104
|
-
return session ? { ...session } : null;
|
|
105
|
-
}
|
|
106
71
|
export async function listPublicApprovals(input, filter) {
|
|
107
|
-
const approvals = await input.persistence.listApprovals(
|
|
72
|
+
const approvals = await input.persistence.listApprovals({
|
|
73
|
+
status: filter?.status,
|
|
74
|
+
sessionId: filter?.sessionId ?? filter?.legacySessionId,
|
|
75
|
+
requestId: filter?.requestId ?? filter?.legacyRunId,
|
|
76
|
+
});
|
|
108
77
|
return approvals.map((approval) => toInspectableApprovalRecord(approval));
|
|
109
78
|
}
|
|
110
79
|
export async function getPublicApproval(input, approvalId) {
|
|
111
80
|
const approval = await input.persistence.getApproval(approvalId);
|
|
112
81
|
return approval ? toInspectableApprovalRecord(approval) : null;
|
|
113
82
|
}
|
|
114
|
-
export async function deleteThreadRecord(input, threadId) {
|
|
115
|
-
const thread = await input.getThread(threadId);
|
|
116
|
-
if (!thread) {
|
|
117
|
-
return false;
|
|
118
|
-
}
|
|
119
|
-
const activeRun = thread.requests.find((run) => !isTerminalRunState(run.state));
|
|
120
|
-
if (activeRun) {
|
|
121
|
-
throw new Error(`Cannot delete thread ${threadId} while run ${activeRun.requestId} is ${activeRun.state}`);
|
|
122
|
-
}
|
|
123
|
-
const deleted = await input.deleteThread(threadId);
|
|
124
|
-
if (deleted) {
|
|
125
|
-
await input.deleteThreadCheckpoints(threadId);
|
|
126
|
-
}
|
|
127
|
-
return deleted;
|
|
128
|
-
}
|
|
129
83
|
export async function deleteSessionRecord(input, sessionId) {
|
|
130
84
|
const session = await input.getSession(sessionId);
|
|
131
85
|
if (!session) {
|
|
132
86
|
return false;
|
|
133
87
|
}
|
|
134
|
-
const activeRequest = session.requests.find((request) => !
|
|
88
|
+
const activeRequest = session.requests.find((request) => !isTerminalRequestState(request.state));
|
|
135
89
|
if (activeRequest) {
|
|
136
90
|
throw new Error(`Cannot delete session ${sessionId} while request ${activeRequest.requestId} is ${activeRequest.state}`);
|
|
137
91
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import type { HarnessEvent, InvocationEnvelope, MessageContent,
|
|
2
|
-
import type {
|
|
1
|
+
import type { HarnessEvent, InvocationEnvelope, MessageContent, RequestResult, RequestStartOptions, WorkspaceBundle } from "../../../contracts/types.js";
|
|
2
|
+
import type { PersistedRequestInput } from "../../../persistence/types.js";
|
|
3
3
|
import type { PolicyEngine } from "../system/policy-engine.js";
|
|
4
4
|
type Binding = WorkspaceBundle["bindings"] extends Map<any, infer T> ? T : never;
|
|
5
|
-
type
|
|
5
|
+
type EnsureSessionStartedRuntime = {
|
|
6
6
|
persistence: {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
bootstrapRequest?: (input: {
|
|
8
|
+
sessionId: string;
|
|
9
9
|
agentId: string;
|
|
10
|
-
|
|
11
|
-
status:
|
|
10
|
+
requestId: string;
|
|
11
|
+
status: RequestResult["state"];
|
|
12
12
|
createdAt: string;
|
|
13
13
|
executionMode: string;
|
|
14
14
|
adapterKind: string;
|
|
@@ -18,29 +18,29 @@ type EnsureThreadStartedRuntime = {
|
|
|
18
18
|
requestId: string;
|
|
19
19
|
createdAt: string;
|
|
20
20
|
};
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
requestInput: PersistedRequestInput;
|
|
22
|
+
createSession: boolean;
|
|
23
23
|
startedAt?: string;
|
|
24
24
|
currentAgentId?: string;
|
|
25
25
|
delegationChain?: string[];
|
|
26
26
|
runtimeSnapshot?: import("../../../contracts/types.js").RuntimeSnapshot;
|
|
27
27
|
}) => Promise<void>;
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
createSession: (input: {
|
|
29
|
+
sessionId: string;
|
|
30
30
|
agentId: string;
|
|
31
|
-
|
|
32
|
-
status:
|
|
31
|
+
requestId: string;
|
|
32
|
+
status: RequestResult["state"];
|
|
33
33
|
createdAt: string;
|
|
34
34
|
}) => Promise<void>;
|
|
35
|
-
|
|
35
|
+
appendSessionMessage?: (sessionId: string, message: {
|
|
36
36
|
role: "user";
|
|
37
37
|
content: MessageContent;
|
|
38
38
|
requestId: string;
|
|
39
39
|
createdAt: string;
|
|
40
40
|
}) => Promise<void>;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
createRequest: (input: {
|
|
42
|
+
sessionId: string;
|
|
43
|
+
requestId: string;
|
|
44
44
|
agentId: string;
|
|
45
45
|
executionMode: string;
|
|
46
46
|
adapterKind: string;
|
|
@@ -50,41 +50,41 @@ type EnsureThreadStartedRuntime = {
|
|
|
50
50
|
delegationChain?: string[];
|
|
51
51
|
runtimeSnapshot?: import("../../../contracts/types.js").RuntimeSnapshot;
|
|
52
52
|
}) => Promise<void>;
|
|
53
|
-
|
|
53
|
+
saveRequestInput?: (sessionId: string, requestId: string, requestInput: PersistedRequestInput) => Promise<void>;
|
|
54
54
|
};
|
|
55
55
|
};
|
|
56
|
-
type
|
|
56
|
+
type PrepareRequestStartRuntime = EnsureSessionStartedRuntime & {
|
|
57
57
|
workspace: WorkspaceBundle;
|
|
58
58
|
policyEngine: PolicyEngine;
|
|
59
|
-
resolveSelectedAgentId: (input: MessageContent, requestedAgentId?: string,
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
resolveSelectedAgentId: (input: MessageContent, requestedAgentId?: string, sessionId?: string) => Promise<string>;
|
|
60
|
+
emitRequestCreated: (sessionId: string, requestId: string, payload: Record<string, unknown>) => Promise<HarnessEvent>;
|
|
61
|
+
acquireRequestSlot: (sessionId?: string, requestId?: string, activeState?: RequestResult["state"], priority?: number) => Promise<() => Promise<void>>;
|
|
62
62
|
};
|
|
63
|
-
export declare function
|
|
63
|
+
export declare function ensureSessionStarted(runtime: EnsureSessionStartedRuntime, input: {
|
|
64
64
|
selectedAgentId: string;
|
|
65
65
|
binding: Binding;
|
|
66
66
|
message: MessageContent;
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
requestInput: PersistedRequestInput;
|
|
68
|
+
existingSessionId?: string;
|
|
69
69
|
}): Promise<{
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
sessionId: string;
|
|
71
|
+
requestId: string;
|
|
72
72
|
createdAt: string;
|
|
73
|
-
|
|
73
|
+
isNewSession: boolean;
|
|
74
74
|
}>;
|
|
75
|
-
export declare function prepareRunStart(runtime:
|
|
76
|
-
options: Pick<
|
|
75
|
+
export declare function prepareRunStart(runtime: PrepareRequestStartRuntime, input: {
|
|
76
|
+
options: Pick<RequestStartOptions, "input" | "agentId" | "sessionId" | "priority">;
|
|
77
77
|
invocation: InvocationEnvelope;
|
|
78
|
-
|
|
78
|
+
requestCreatedPayload: (binding: Binding, selectedAgentId: string) => Record<string, unknown>;
|
|
79
79
|
}): Promise<{
|
|
80
80
|
binding: Binding;
|
|
81
81
|
selectedAgentId: string;
|
|
82
82
|
priority: number;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
sessionId: string;
|
|
84
|
+
requestId: string;
|
|
85
|
+
isNewSession: boolean;
|
|
86
|
+
requestCreatedEventPromise: Promise<HarnessEvent>;
|
|
87
|
+
releaseRequestSlotPromise: Promise<() => Promise<void>>;
|
|
88
88
|
}>;
|
|
89
89
|
export declare function defaultRequestedAgentId(agentId?: string): string;
|
|
90
90
|
export {};
|
|
@@ -1,38 +1,60 @@
|
|
|
1
1
|
import { AUTO_AGENT_ID } from "../../../contracts/types.js";
|
|
2
2
|
import { createPersistentId } from "../../../utils/id.js";
|
|
3
3
|
import { normalizeMessageContent } from "../../../utils/message-content.js";
|
|
4
|
-
import {
|
|
4
|
+
import { buildPersistedRequestInput, normalizeRequestPriority } from "./helpers.js";
|
|
5
5
|
import { getRequiredWorkspaceBinding } from "../bindings.js";
|
|
6
6
|
import { getBindingAdapterKind, getBindingRuntimeExecutionMode } from "../../support/compiled-binding.js";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
import { buildRequestRuntimeSnapshot } from "./inspection.js";
|
|
8
|
+
async function appendUserMessage(runtime, sessionId, message) {
|
|
9
|
+
await runtime.persistence.appendSessionMessage?.(sessionId, message);
|
|
10
|
+
}
|
|
11
|
+
async function saveRequestInput(runtime, sessionId, requestId, requestInput) {
|
|
12
|
+
await runtime.persistence.saveRequestInput?.(sessionId, requestId, requestInput);
|
|
13
|
+
}
|
|
14
|
+
async function createSessionRecord(runtime, sessionId, input) {
|
|
15
|
+
await runtime.persistence.createSession({
|
|
16
|
+
sessionId,
|
|
17
|
+
agentId: input.agentId,
|
|
18
|
+
requestId: input.requestId,
|
|
19
|
+
status: input.status,
|
|
20
|
+
createdAt: input.createdAt,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
async function createRequestRecord(runtime, sessionId, requestId, input) {
|
|
24
|
+
await runtime.persistence.createRequest({
|
|
25
|
+
sessionId,
|
|
26
|
+
requestId,
|
|
27
|
+
...input,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
export async function ensureSessionStarted(runtime, input) {
|
|
31
|
+
const { selectedAgentId, binding, message, requestInput, existingSessionId } = input;
|
|
32
|
+
const sessionId = existingSessionId ?? createPersistentId();
|
|
33
|
+
const requestId = createPersistentId();
|
|
12
34
|
const createdAt = new Date().toISOString();
|
|
13
|
-
const
|
|
35
|
+
const isNewSession = !existingSessionId;
|
|
14
36
|
const startedAt = createdAt;
|
|
15
37
|
const currentAgentId = selectedAgentId;
|
|
16
38
|
const delegationChain = [selectedAgentId];
|
|
17
|
-
const runtimeSnapshot =
|
|
39
|
+
const runtimeSnapshot = buildRequestRuntimeSnapshot(binding, { requestId });
|
|
18
40
|
const userMessage = {
|
|
19
41
|
role: "user",
|
|
20
42
|
content: normalizeMessageContent(message),
|
|
21
|
-
requestId
|
|
43
|
+
requestId,
|
|
22
44
|
createdAt,
|
|
23
45
|
};
|
|
24
|
-
if (typeof runtime.persistence.
|
|
25
|
-
await runtime.persistence.
|
|
26
|
-
|
|
46
|
+
if (typeof runtime.persistence.bootstrapRequest === "function") {
|
|
47
|
+
await runtime.persistence.bootstrapRequest({
|
|
48
|
+
sessionId,
|
|
27
49
|
agentId: binding.agent.id,
|
|
28
|
-
|
|
50
|
+
requestId,
|
|
29
51
|
status: "running",
|
|
30
52
|
createdAt,
|
|
31
53
|
executionMode: getBindingRuntimeExecutionMode(binding),
|
|
32
54
|
adapterKind: getBindingAdapterKind(binding),
|
|
33
55
|
userMessage,
|
|
34
|
-
|
|
35
|
-
|
|
56
|
+
requestInput,
|
|
57
|
+
createSession: isNewSession,
|
|
36
58
|
startedAt,
|
|
37
59
|
currentAgentId,
|
|
38
60
|
delegationChain,
|
|
@@ -40,20 +62,17 @@ export async function ensureThreadStarted(runtime, input) {
|
|
|
40
62
|
});
|
|
41
63
|
}
|
|
42
64
|
else {
|
|
43
|
-
if (
|
|
44
|
-
await runtime
|
|
45
|
-
threadId,
|
|
65
|
+
if (isNewSession) {
|
|
66
|
+
await createSessionRecord(runtime, sessionId, {
|
|
46
67
|
agentId: selectedAgentId,
|
|
47
|
-
|
|
68
|
+
requestId,
|
|
48
69
|
status: "running",
|
|
49
70
|
createdAt,
|
|
50
71
|
});
|
|
51
72
|
}
|
|
52
73
|
await Promise.all([
|
|
53
|
-
runtime
|
|
54
|
-
runtime
|
|
55
|
-
threadId,
|
|
56
|
-
runId,
|
|
74
|
+
appendUserMessage(runtime, sessionId, userMessage),
|
|
75
|
+
createRequestRecord(runtime, sessionId, requestId, {
|
|
57
76
|
agentId: binding.agent.id,
|
|
58
77
|
executionMode: getBindingRuntimeExecutionMode(binding),
|
|
59
78
|
adapterKind: getBindingAdapterKind(binding),
|
|
@@ -63,37 +82,37 @@ export async function ensureThreadStarted(runtime, input) {
|
|
|
63
82
|
delegationChain,
|
|
64
83
|
runtimeSnapshot,
|
|
65
84
|
}),
|
|
66
|
-
runtime
|
|
85
|
+
saveRequestInput(runtime, sessionId, requestId, requestInput),
|
|
67
86
|
]);
|
|
68
87
|
}
|
|
69
|
-
return {
|
|
88
|
+
return { sessionId, requestId, createdAt, isNewSession };
|
|
70
89
|
}
|
|
71
90
|
export async function prepareRunStart(runtime, input) {
|
|
72
|
-
const { options, invocation,
|
|
91
|
+
const { options, invocation, requestCreatedPayload } = input;
|
|
73
92
|
const selectedAgentId = await runtime.resolveSelectedAgentId(options.input, options.agentId, options.sessionId);
|
|
74
93
|
const binding = getRequiredWorkspaceBinding(runtime.workspace, selectedAgentId);
|
|
75
94
|
const policyDecision = runtime.policyEngine.evaluate(binding);
|
|
76
95
|
if (!policyDecision.allowed) {
|
|
77
96
|
throw new Error(`Policy evaluation blocked agent ${selectedAgentId}: ${policyDecision.reasons.join(", ")}`);
|
|
78
97
|
}
|
|
79
|
-
const priority =
|
|
80
|
-
const
|
|
81
|
-
const {
|
|
98
|
+
const priority = normalizeRequestPriority(options.priority);
|
|
99
|
+
const requestInput = buildPersistedRequestInput(options.input, invocation, priority);
|
|
100
|
+
const { sessionId, requestId, isNewSession } = await ensureSessionStarted(runtime, {
|
|
82
101
|
selectedAgentId,
|
|
83
102
|
binding,
|
|
84
103
|
message: options.input,
|
|
85
|
-
|
|
86
|
-
|
|
104
|
+
requestInput,
|
|
105
|
+
existingSessionId: options.sessionId,
|
|
87
106
|
});
|
|
88
107
|
return {
|
|
89
108
|
binding,
|
|
90
109
|
selectedAgentId,
|
|
91
110
|
priority,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
111
|
+
sessionId,
|
|
112
|
+
requestId,
|
|
113
|
+
isNewSession,
|
|
114
|
+
requestCreatedEventPromise: runtime.emitRequestCreated(sessionId, requestId, requestCreatedPayload(binding, selectedAgentId)),
|
|
115
|
+
releaseRequestSlotPromise: runtime.acquireRequestSlot(sessionId, requestId, "running", priority),
|
|
97
116
|
};
|
|
98
117
|
}
|
|
99
118
|
export function defaultRequestedAgentId(agentId) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RequestResult, SessionSummary } from "../../../contracts/types.js";
|
|
2
2
|
import type { RuntimePersistence } from "../../../persistence/types.js";
|
|
3
3
|
import type { ConcurrencyConfig, RecoveryConfig } from "../../../workspace/support/workspace-ref-utils.js";
|
|
4
4
|
import { type StartupRecoveryContext } from "./recovery.js";
|
|
@@ -10,25 +10,25 @@ export declare function initializeHarnessRuntime(input: {
|
|
|
10
10
|
healthMonitor: Startable | null;
|
|
11
11
|
scheduleBackgroundTask?: (task: Promise<void>) => void;
|
|
12
12
|
}): Promise<void>;
|
|
13
|
-
export declare function
|
|
13
|
+
export declare function recoverStartupRequests(input: {
|
|
14
14
|
recoveryConfig: RecoveryConfig;
|
|
15
15
|
persistence: RuntimePersistence;
|
|
16
16
|
createStartupRecoveryContext: () => StartupRecoveryContext;
|
|
17
|
-
|
|
17
|
+
reclaimExpiredClaimedRequests: (nowIso?: string) => Promise<void>;
|
|
18
18
|
}): Promise<void>;
|
|
19
|
-
export declare function
|
|
19
|
+
export declare function reclaimExpiredClaimedRequests(input: {
|
|
20
20
|
persistence: RuntimePersistence;
|
|
21
|
-
|
|
21
|
+
setRequestStateAndEmit: (sessionId: string, requestId: string, sequence: number, state: RequestResult["state"], options: {
|
|
22
22
|
previousState: string | null;
|
|
23
23
|
checkpointRef?: string | null;
|
|
24
24
|
error?: string;
|
|
25
25
|
}) => Promise<unknown>;
|
|
26
|
-
emit: (
|
|
26
|
+
emit: (sessionId: string, requestId: string, sequence: number, eventType: string, payload: Record<string, unknown>) => Promise<unknown>;
|
|
27
27
|
concurrencyConfig: ConcurrencyConfig;
|
|
28
|
-
|
|
28
|
+
getActiveRequestSlots: () => number;
|
|
29
29
|
}, nowIso?: string): Promise<void>;
|
|
30
|
-
export declare function
|
|
30
|
+
export declare function isStaleRunningRequest(input: {
|
|
31
31
|
persistence: RuntimePersistence;
|
|
32
32
|
concurrencyConfig: ConcurrencyConfig;
|
|
33
|
-
},
|
|
33
|
+
}, session: SessionSummary, nowMs?: number): Promise<boolean>;
|
|
34
34
|
export {};
|