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 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,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -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
+ }