@botbotgo/agent-harness 0.0.291 → 0.0.293
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.292";
|
package/dist/package-version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.292";
|
|
@@ -17,6 +17,7 @@ export declare class FilePersistence implements RuntimePersistence {
|
|
|
17
17
|
private requestQueuePath;
|
|
18
18
|
private requestControlPath;
|
|
19
19
|
private traceItemsPath;
|
|
20
|
+
private writeSessionHead;
|
|
20
21
|
initialize(): Promise<void>;
|
|
21
22
|
sessionDir(sessionId: string): string;
|
|
22
23
|
requestDir(sessionId: string, requestId: string): string;
|
|
@@ -31,6 +31,24 @@ export class FilePersistence {
|
|
|
31
31
|
traceItemsPath(sessionId, requestId) {
|
|
32
32
|
return path.join(this.requestDir(sessionId, requestId), "trace-items.ndjson");
|
|
33
33
|
}
|
|
34
|
+
async writeSessionHead(sessionId, input) {
|
|
35
|
+
const sessionMetaPath = path.join(this.sessionDir(sessionId), "meta.json");
|
|
36
|
+
const sessionMeta = await readJson(sessionMetaPath);
|
|
37
|
+
await Promise.all([
|
|
38
|
+
writeJson(sessionMetaPath, {
|
|
39
|
+
...sessionMeta,
|
|
40
|
+
status: input.status,
|
|
41
|
+
latestRequestId: input.latestRequestId,
|
|
42
|
+
updatedAt: input.updatedAt,
|
|
43
|
+
}),
|
|
44
|
+
writeJson(this.sessionIndexPath(sessionId), {
|
|
45
|
+
sessionId,
|
|
46
|
+
status: input.status,
|
|
47
|
+
latestRequestId: input.latestRequestId,
|
|
48
|
+
updatedAt: input.updatedAt,
|
|
49
|
+
}),
|
|
50
|
+
]);
|
|
51
|
+
}
|
|
34
52
|
async initialize() {
|
|
35
53
|
await Promise.all([
|
|
36
54
|
"indexes/sessions",
|
|
@@ -74,11 +92,14 @@ export class FilePersistence {
|
|
|
74
92
|
await ensureDir(path.join(requestDir, "events"));
|
|
75
93
|
await ensureDir(path.join(requestDir, "approvals"));
|
|
76
94
|
const sessionMeta = await this.getSessionMeta(input.sessionId);
|
|
95
|
+
const parentRequestId = sessionMeta?.latestRequestId === input.requestId
|
|
96
|
+
? null
|
|
97
|
+
: sessionMeta?.latestRequestId ?? null;
|
|
77
98
|
const meta = {
|
|
78
99
|
requestId: input.requestId,
|
|
79
100
|
sessionId: input.sessionId,
|
|
80
101
|
agentId: input.agentId,
|
|
81
|
-
parentRequestId
|
|
102
|
+
parentRequestId,
|
|
82
103
|
executionMode: input.executionMode,
|
|
83
104
|
adapterKind: input.adapterKind ?? input.executionMode,
|
|
84
105
|
createdAt: input.createdAt,
|
|
@@ -139,6 +160,11 @@ export class FilePersistence {
|
|
|
139
160
|
workerStartedAt: null,
|
|
140
161
|
}),
|
|
141
162
|
]);
|
|
163
|
+
await this.writeSessionHead(input.sessionId, {
|
|
164
|
+
latestRequestId: input.requestId,
|
|
165
|
+
status: "running",
|
|
166
|
+
updatedAt: input.createdAt,
|
|
167
|
+
});
|
|
142
168
|
}
|
|
143
169
|
async setRequestState(sessionId, requestId, state, checkpointRef) {
|
|
144
170
|
const lifecyclePath = path.join(this.requestDir(sessionId, requestId), "lifecycle.json");
|
|
@@ -186,16 +212,9 @@ export class FilePersistence {
|
|
|
186
212
|
resumable: next.resumable,
|
|
187
213
|
updatedAt: now,
|
|
188
214
|
});
|
|
189
|
-
|
|
190
|
-
const sessionMeta = await readJson(sessionMetaPath);
|
|
191
|
-
sessionMeta.status = state;
|
|
192
|
-
sessionMeta.updatedAt = now;
|
|
193
|
-
sessionMeta.latestRequestId = requestId;
|
|
194
|
-
await writeJson(sessionMetaPath, sessionMeta);
|
|
195
|
-
await writeJson(this.sessionIndexPath(sessionId), {
|
|
196
|
-
sessionId,
|
|
197
|
-
status: state,
|
|
215
|
+
await this.writeSessionHead(sessionId, {
|
|
198
216
|
latestRequestId: requestId,
|
|
217
|
+
status: state,
|
|
199
218
|
updatedAt: now,
|
|
200
219
|
});
|
|
201
220
|
}
|
|
@@ -406,19 +425,20 @@ export class FilePersistence {
|
|
|
406
425
|
}
|
|
407
426
|
async getRequestInspection(sessionId, requestId) {
|
|
408
427
|
const inspection = await readJson(path.join(this.requestDir(sessionId, requestId), "inspection.json"));
|
|
428
|
+
const traceItems = await this.listRequestTraceItems(sessionId, requestId);
|
|
409
429
|
return {
|
|
410
430
|
...inspection,
|
|
411
|
-
traceItems
|
|
412
|
-
?? (Array.isArray(inspection.traceItems)
|
|
413
|
-
? inspection.traceItems
|
|
414
|
-
: Array.isArray(inspection.upstreamEvents)
|
|
415
|
-
? inspection.upstreamEvents
|
|
416
|
-
: []),
|
|
431
|
+
traceItems,
|
|
417
432
|
};
|
|
418
433
|
}
|
|
419
434
|
async updateRequestInspection(sessionId, requestId, patch) {
|
|
420
435
|
const inspectionPath = path.join(this.requestDir(sessionId, requestId), "inspection.json");
|
|
421
436
|
const current = await readJson(inspectionPath);
|
|
437
|
+
const traceItems = Array.isArray(current.traceItems)
|
|
438
|
+
? current.traceItems
|
|
439
|
+
: Array.isArray(current.upstreamEvents)
|
|
440
|
+
? current.upstreamEvents
|
|
441
|
+
: [];
|
|
422
442
|
await writeJson(inspectionPath, {
|
|
423
443
|
...current,
|
|
424
444
|
...(patch.endedAt !== undefined ? { endedAt: patch.endedAt } : {}),
|
|
@@ -426,7 +446,7 @@ export class FilePersistence {
|
|
|
426
446
|
...(patch.currentAgentId !== undefined ? { currentAgentId: patch.currentAgentId } : {}),
|
|
427
447
|
...(patch.delegationChain ? { delegationChain: patch.delegationChain } : {}),
|
|
428
448
|
...(patch.runtimeSnapshot !== undefined ? { runtimeSnapshot: patch.runtimeSnapshot } : {}),
|
|
429
|
-
traceItems
|
|
449
|
+
traceItems,
|
|
430
450
|
});
|
|
431
451
|
}
|
|
432
452
|
async appendRequestTraceItem(sessionId, requestId, item) {
|
|
@@ -436,11 +456,14 @@ export class FilePersistence {
|
|
|
436
456
|
const traceItemsPath = this.traceItemsPath(sessionId, requestId);
|
|
437
457
|
if (await fileExists(traceItemsPath)) {
|
|
438
458
|
const contents = await readFile(traceItemsPath, "utf8");
|
|
439
|
-
|
|
459
|
+
const traceItems = contents
|
|
440
460
|
.split("\n")
|
|
441
461
|
.map((line) => line.trim())
|
|
442
462
|
.filter((line) => line.length > 0)
|
|
443
463
|
.map((line) => JSON.parse(line));
|
|
464
|
+
if (traceItems.length > 0) {
|
|
465
|
+
return traceItems;
|
|
466
|
+
}
|
|
444
467
|
}
|
|
445
468
|
const inspection = await readJson(path.join(this.requestDir(sessionId, requestId), "inspection.json"));
|
|
446
469
|
return Array.isArray(inspection.traceItems)
|
|
@@ -568,6 +568,14 @@ export class SqlitePersistence {
|
|
|
568
568
|
args: [input.sessionId, "default", input.agentId, input.status, input.requestId, input.createdAt, input.createdAt],
|
|
569
569
|
});
|
|
570
570
|
}
|
|
571
|
+
else {
|
|
572
|
+
steps.push({
|
|
573
|
+
sql: `UPDATE sessions
|
|
574
|
+
SET status = ?, latest_request_id = ?, updated_at = ?
|
|
575
|
+
WHERE session_id = ?`,
|
|
576
|
+
args: [input.status, input.requestId, input.createdAt, input.sessionId],
|
|
577
|
+
});
|
|
578
|
+
}
|
|
571
579
|
steps.push({
|
|
572
580
|
sql: `INSERT OR REPLACE INTO requests
|
|
573
581
|
(request_id, session_id, agent_id, parent_request_id, execution_mode, adapter_kind, created_at, updated_at, state, previous_state, state_entered_at, last_transition_at, resumable, checkpoint_ref)
|
|
@@ -627,7 +635,10 @@ export class SqlitePersistence {
|
|
|
627
635
|
await this.executeTransaction(steps);
|
|
628
636
|
}
|
|
629
637
|
async createRequest(input) {
|
|
630
|
-
const
|
|
638
|
+
const sessionMeta = await this.getSessionMeta(input.sessionId);
|
|
639
|
+
const parentRequestId = sessionMeta?.latestRequestId === input.requestId
|
|
640
|
+
? null
|
|
641
|
+
: sessionMeta?.latestRequestId ?? null;
|
|
631
642
|
await mkdir(path.join(this.requestDir(input.sessionId, input.requestId), "events"), { recursive: true });
|
|
632
643
|
await this.execute(`INSERT OR REPLACE INTO requests
|
|
633
644
|
(request_id, session_id, agent_id, parent_request_id, execution_mode, adapter_kind, created_at, updated_at, state, previous_state, state_entered_at, last_transition_at, resumable, checkpoint_ref)
|
|
@@ -662,6 +673,9 @@ export class SqlitePersistence {
|
|
|
662
673
|
input.runtimeSnapshot ? JSON.stringify(input.runtimeSnapshot) : null,
|
|
663
674
|
"[]",
|
|
664
675
|
]);
|
|
676
|
+
await this.execute(`UPDATE sessions
|
|
677
|
+
SET status = ?, latest_request_id = ?, updated_at = ?
|
|
678
|
+
WHERE session_id = ?`, ["running", input.requestId, input.createdAt, input.sessionId]);
|
|
665
679
|
}
|
|
666
680
|
async setRequestState(sessionId, requestId, state, checkpointRef) {
|
|
667
681
|
const current = await this.getRequestLifecycle(sessionId, requestId);
|
|
@@ -50,10 +50,21 @@ export function createAcpStdioClient(options) {
|
|
|
50
50
|
if (!trimmed) {
|
|
51
51
|
continue;
|
|
52
52
|
}
|
|
53
|
-
|
|
53
|
+
let parsed;
|
|
54
|
+
try {
|
|
55
|
+
parsed = JSON.parse(trimmed);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
54
60
|
if (isNotification(parsed)) {
|
|
55
61
|
for (const listener of Array.from(listeners)) {
|
|
56
|
-
|
|
62
|
+
try {
|
|
63
|
+
listener(parsed);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// Ignore listener failures so one subscriber cannot tear down the transport.
|
|
67
|
+
}
|
|
57
68
|
}
|
|
58
69
|
continue;
|
|
59
70
|
}
|