badgr-agent-resume 0.1.0
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 +157 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +84 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +126 -0
- package/dist/index.js.map +1 -0
- package/package.json +16 -0
package/README.md
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# badgr-agent-resume
|
|
2
|
+
|
|
3
|
+
Add step-level checkpoints to agent runs so they survive crashes, timeouts, and restarts — without repeating completed steps.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { agentRun } from "badgr-agent-resume";
|
|
7
|
+
|
|
8
|
+
await agentRun("support-agent", async (run) => {
|
|
9
|
+
const plan = await run.step("create-plan", generatePlan);
|
|
10
|
+
const order = await run.step("fetch-order", () => fetchOrder(plan.id));
|
|
11
|
+
return await run.step("write-response", () => generateReply(order));
|
|
12
|
+
});
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**Free. No signup required.** Checkpoints are saved to `.badgr/runs/` on your machine.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## The problem it solves
|
|
20
|
+
|
|
21
|
+
Multi-step agents crash mid-run and restart from scratch. A 20-minute agent that fails at step 8 of 10 wastes 18 minutes of compute and re-runs side effects. `badgr-agent-resume` wraps each step with a checkpoint — if the run crashes, the next execution skips completed steps and picks up exactly where it left off.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Quick start
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install badgr-agent-resume
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { agentRun } from "badgr-agent-resume";
|
|
33
|
+
|
|
34
|
+
await agentRun("my-agent", async (run) => {
|
|
35
|
+
// Each step is checkpointed. On re-run, completed steps are skipped.
|
|
36
|
+
const data = await run.step("fetch-data", () => fetchFromApi());
|
|
37
|
+
const summary = await run.step("summarize", () => callLlm(data));
|
|
38
|
+
return await run.step("send-email", () => sendEmail(summary));
|
|
39
|
+
});
|
|
40
|
+
// Checkpoints saved to: .badgr/runs/my-agent-<timestamp>.json
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
If `summarize` crashes, re-running the script skips `fetch-data` (already done) and resumes from `summarize`.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## How checkpointing works
|
|
48
|
+
|
|
49
|
+
Each `run.step(name, fn)` call:
|
|
50
|
+
|
|
51
|
+
1. Checks `.badgr/runs/` for an existing run with this name
|
|
52
|
+
2. If the step was completed in a previous run, returns the saved output immediately
|
|
53
|
+
3. If not, executes `fn`, saves the output, and marks the step complete
|
|
54
|
+
4. If `fn` throws, the step is marked `failed` and the error is rethrown
|
|
55
|
+
|
|
56
|
+
Steps are identified by name, so renaming a step invalidates its checkpoint.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## API
|
|
61
|
+
|
|
62
|
+
### `agentRun(name, fn, options?)`
|
|
63
|
+
|
|
64
|
+
Runs an agent with checkpointing. Returns the final value of `fn`.
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
await agentRun(
|
|
68
|
+
"my-agent", // run name — used to find existing checkpoints
|
|
69
|
+
async (run) => {
|
|
70
|
+
return await run.step("step-name", async () => {
|
|
71
|
+
// your step logic
|
|
72
|
+
});
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
stateDir?: string; // where to save checkpoints (default: .badgr/runs)
|
|
76
|
+
}
|
|
77
|
+
);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### `run.step(name, fn)`
|
|
81
|
+
|
|
82
|
+
Executes a step with checkpointing. If the step completed in a previous run, `fn` is not called — the saved output is returned instead.
|
|
83
|
+
|
|
84
|
+
### `run.timeline()`
|
|
85
|
+
|
|
86
|
+
Returns a human-readable timeline of all steps:
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
create-plan completed 1.2s
|
|
90
|
+
fetch-order completed 0.4s
|
|
91
|
+
write-response running ...
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### `run.state()`
|
|
95
|
+
|
|
96
|
+
Returns the full run state as a typed object.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## CLI — inspect a saved run
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# Show the status of a saved run and resume instructions
|
|
104
|
+
npx badgr-agent-resume resume <run-id>
|
|
105
|
+
|
|
106
|
+
# Machine-readable JSON
|
|
107
|
+
npx badgr-agent-resume resume <run-id> --json
|
|
108
|
+
|
|
109
|
+
# Show optional hosted run history link
|
|
110
|
+
npx badgr-agent-resume connect
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## TypeScript API
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
import { agentRun, loadRun, formatTimeline } from "badgr-agent-resume";
|
|
119
|
+
|
|
120
|
+
// Load a saved run by ID
|
|
121
|
+
const state = await loadRun("my-agent-1718000000000");
|
|
122
|
+
|
|
123
|
+
// Format the timeline
|
|
124
|
+
console.log(formatTimeline(state));
|
|
125
|
+
// create-plan completed 1.2s
|
|
126
|
+
// fetch-order completed 0.4s
|
|
127
|
+
// write-response failed 0.1s Error: API timeout
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Types:**
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
interface AgentRunState {
|
|
134
|
+
id: string;
|
|
135
|
+
name: string;
|
|
136
|
+
createdAt: string;
|
|
137
|
+
updatedAt: string;
|
|
138
|
+
steps: RecordedStep[];
|
|
139
|
+
result?: unknown;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
interface RecordedStep<T = unknown> {
|
|
143
|
+
name: string;
|
|
144
|
+
status: "completed" | "failed" | "running";
|
|
145
|
+
startedAt: string;
|
|
146
|
+
finishedAt?: string;
|
|
147
|
+
output?: T;
|
|
148
|
+
error?: string;
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Requirements
|
|
155
|
+
|
|
156
|
+
- Node.js 18+
|
|
157
|
+
- TypeScript 5+ (for type definitions)
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createLogger, fireTelemetry } from "badgr-shared";
|
|
3
|
+
import { buildRunReport, loadRun, formatTimeline } from "./index.js";
|
|
4
|
+
fireTelemetry({ package: "badgr-agent-resume", command: process.argv[2] });
|
|
5
|
+
const [command, runId] = process.argv.slice(2);
|
|
6
|
+
const json = process.argv.includes("--json");
|
|
7
|
+
if (!command || command === "--help" || command === "-h") {
|
|
8
|
+
console.log(`badgr-agent-resume — local step checkpoint wrapper for resumable agent runs
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
npx badgr-agent-resume resume <run_id>
|
|
12
|
+
npx badgr-agent-resume resume <run_id> --json
|
|
13
|
+
npx badgr-agent-resume connect
|
|
14
|
+
|
|
15
|
+
Commands:
|
|
16
|
+
resume <run_id> Show the status of a saved run and resume instructions
|
|
17
|
+
connect Show the optional AI Badgr hosted run history link
|
|
18
|
+
|
|
19
|
+
Flags:
|
|
20
|
+
--json Output machine-readable JSON
|
|
21
|
+
|
|
22
|
+
Library usage (no CLI needed):
|
|
23
|
+
import { agentRun } from "badgr-agent-resume";
|
|
24
|
+
|
|
25
|
+
await agentRun("my-agent", async (run) => {
|
|
26
|
+
const plan = await run.step("create-plan", generatePlan);
|
|
27
|
+
const order = await run.step("fetch-order", () => fetchOrder(plan.id));
|
|
28
|
+
return run.step("write-response", () => generateReply(order));
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
Exit codes:
|
|
32
|
+
0 Run loaded successfully
|
|
33
|
+
1 Run not found or load error
|
|
34
|
+
2 Bad usage
|
|
35
|
+
|
|
36
|
+
No signup required. Hosted run history and alerts are optional.
|
|
37
|
+
|
|
38
|
+
Environment:
|
|
39
|
+
BADGR_TELEMETRY=0 Disable anonymous usage telemetry`);
|
|
40
|
+
process.exit(0);
|
|
41
|
+
}
|
|
42
|
+
if (command === "connect") {
|
|
43
|
+
console.log("Want hosted run history, remote checkpoints, email alerts, and shareable traces?");
|
|
44
|
+
console.log("https://aibadgr.com/agents/connect");
|
|
45
|
+
console.log("");
|
|
46
|
+
console.log("Signup is only required if you choose to upload traces or checkpoints.");
|
|
47
|
+
process.exit(0);
|
|
48
|
+
}
|
|
49
|
+
if (command !== "resume" || !runId) {
|
|
50
|
+
console.error(`Error: expected "resume <run_id>", got "${command ?? ""} ${runId ?? ""}".trim()`);
|
|
51
|
+
console.error("Usage: npx badgr-agent-resume resume <run_id> [--json]");
|
|
52
|
+
process.exit(2);
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const state = await loadRun(runId);
|
|
56
|
+
const report = buildRunReport(state);
|
|
57
|
+
const logger = createLogger(json);
|
|
58
|
+
if (json) {
|
|
59
|
+
logger.report(report);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
console.log(`Run: ${state.id} status: ${report.status}`);
|
|
63
|
+
console.log("");
|
|
64
|
+
console.log(formatTimeline(state));
|
|
65
|
+
const failed = state.steps.find((s) => s.status === "failed");
|
|
66
|
+
if (failed) {
|
|
67
|
+
console.log("");
|
|
68
|
+
console.log(`Failed step: ${failed.name}`);
|
|
69
|
+
if (failed.error)
|
|
70
|
+
console.log(`Error: ${failed.error}`);
|
|
71
|
+
console.log("");
|
|
72
|
+
console.log("Resume from where it stopped:");
|
|
73
|
+
console.log(` npx badgr-agent-resume resume ${state.id}`);
|
|
74
|
+
}
|
|
75
|
+
console.log("");
|
|
76
|
+
console.log("Optional: hosted run history and alerts:");
|
|
77
|
+
console.log(" npx badgr-agent-resume connect");
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type JsonReport } from "badgr-shared";
|
|
2
|
+
export type StepStatus = "completed" | "failed" | "running";
|
|
3
|
+
export interface RecordedStep<T = unknown> {
|
|
4
|
+
name: string;
|
|
5
|
+
status: StepStatus;
|
|
6
|
+
startedAt: string;
|
|
7
|
+
finishedAt?: string;
|
|
8
|
+
output?: T;
|
|
9
|
+
error?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface AgentRunState {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
createdAt: string;
|
|
15
|
+
updatedAt: string;
|
|
16
|
+
steps: RecordedStep[];
|
|
17
|
+
result?: unknown;
|
|
18
|
+
}
|
|
19
|
+
export interface AgentRunOptions {
|
|
20
|
+
runId?: string;
|
|
21
|
+
stateDir?: string;
|
|
22
|
+
resume?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface AgentRunContext {
|
|
25
|
+
id: string;
|
|
26
|
+
step<T>(name: string, fn: () => Promise<T> | T): Promise<T>;
|
|
27
|
+
timeline(): string;
|
|
28
|
+
state(): AgentRunState;
|
|
29
|
+
}
|
|
30
|
+
export declare function agentRun<T>(name: string, fn: (run: AgentRunContext) => Promise<T> | T, options?: AgentRunOptions): Promise<T>;
|
|
31
|
+
export declare function loadRun(runId: string, stateDir?: string): Promise<AgentRunState>;
|
|
32
|
+
export declare function formatTimeline(state: AgentRunState): string;
|
|
33
|
+
export declare function buildRunReport(state: AgentRunState): JsonReport;
|
|
34
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAA0D,KAAK,UAAU,EAAsB,MAAM,cAAc,CAAC;AAE3H,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE5D,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,OAAO;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,CAAC,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5D,QAAQ,IAAI,MAAM,CAAC;IACnB,KAAK,IAAI,aAAa,CAAC;CACxB;AAID,wBAAsB,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,CAAC,CAAC,CA4CvI;AAED,wBAAsB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,SAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAE3F;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAM3D;AAiCD,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,GAAG,UAAU,CAgB/D"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
import { BadgrToolError, createReport, reportStatusFromFindings } from "badgr-shared";
|
|
5
|
+
const DEFAULT_DIR = ".badgr";
|
|
6
|
+
export async function agentRun(name, fn, options = {}) {
|
|
7
|
+
const stateDir = resolve(options.stateDir ?? DEFAULT_DIR);
|
|
8
|
+
await mkdir(join(stateDir, "runs"), { recursive: true });
|
|
9
|
+
const runId = options.runId ?? await resolveLatestRunId(stateDir, name) ?? createRunId();
|
|
10
|
+
const path = statePath(stateDir, runId);
|
|
11
|
+
const state = options.resume !== false && existsSync(path)
|
|
12
|
+
? await readState(path)
|
|
13
|
+
: { id: runId, name, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), steps: [] };
|
|
14
|
+
const context = {
|
|
15
|
+
id: state.id,
|
|
16
|
+
async step(stepName, stepFn) {
|
|
17
|
+
const existing = state.steps.find((step) => step.name === stepName && step.status === "completed");
|
|
18
|
+
if (existing)
|
|
19
|
+
return existing.output;
|
|
20
|
+
const failedIndex = state.steps.findIndex((step) => step.name === stepName && step.status === "failed");
|
|
21
|
+
if (failedIndex >= 0)
|
|
22
|
+
state.steps.splice(failedIndex, 1);
|
|
23
|
+
const record = { name: stepName, status: "running", startedAt: new Date().toISOString() };
|
|
24
|
+
state.steps.push(record);
|
|
25
|
+
await persist(stateDir, state);
|
|
26
|
+
try {
|
|
27
|
+
const output = await stepFn();
|
|
28
|
+
record.status = "completed";
|
|
29
|
+
record.finishedAt = new Date().toISOString();
|
|
30
|
+
record.output = output;
|
|
31
|
+
await persist(stateDir, state);
|
|
32
|
+
return output;
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
record.status = "failed";
|
|
36
|
+
record.finishedAt = new Date().toISOString();
|
|
37
|
+
record.error = error instanceof Error ? error.message : String(error);
|
|
38
|
+
await persist(stateDir, state);
|
|
39
|
+
const message = `Run failed: ${state.id}\n\n${formatTimeline(state)}\n\nResume:\nnpx @aibadgr/agent-resume resume ${state.id}`;
|
|
40
|
+
throw new BadgrToolError(message, "AGENT_STEP_FAILED", { runId: state.id, failedStep: stepName });
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
timeline: () => formatTimeline(state),
|
|
44
|
+
state: () => structuredClone(state),
|
|
45
|
+
};
|
|
46
|
+
const result = await fn(context);
|
|
47
|
+
state.result = result;
|
|
48
|
+
await persist(stateDir, state);
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
export async function loadRun(runId, stateDir = DEFAULT_DIR) {
|
|
52
|
+
return readState(statePath(resolve(stateDir), runId));
|
|
53
|
+
}
|
|
54
|
+
export function formatTimeline(state) {
|
|
55
|
+
return state.steps.map((step) => {
|
|
56
|
+
if (step.status === "completed")
|
|
57
|
+
return `✓ ${step.name} completed`;
|
|
58
|
+
if (step.status === "failed")
|
|
59
|
+
return `✗ ${step.name} ${step.error ?? "failed"}`;
|
|
60
|
+
return `• ${step.name} running`;
|
|
61
|
+
}).join("\n");
|
|
62
|
+
}
|
|
63
|
+
async function persist(stateDir, state) {
|
|
64
|
+
state.updatedAt = new Date().toISOString();
|
|
65
|
+
await writeFile(statePath(stateDir, state.id), `${JSON.stringify(state, null, 2)}\n`);
|
|
66
|
+
await writeFile(join(stateDir, "runs", `${state.id}.steps.json`), `${JSON.stringify(state.steps, null, 2)}\n`);
|
|
67
|
+
await writeFile(join(stateDir, "runs", `${state.id}.checkpoint.json`), `${JSON.stringify(buildCheckpoint(state), null, 2)}\n`);
|
|
68
|
+
await writeFile(join(stateDir, `${safeName(state.name)}.latest`), state.id);
|
|
69
|
+
}
|
|
70
|
+
async function readState(path) {
|
|
71
|
+
return JSON.parse(await readFile(path, "utf8"));
|
|
72
|
+
}
|
|
73
|
+
async function resolveLatestRunId(stateDir, name) {
|
|
74
|
+
const path = join(stateDir, `${safeName(name)}.latest`);
|
|
75
|
+
if (!existsSync(path))
|
|
76
|
+
return undefined;
|
|
77
|
+
return (await readFile(path, "utf8")).trim();
|
|
78
|
+
}
|
|
79
|
+
function statePath(stateDir, runId) {
|
|
80
|
+
return join(stateDir, "runs", `${runId}.json`);
|
|
81
|
+
}
|
|
82
|
+
function safeName(name) {
|
|
83
|
+
return name.replace(/[^a-z0-9._-]+/gi, "_");
|
|
84
|
+
}
|
|
85
|
+
function createRunId() {
|
|
86
|
+
return `run_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
|
|
87
|
+
}
|
|
88
|
+
export function buildRunReport(state) {
|
|
89
|
+
const findings = buildFindings(state);
|
|
90
|
+
const status = reportStatusFromFindings(findings);
|
|
91
|
+
return createReport({
|
|
92
|
+
tool: "agent-resume",
|
|
93
|
+
reportId: `rpt_${state.id}`,
|
|
94
|
+
status,
|
|
95
|
+
summary: status === "failed" ? `Run failed at ${state.steps.find((step) => step.status === "failed")?.name ?? "unknown step"}` : "Run checkpoints are available locally",
|
|
96
|
+
findings,
|
|
97
|
+
recommendedActions: status === "failed"
|
|
98
|
+
? [`Resume failed run: npx @aibadgr/agent-resume resume ${state.id}`, "Connect for hosted run history and alerts"]
|
|
99
|
+
: ["Keep local checkpoints for reproducible agent runs", "Connect for hosted run history and alerts"],
|
|
100
|
+
nextCommand: "npx @aibadgr/agent-resume connect",
|
|
101
|
+
actionUrl: "https://aibadgr.com/agents/connect",
|
|
102
|
+
metadata: { runId: state.id, runName: state.name, stepCount: state.steps.length },
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function buildFindings(state) {
|
|
106
|
+
if (state.steps.length === 0)
|
|
107
|
+
return [{ severity: "warning", code: "AGENT_NO_STEPS_RECORDED", message: "No steps have been recorded yet." }];
|
|
108
|
+
return state.steps.map((step) => ({
|
|
109
|
+
severity: step.status === "failed" ? "error" : step.status === "running" ? "warning" : "info",
|
|
110
|
+
code: step.status === "failed" ? "AGENT_STEP_FAILED" : step.status === "running" ? "AGENT_STEP_INCOMPLETE" : "AGENT_STEP_COMPLETED",
|
|
111
|
+
message: step.status === "failed" ? `${step.name} ${step.error ?? "failed"}` : `${step.name} ${step.status}`,
|
|
112
|
+
details: { startedAt: step.startedAt, finishedAt: step.finishedAt },
|
|
113
|
+
}));
|
|
114
|
+
}
|
|
115
|
+
function buildCheckpoint(state) {
|
|
116
|
+
const completedSteps = state.steps.filter((step) => step.status === "completed");
|
|
117
|
+
const failedStep = state.steps.find((step) => step.status === "failed");
|
|
118
|
+
return {
|
|
119
|
+
runId: state.id,
|
|
120
|
+
runName: state.name,
|
|
121
|
+
lastSuccessfulStep: completedSteps.at(-1)?.name,
|
|
122
|
+
failedStep: failedStep?.name,
|
|
123
|
+
updatedAt: state.updatedAt,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "badgr-agent-resume",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Tiny TypeScript step checkpoint wrapper for resumable agent runs.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": { "badgr-agent-resume": "dist/cli.js" },
|
|
9
|
+
"exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" } },
|
|
10
|
+
"files": ["dist", "README.md"],
|
|
11
|
+
"scripts": { "build": "tsc -b", "typecheck": "tsc -b --pretty false", "test": "vitest run" },
|
|
12
|
+
"dependencies": { "badgr-shared": "0.1.1" },
|
|
13
|
+
"engines": { "node": ">=18.0.0" },
|
|
14
|
+
"keywords": ["agent", "resume", "checkpoint", "context", "workflow"],
|
|
15
|
+
"license": "MIT"
|
|
16
|
+
}
|