@botbotgo/agent-harness 0.0.129 → 0.0.130
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 +4 -0
- package/README.zh.md +4 -0
- package/dist/contracts/runtime.d.ts +19 -0
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/runtime/harness/events/timeline.d.ts +2 -0
- package/dist/runtime/harness/events/timeline.js +52 -0
- package/dist/runtime/harness/index.d.ts +1 -0
- package/dist/runtime/harness/index.js +1 -0
- package/dist/runtime/harness/run/recovery.js +13 -11
- package/dist/runtime/harness/system/policy-engine.d.ts +5 -0
- package/dist/runtime/harness/system/policy-engine.js +5 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -109,7 +109,11 @@ Boundary documents live in:
|
|
|
109
109
|
|
|
110
110
|
- `docs/upstream-feature-matrix.md`
|
|
111
111
|
- `docs/product-boundary.md`
|
|
112
|
+
- `docs/runtime-blueprint-assessment.md`
|
|
113
|
+
- `docs/policy-engine-scope.md`
|
|
112
114
|
- `docs/acp-support-plan.md`
|
|
115
|
+
- `docs/recovery-policy-matrix.md`
|
|
116
|
+
- `docs/operator-timeline.md`
|
|
113
117
|
- `docs/feature-checklist.md`
|
|
114
118
|
- `docs/long-term-memory.md`
|
|
115
119
|
- `docs/app-task-pattern.md`
|
package/README.zh.md
CHANGED
|
@@ -109,7 +109,11 @@ AI 让 agent 逻辑、工具调用和工作流代码更容易生成,真正变
|
|
|
109
109
|
|
|
110
110
|
- `docs/upstream-feature-matrix.md`
|
|
111
111
|
- `docs/product-boundary.md`
|
|
112
|
+
- `docs/runtime-blueprint-assessment.md`
|
|
113
|
+
- `docs/policy-engine-scope.md`
|
|
112
114
|
- `docs/acp-support-plan.md`
|
|
115
|
+
- `docs/recovery-policy-matrix.md`
|
|
116
|
+
- `docs/operator-timeline.md`
|
|
113
117
|
- `docs/feature-checklist.md`
|
|
114
118
|
- `docs/long-term-memory.md`
|
|
115
119
|
- `docs/app-task-pattern.md`
|
|
@@ -40,6 +40,25 @@ export type HarnessEventProjection = {
|
|
|
40
40
|
shouldHandle?: (event: HarnessEvent) => boolean;
|
|
41
41
|
handleEvent: HarnessEventListener;
|
|
42
42
|
};
|
|
43
|
+
/**
|
|
44
|
+
* Operator-facing timeline item projected from persisted runtime events.
|
|
45
|
+
* This is an inspection convenience over runtime records, not a new execution protocol.
|
|
46
|
+
*/
|
|
47
|
+
export type RuntimeTimelineItem = {
|
|
48
|
+
eventId: string;
|
|
49
|
+
threadId: string;
|
|
50
|
+
runId: string;
|
|
51
|
+
eventType: HarnessEventType;
|
|
52
|
+
timestamp: string;
|
|
53
|
+
sequence: number;
|
|
54
|
+
source: HarnessEvent["source"];
|
|
55
|
+
kind: "run" | "queue" | "approval" | "recovery" | "artifact" | "other";
|
|
56
|
+
payload: Record<string, unknown>;
|
|
57
|
+
};
|
|
58
|
+
export type RuntimeTimelineProjectionOptions = {
|
|
59
|
+
threadId?: string;
|
|
60
|
+
runId?: string;
|
|
61
|
+
};
|
|
43
62
|
export type RuntimeEventSink = {
|
|
44
63
|
publish: (event: HarnessEvent) => void;
|
|
45
64
|
subscribe: (listener: HarnessEventListener) => () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.129";
|
package/dist/package-version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.129";
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
function classifyTimelineItem(event) {
|
|
2
|
+
switch (event.eventType) {
|
|
3
|
+
case "run.queued":
|
|
4
|
+
case "run.dequeued":
|
|
5
|
+
return "queue";
|
|
6
|
+
case "approval.requested":
|
|
7
|
+
case "approval.resolved":
|
|
8
|
+
return "approval";
|
|
9
|
+
case "run.resumed":
|
|
10
|
+
return "recovery";
|
|
11
|
+
case "artifact.created":
|
|
12
|
+
return "artifact";
|
|
13
|
+
case "run.created":
|
|
14
|
+
case "run.state.changed":
|
|
15
|
+
return "run";
|
|
16
|
+
default:
|
|
17
|
+
return "other";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function projectRuntimeTimeline(events, options = {}) {
|
|
21
|
+
const filtered = events.filter((event) => {
|
|
22
|
+
if (options.threadId && event.threadId !== options.threadId) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
if (options.runId && event.runId !== options.runId) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
return true;
|
|
29
|
+
});
|
|
30
|
+
return [...filtered]
|
|
31
|
+
.sort((left, right) => {
|
|
32
|
+
const timestampComparison = left.timestamp.localeCompare(right.timestamp);
|
|
33
|
+
if (timestampComparison !== 0) {
|
|
34
|
+
return timestampComparison;
|
|
35
|
+
}
|
|
36
|
+
if (left.sequence !== right.sequence) {
|
|
37
|
+
return left.sequence - right.sequence;
|
|
38
|
+
}
|
|
39
|
+
return left.eventId.localeCompare(right.eventId);
|
|
40
|
+
})
|
|
41
|
+
.map((event) => ({
|
|
42
|
+
eventId: event.eventId,
|
|
43
|
+
threadId: event.threadId,
|
|
44
|
+
runId: event.runId,
|
|
45
|
+
eventType: event.eventType,
|
|
46
|
+
timestamp: event.timestamp,
|
|
47
|
+
sequence: event.sequence,
|
|
48
|
+
source: event.source,
|
|
49
|
+
kind: classifyTimelineItem(event),
|
|
50
|
+
payload: event.payload,
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from "./events/event-bus.js";
|
|
2
2
|
export * from "./events/event-sink.js";
|
|
3
3
|
export * from "./events/events.js";
|
|
4
|
+
export * from "./events/timeline.js";
|
|
4
5
|
export * from "./system/health-monitor.js";
|
|
5
6
|
export * from "./run/helpers.js";
|
|
6
7
|
export * from "./system/inventory.js";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from "./events/event-bus.js";
|
|
2
2
|
export * from "./events/event-sink.js";
|
|
3
3
|
export * from "./events/events.js";
|
|
4
|
+
export * from "./events/timeline.js";
|
|
4
5
|
export * from "./system/health-monitor.js";
|
|
5
6
|
export * from "./run/helpers.js";
|
|
6
7
|
export * from "./system/inventory.js";
|
|
@@ -41,6 +41,17 @@ async function executeRecoveredRun(context, input) {
|
|
|
41
41
|
}
|
|
42
42
|
return true;
|
|
43
43
|
}
|
|
44
|
+
async function failResumingRecovery(context, thread, checkpointRef, error) {
|
|
45
|
+
await context.persistence.setRunState(thread.threadId, thread.latestRunId, "failed", checkpointRef);
|
|
46
|
+
await context.persistence.clearRecoveryIntent(thread.threadId, thread.latestRunId);
|
|
47
|
+
await context.emit(thread.threadId, thread.latestRunId, 101, "run.state.changed", {
|
|
48
|
+
previousState: "resuming",
|
|
49
|
+
state: "failed",
|
|
50
|
+
checkpointRef,
|
|
51
|
+
...(error ? { error } : {}),
|
|
52
|
+
});
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
44
55
|
export async function recoverQueuedStartupRun(context, thread) {
|
|
45
56
|
if (thread.status !== "queued") {
|
|
46
57
|
return false;
|
|
@@ -113,9 +124,7 @@ export async function recoverResumingStartupRun(context, thread) {
|
|
|
113
124
|
return true;
|
|
114
125
|
}
|
|
115
126
|
if (recoveryIntent.attempts >= context.recoveryConfig.maxRecoveryAttempts) {
|
|
116
|
-
|
|
117
|
-
await context.persistence.clearRecoveryIntent(thread.threadId, thread.latestRunId);
|
|
118
|
-
return true;
|
|
127
|
+
return failResumingRecovery(context, thread, recoveryIntent.checkpointRef, "recovery attempts exhausted");
|
|
119
128
|
}
|
|
120
129
|
await context.persistence.saveRecoveryIntent(thread.threadId, thread.latestRunId, {
|
|
121
130
|
...recoveryIntent,
|
|
@@ -143,14 +152,7 @@ export async function recoverResumingStartupRun(context, thread) {
|
|
|
143
152
|
catch (error) {
|
|
144
153
|
context.recordLlmFailure(startedAt);
|
|
145
154
|
if (recoveryIntent.attempts + 1 >= context.recoveryConfig.maxRecoveryAttempts) {
|
|
146
|
-
await context
|
|
147
|
-
await context.persistence.clearRecoveryIntent(thread.threadId, thread.latestRunId);
|
|
148
|
-
await context.emit(thread.threadId, thread.latestRunId, 101, "run.state.changed", {
|
|
149
|
-
previousState: "resuming",
|
|
150
|
-
state: "failed",
|
|
151
|
-
checkpointRef: recoveryIntent.checkpointRef,
|
|
152
|
-
error: error instanceof Error ? error.message : String(error),
|
|
153
|
-
});
|
|
155
|
+
await failResumingRecovery(context, thread, recoveryIntent.checkpointRef, error instanceof Error ? error.message : String(error));
|
|
154
156
|
}
|
|
155
157
|
}
|
|
156
158
|
return true;
|
|
@@ -4,6 +4,11 @@ export type PolicyEngineDecision = {
|
|
|
4
4
|
reasons: string[];
|
|
5
5
|
};
|
|
6
6
|
export declare class PolicyEngine {
|
|
7
|
+
/**
|
|
8
|
+
* Runtime governance gate for a compiled binding.
|
|
9
|
+
* This engine may allow or block execution with reasons, but it must not
|
|
10
|
+
* redefine upstream planning or execution semantics.
|
|
11
|
+
*/
|
|
7
12
|
evaluate(binding: CompiledAgentBinding): PolicyEngineDecision;
|
|
8
13
|
}
|
|
9
14
|
export { PolicyEngineDecision as GovernanceDecision, PolicyEngine as GovernanceEngine, };
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { getPolicyEvaluators } from "../../../extensions.js";
|
|
2
2
|
export class PolicyEngine {
|
|
3
|
+
/**
|
|
4
|
+
* Runtime governance gate for a compiled binding.
|
|
5
|
+
* This engine may allow or block execution with reasons, but it must not
|
|
6
|
+
* redefine upstream planning or execution semantics.
|
|
7
|
+
*/
|
|
3
8
|
evaluate(binding) {
|
|
4
9
|
const reasons = [];
|
|
5
10
|
let allowed = true;
|