tubeless 0.3.0 → 0.3.2

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.
Files changed (167) hide show
  1. package/README.md +1 -1
  2. package/dist/agent/agent-identity.d.ts +2 -0
  3. package/dist/agent/agent-identity.js +8 -0
  4. package/dist/agent/agent-identity.js.map +1 -0
  5. package/dist/agent/agent-state.d.ts +1 -0
  6. package/dist/agent/agent-state.js +3 -0
  7. package/dist/agent/agent-state.js.map +1 -1
  8. package/dist/agent/agent-types.d.ts +6 -0
  9. package/dist/agent/agent-types.js.map +1 -1
  10. package/dist/agent/agent.d.ts +3 -0
  11. package/dist/agent/agent.js +2 -0
  12. package/dist/agent/agent.js.map +1 -1
  13. package/dist/agent/checkpoint-calls.d.ts +8 -0
  14. package/dist/agent/checkpoint-calls.js +46 -0
  15. package/dist/agent/checkpoint-calls.js.map +1 -0
  16. package/dist/agent/checkpoint-codec.d.ts +3 -0
  17. package/dist/agent/checkpoint-codec.js +108 -0
  18. package/dist/agent/checkpoint-codec.js.map +1 -0
  19. package/dist/agent/checkpoint-format.d.ts +80 -0
  20. package/dist/agent/checkpoint-format.js +116 -0
  21. package/dist/agent/checkpoint-format.js.map +1 -0
  22. package/dist/agent/checkpoint-key.d.ts +1 -0
  23. package/dist/agent/checkpoint-key.js +6 -0
  24. package/dist/agent/checkpoint-key.js.map +1 -0
  25. package/dist/agent/checkpoint-session.d.ts +38 -0
  26. package/dist/agent/checkpoint-session.js +226 -0
  27. package/dist/agent/checkpoint-session.js.map +1 -0
  28. package/dist/agent/checkpoint-types.d.ts +31 -0
  29. package/dist/agent/checkpoint-types.js +2 -0
  30. package/dist/agent/checkpoint-types.js.map +1 -0
  31. package/dist/agent/compile-agent.js +11 -10
  32. package/dist/agent/compile-agent.js.map +1 -1
  33. package/dist/agent/decision.d.ts +1 -1
  34. package/dist/agent/decision.js +2 -2
  35. package/dist/agent/decision.js.map +1 -1
  36. package/dist/agent/default-tools.d.ts +6 -6
  37. package/dist/agent/default-tools.js +12 -9
  38. package/dist/agent/default-tools.js.map +1 -1
  39. package/dist/agent/execution-scope.d.ts +21 -6
  40. package/dist/agent/execution-scope.js +73 -17
  41. package/dist/agent/execution-scope.js.map +1 -1
  42. package/dist/agent/invocation.d.ts +13 -4
  43. package/dist/agent/invocation.js +47 -3
  44. package/dist/agent/invocation.js.map +1 -1
  45. package/dist/agent/memory-checkpoint-store.d.ts +3 -0
  46. package/dist/agent/memory-checkpoint-store.js +37 -0
  47. package/dist/agent/memory-checkpoint-store.js.map +1 -0
  48. package/dist/agent/model-agent.d.ts +4 -0
  49. package/dist/agent/model-agent.js.map +1 -1
  50. package/dist/agent/node-environment.d.ts +10 -2
  51. package/dist/agent/node-environment.js +9 -4
  52. package/dist/agent/node-environment.js.map +1 -1
  53. package/dist/agent/node.d.ts +2 -0
  54. package/dist/agent/node.js +1 -0
  55. package/dist/agent/node.js.map +1 -1
  56. package/dist/agent/pipeline-tool.d.ts +3 -0
  57. package/dist/agent/pipeline-tool.js +6 -0
  58. package/dist/agent/pipeline-tool.js.map +1 -1
  59. package/dist/agent/sqlite-checkpoint-store.d.ts +8 -0
  60. package/dist/agent/sqlite-checkpoint-store.js +117 -0
  61. package/dist/agent/sqlite-checkpoint-store.js.map +1 -0
  62. package/dist/agent/tools.d.ts +5 -0
  63. package/dist/agent/tools.js +7 -2
  64. package/dist/agent/tools.js.map +1 -1
  65. package/dist/agent/turn.d.ts +2 -9
  66. package/dist/agent/turn.js +64 -16
  67. package/dist/agent/turn.js.map +1 -1
  68. package/dist/core/child-execution.d.ts +4 -0
  69. package/dist/core/child-execution.js +26 -10
  70. package/dist/core/child-execution.js.map +1 -1
  71. package/dist/core/execution-scope.d.ts +11 -1
  72. package/dist/core/execution-scope.js +7 -6
  73. package/dist/core/execution-scope.js.map +1 -1
  74. package/dist/core/iteration.js +2 -0
  75. package/dist/core/iteration.js.map +1 -1
  76. package/dist/core/pipeline-steps.js +8 -3
  77. package/dist/core/pipeline-steps.js.map +1 -1
  78. package/dist/core/prepared-options.d.ts +3 -1
  79. package/dist/core/prepared-options.js +5 -1
  80. package/dist/core/prepared-options.js.map +1 -1
  81. package/dist/project/project-registry.js +4 -0
  82. package/dist/project/project-registry.js.map +1 -1
  83. package/dist/run-store/run-history.d.ts +53 -0
  84. package/dist/run-store/run-history.js +270 -0
  85. package/dist/run-store/run-history.js.map +1 -0
  86. package/dist/run-store/run-projection.js +9 -0
  87. package/dist/run-store/run-projection.js.map +1 -1
  88. package/dist/run-store/run-store-schema.d.ts +7 -0
  89. package/dist/run-store/run-store-schema.js +148 -0
  90. package/dist/run-store/run-store-schema.js.map +1 -0
  91. package/dist/run-store/run-store-sqlite.js +7 -1
  92. package/dist/run-store/run-store-sqlite.js.map +1 -1
  93. package/dist/run-store/run-store.d.ts +11 -1
  94. package/dist/run-store/run-store.js.map +1 -1
  95. package/dist/studio/run-store-ui-api.d.ts +1 -1
  96. package/dist/studio/run-store-ui-api.js +44 -10
  97. package/dist/studio/run-store-ui-api.js.map +1 -1
  98. package/dist/studio/run-store-ui-client-browser.js +4 -2
  99. package/dist/studio/run-store-ui-client-transport.d.ts +11 -9
  100. package/dist/studio/run-store-ui-client-transport.js +54 -216
  101. package/dist/studio/run-store-ui-client-transport.js.map +1 -1
  102. package/dist/studio/run-store-ui-client.d.ts +15 -25
  103. package/dist/studio/run-store-ui-client.js +59 -306
  104. package/dist/studio/run-store-ui-client.js.map +1 -1
  105. package/dist/studio/run-store-ui-data-controller.d.ts +30 -5
  106. package/dist/studio/run-store-ui-data-controller.js +123 -70
  107. package/dist/studio/run-store-ui-data-controller.js.map +1 -1
  108. package/dist/studio/run-store-ui-definitions.d.ts +21 -5
  109. package/dist/studio/run-store-ui-definitions.js +53 -14
  110. package/dist/studio/run-store-ui-definitions.js.map +1 -1
  111. package/dist/studio/run-store-ui-graph-layout.d.ts +32 -0
  112. package/dist/studio/run-store-ui-graph-layout.js +77 -0
  113. package/dist/studio/run-store-ui-graph-layout.js.map +1 -0
  114. package/dist/studio/run-store-ui-graph.d.ts +10 -0
  115. package/dist/studio/run-store-ui-graph.js +546 -0
  116. package/dist/studio/run-store-ui-graph.js.map +1 -0
  117. package/dist/studio/run-store-ui-page.js +117 -0
  118. package/dist/studio/run-store-ui-page.js.map +1 -1
  119. package/dist/studio/run-store-ui-protocol.js +2 -32
  120. package/dist/studio/run-store-ui-protocol.js.map +1 -1
  121. package/dist/studio/run-store-ui-resource.d.ts +8 -0
  122. package/dist/studio/run-store-ui-resource.js +53 -0
  123. package/dist/studio/run-store-ui-resource.js.map +1 -0
  124. package/dist/studio/run-store-ui-schema.d.ts +52 -0
  125. package/dist/studio/run-store-ui-schema.js +132 -0
  126. package/dist/studio/run-store-ui-schema.js.map +1 -0
  127. package/dist/studio/run-store-ui-state.d.ts +6 -3
  128. package/dist/studio/run-store-ui-state.js +97 -4
  129. package/dist/studio/run-store-ui-state.js.map +1 -1
  130. package/dist/studio/run-store-ui-steps.d.ts +19 -0
  131. package/dist/studio/run-store-ui-steps.js +58 -0
  132. package/dist/studio/run-store-ui-steps.js.map +1 -0
  133. package/dist/tracing/tracing-codec.d.ts +1 -3
  134. package/dist/tracing/tracing-codec.js +1 -5
  135. package/dist/tracing/tracing-codec.js.map +1 -1
  136. package/dist/tracing/tracing-contracts.d.ts +8 -0
  137. package/dist/tracing/tracing-contracts.js.map +1 -1
  138. package/dist/tracing/tracing-internal.js +3 -0
  139. package/dist/tracing/tracing-internal.js.map +1 -1
  140. package/dist/tracing/tracing-schema.d.ts +142 -56
  141. package/dist/tracing/tracing-schema.js +21 -14
  142. package/dist/tracing/tracing-schema.js.map +1 -1
  143. package/dist/tracing/wire-schema.d.ts +1 -1
  144. package/dist/tracing/wire-schema.js.map +1 -1
  145. package/dist/utilities/abort.d.ts +6 -0
  146. package/dist/utilities/abort.js +9 -2
  147. package/dist/utilities/abort.js.map +1 -1
  148. package/dist/utilities/retry.d.ts +5 -0
  149. package/dist/utilities/retry.js +6 -3
  150. package/dist/utilities/retry.js.map +1 -1
  151. package/docs/agent-guide.md +23 -6
  152. package/docs/agents.md +120 -9
  153. package/docs/api-reference.md +53 -44
  154. package/docs/api-report.json +22 -11
  155. package/docs/child-pipeline-composition.md +5 -2
  156. package/docs/concepts.md +3 -1
  157. package/docs/declarative-pipelines.md +3 -1
  158. package/docs/recipes.md +7 -2
  159. package/docs/studio.md +44 -11
  160. package/examples/agent-durable.ts +82 -0
  161. package/examples/project/tubeless.project.ts +3 -1
  162. package/package.json +7 -6
  163. package/skills/tubeless/SKILL.md +18 -5
  164. package/dist/run-store/run-store-codec.d.ts +0 -6
  165. package/dist/run-store/run-store-codec.js +0 -42
  166. package/dist/run-store/run-store-codec.js.map +0 -1
  167. package/dist/studio/run-store-ui-client-browser.d.ts +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint-format.js","sourceRoot":"","sources":["../../src/agent/checkpoint-format.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentLimits, AgentOutcome, Tools } from \"./agent-types.js\";\n\nexport interface StoredBudget {\n depth: number;\n limits: Required<AgentLimits>;\n maxCalls: number;\n maxDecisions: number;\n}\nexport type CallOutcome = AgentOutcome<Tools>;\nexport type SavedCall = {\n id: string;\n tool: string;\n replay: \"safe\" | \"unsafe\";\n} & (\n | { kind: \"handler\"; input: unknown; validatedOptions?: never }\n | { kind: \"pipeline\"; input: object; validatedOptions: object }\n) &\n (\n | { status: \"pending\" | \"running\"; outcome?: never }\n | { status: \"completed\"; outcome: CallOutcome }\n );\nexport interface SavedDecision {\n state: unknown;\n calls: SavedCall[];\n admitted: boolean;\n}\ninterface AgentSnapshot {\n metadata: {\n definition: string;\n implementationVersion?: string;\n options: object;\n environment: string;\n cwd: string;\n cache: \"use\" | \"recompute\" | \"bypass\";\n };\n execution: { state: unknown; turn: number; stateVersion: number; calls: number };\n}\nexport type SavedAgent = AgentSnapshot &\n (\n | { phase: \"decide\"; decision?: never; result?: never; failure?: never }\n | { phase: \"calls\"; decision: SavedDecision; result?: never; failure?: never }\n | { phase: \"completed\"; result: unknown; decision?: never; failure?: never }\n | {\n phase: \"failed\";\n failure: { code: string; message: string };\n decision?: never;\n result?: never;\n }\n );\nexport interface Checkpoint {\n version: 1;\n agents: Record<string, SavedAgent>;\n budgets: Record<string, StoredBudget>;\n}\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return (\n value !== null &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null)\n );\n}\nfunction natural(value: unknown): value is number {\n return typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0;\n}\nfunction options(value: unknown): value is object {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\nfunction failure(value: unknown): boolean {\n return record(value) && typeof value.code === \"string\" && typeof value.message === \"string\";\n}\n\nfunction checkCall(call: unknown, admitted: boolean, ids: Set<string>): void {\n if (\n !record(call) ||\n typeof call.id !== \"string\" ||\n !call.id.trim() ||\n call.id.length > 256 ||\n ids.has(call.id) ||\n typeof call.tool !== \"string\" ||\n !/^[A-Za-z][A-Za-z0-9_-]{0,127}$/.test(call.tool) ||\n ![\"handler\", \"pipeline\"].includes(String(call.kind)) ||\n ![\"safe\", \"unsafe\"].includes(String(call.replay)) ||\n ![\"pending\", \"running\", \"completed\"].includes(String(call.status)) ||\n !Object.hasOwn(call, \"input\")\n )\n throw new Error(\"Invalid saved call\");\n ids.add(call.id);\n if (call.kind === \"pipeline\" && (!options(call.input) || !options(call.validatedOptions)))\n throw new Error(\"Invalid saved pipeline options\");\n if (!admitted && call.status !== \"pending\") throw new Error(\"Unadmitted call has started\");\n if (call.status === \"completed\") {\n const outcome = call.outcome;\n if (\n !record(outcome) ||\n outcome.id !== call.id ||\n outcome.tool !== call.tool ||\n typeof outcome.ok !== \"boolean\" ||\n (outcome.ok ? !Object.hasOwn(outcome, \"value\") : !failure(outcome.error))\n )\n throw new Error(\"Invalid saved call outcome\");\n }\n}\n\nfunction checkAgent(agent: unknown): void {\n if (!record(agent) || !record(agent.metadata) || !record(agent.execution))\n throw new Error(\"Invalid saved agent\");\n const { metadata, execution } = agent;\n if (\n typeof metadata.definition !== \"string\" ||\n typeof metadata.environment !== \"string\" ||\n typeof metadata.cwd !== \"string\" ||\n !options(metadata.options) ||\n (metadata.implementationVersion !== undefined &&\n typeof metadata.implementationVersion !== \"string\") ||\n ![\"use\", \"recompute\", \"bypass\"].includes(String(metadata.cache))\n )\n throw new Error(\"Invalid saved agent metadata\");\n if (\n !Object.hasOwn(execution, \"state\") ||\n !natural(execution.turn) ||\n execution.turn < 1 ||\n !natural(execution.stateVersion) ||\n !natural(execution.calls) ||\n ![\"decide\", \"calls\", \"completed\", \"failed\"].includes(String(agent.phase))\n )\n throw new Error(\"Invalid saved agent execution\");\n if (agent.phase === \"completed\" && !Object.hasOwn(agent, \"result\"))\n throw new Error(\"Missing saved agent result\");\n if (agent.phase === \"failed\" && !failure(agent.failure))\n throw new Error(\"Invalid saved agent failure\");\n if (agent.phase === \"calls\") {\n const decision = agent.decision;\n if (\n !record(decision) ||\n !Object.hasOwn(decision, \"state\") ||\n !Array.isArray(decision.calls) ||\n decision.calls.length === 0 ||\n typeof decision.admitted !== \"boolean\"\n )\n throw new Error(\"Invalid saved call batch\");\n const ids = new Set<string>();\n for (const call of decision.calls) checkCall(call, decision.admitted, ids);\n }\n}\n\nfunction checkBudget(budget: unknown): void {\n if (\n !record(budget) ||\n !natural(budget.depth) ||\n !natural(budget.maxCalls) ||\n !natural(budget.maxDecisions) ||\n !record(budget.limits)\n )\n throw new Error(\"Invalid saved agent budget\");\n for (const name of [\n \"maxTurns\",\n \"maxCalls\",\n \"maxDecisions\",\n \"maxDepth\",\n \"maxConcurrency\",\n ] as const) {\n const bound = budget.limits[name];\n if (!natural(bound) || (![\"maxCalls\", \"maxDepth\"].includes(name) && bound === 0))\n throw new Error(\"Invalid saved agent limits\");\n }\n if (\n budget.maxCalls > Number(budget.limits.maxCalls) ||\n budget.maxDecisions > Number(budget.limits.maxDecisions)\n )\n throw new Error(\"Saved agent budget exceeds its limits\");\n}\n\n/** Validate receipts and counters before treating decoded storage as prepared work. */\nexport function checkedCheckpoint(value: unknown): Checkpoint {\n if (!record(value) || value.version !== 1 || !record(value.agents) || !record(value.budgets))\n throw new Error(\"Invalid agent checkpoint envelope\");\n for (const [key, agent] of Object.entries(value.agents)) {\n checkAgent(agent);\n if (!Object.hasOwn(value.budgets, key)) throw new Error(\"Missing saved agent budget\");\n }\n for (const budget of Object.values(value.budgets)) checkBudget(budget);\n // SAFETY: metadata, execution counters, call receipts and budget contracts were checked above.\n return value as unknown as Checkpoint;\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function checkCheckpointKey(key: string): void;
@@ -0,0 +1,6 @@
1
+ import { agentError } from "./agent-state.js";
2
+ export function checkCheckpointKey(key) {
3
+ if (typeof key !== "string" || !key.trim() || key.length > 4096)
4
+ throw agentError("TUBELESS_AGENT_INVALID_CHECKPOINT_KEY", "Agent execution key must be nonblank and at most 4096 characters");
5
+ }
6
+ //# sourceMappingURL=checkpoint-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint-key.js","sourceRoot":"","sources":["../../src/agent/checkpoint-key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,MAAM,GAAG,IAAI;QAC7D,MAAM,UAAU,CACd,uCAAuC,EACvC,kEAAkE,CACnE,CAAC;AACN,CAAC","sourcesContent":["import { agentError } from \"./agent-state.js\";\n\nexport function checkCheckpointKey(key: string): void {\n if (typeof key !== \"string\" || !key.trim() || key.length > 4096)\n throw agentError(\n \"TUBELESS_AGENT_INVALID_CHECKPOINT_KEY\",\n \"Agent execution key must be nonblank and at most 4096 characters\"\n );\n}\n"]}
@@ -0,0 +1,38 @@
1
+ import type { AgentCheckpointCodec, AgentCheckpointStore } from "./checkpoint-types.js";
2
+ import type { CallOutcome, SavedAgent, SavedCall, SavedDecision, StoredBudget } from "./checkpoint-format.js";
3
+ export interface BudgetReference {
4
+ key: string;
5
+ id: string;
6
+ }
7
+ /** One owner for acknowledged state transitions and budgets across a durable subtree. */
8
+ export declare class AgentCheckpointSession {
9
+ #private;
10
+ readonly key: string;
11
+ private readonly lease;
12
+ private readonly codec;
13
+ private constructor();
14
+ static open(store: AgentCheckpointStore, key: string, codec?: AgentCheckpointCodec): Promise<AgentCheckpointSession>;
15
+ private roundTrip;
16
+ agent(key: string): SavedAgent | undefined;
17
+ decision(key: string): SavedDecision | undefined;
18
+ budget(key: string): Readonly<StoredBudget>;
19
+ enter(key: string, metadata: SavedAgent["metadata"], budget: Pick<StoredBudget, "depth" | "limits">, initialize: () => SavedAgent["execution"]): Promise<SavedAgent>;
20
+ private charge;
21
+ reserve(budgets: readonly BudgetReference[], kind: "maxCalls" | "maxDecisions", count: number): Promise<void>;
22
+ acceptDecision(key: string, state: unknown, calls: SavedCall[]): Promise<void>;
23
+ admitCalls(key: string, budgets: readonly BudgetReference[], count: number): Promise<void>;
24
+ startCall(key: string, id: string, replay: "safe" | "unsafe"): Promise<{
25
+ kind: "run";
26
+ } | {
27
+ kind: "outcome";
28
+ outcome: CallOutcome;
29
+ reused: boolean;
30
+ }>;
31
+ completeCall(key: string, id: string, outcome: CallOutcome): Promise<void>;
32
+ private changeCall;
33
+ advance(key: string, execution: SavedAgent["execution"]): Promise<void>;
34
+ finish(key: string, result: unknown): Promise<void>;
35
+ fail(key: string, error: unknown, signal?: AbortSignal): Promise<void>;
36
+ private update;
37
+ close(): Promise<void>;
38
+ }
@@ -0,0 +1,226 @@
1
+ import { agentError, limit } from "./agent-state.js";
2
+ import { plainAgentCheckpointCodec } from "./checkpoint-codec.js";
3
+ import { checkCheckpointKey } from "./checkpoint-key.js";
4
+ import { checkedCheckpoint } from "./checkpoint-format.js";
5
+ function callingAgent(checkpoint, key) {
6
+ const saved = checkpoint.agents[key];
7
+ if (!saved || saved.phase !== "calls")
8
+ throw new Error("Agent has no accepted call batch");
9
+ return saved;
10
+ }
11
+ /** One owner for acknowledged state transitions and budgets across a durable subtree. */
12
+ export class AgentCheckpointSession {
13
+ key;
14
+ lease;
15
+ codec;
16
+ #checkpoint;
17
+ #tail = Promise.resolve();
18
+ #failure;
19
+ constructor(key, lease, codec, checkpoint) {
20
+ this.key = key;
21
+ this.lease = lease;
22
+ this.codec = codec;
23
+ this.#checkpoint = checkpoint;
24
+ }
25
+ static async open(store, key, codec = plainAgentCheckpointCodec) {
26
+ checkCheckpointKey(key);
27
+ const lease = await store.acquire(key);
28
+ try {
29
+ const bytes = await lease.read();
30
+ const checkpoint = bytes === undefined
31
+ ? { version: 1, agents: {}, budgets: {} }
32
+ : checkedCheckpoint(codec.decode(bytes));
33
+ return new AgentCheckpointSession(key, lease, codec, checkpoint);
34
+ }
35
+ catch (error) {
36
+ await lease.close();
37
+ throw error;
38
+ }
39
+ }
40
+ roundTrip(value) {
41
+ const encoded = this.codec.encode(value);
42
+ const decoded = this.codec.decode(encoded);
43
+ if (this.codec.encode(decoded) !== encoded)
44
+ throw agentError("TUBELESS_AGENT_CHECKPOINT_CODEC", "Agent checkpoint codec must round-trip deterministically");
45
+ // SAFETY: codecs promise lossless round trips; the default checks finite plain data.
46
+ return { encoded, decoded: decoded };
47
+ }
48
+ agent(key) {
49
+ const value = this.#checkpoint.agents[key];
50
+ return value === undefined ? undefined : this.roundTrip(value).decoded;
51
+ }
52
+ decision(key) {
53
+ const saved = this.agent(key);
54
+ return saved?.phase === "calls" ? saved.decision : undefined;
55
+ }
56
+ budget(key) {
57
+ const saved = this.#checkpoint.budgets[key];
58
+ if (!saved)
59
+ throw new Error("Saved agent budget disappeared");
60
+ return { ...saved, limits: { ...saved.limits } };
61
+ }
62
+ async enter(key, metadata, budget, initialize) {
63
+ const saved = this.agent(key);
64
+ if (saved) {
65
+ const restored = this.budget(key);
66
+ if (this.codec.encode(saved.metadata) !== this.codec.encode(metadata))
67
+ throw agentError("TUBELESS_AGENT_CHECKPOINT_MISMATCH", "Agent checkpoint definition, inputs or workspace differ; use a new execution key");
68
+ if (this.codec.encode({ depth: restored.depth, limits: restored.limits }) !==
69
+ this.codec.encode(budget))
70
+ throw agentError("TUBELESS_AGENT_CHECKPOINT_MISMATCH", "Saved agent limits or delegation depth differ");
71
+ return saved;
72
+ }
73
+ await this.update((checkpoint) => {
74
+ checkpoint.budgets[key] = { ...budget, maxCalls: 0, maxDecisions: 0 };
75
+ checkpoint.agents[key] = { metadata, execution: initialize(), phase: "decide" };
76
+ });
77
+ const entered = this.agent(key);
78
+ if (!entered)
79
+ throw new Error("Saved agent disappeared");
80
+ return entered;
81
+ }
82
+ charge(checkpoint, budgets, kind, count) {
83
+ for (const { key, id } of budgets) {
84
+ const budget = checkpoint.budgets[key];
85
+ if (!budget)
86
+ throw new Error("Saved agent budget disappeared");
87
+ if (count > budget.limits[kind] - budget[kind])
88
+ limit(kind, budget.limits[kind], budget[kind], count, id);
89
+ }
90
+ for (const { key } of budgets)
91
+ checkpoint.budgets[key][kind] += count;
92
+ }
93
+ reserve(budgets, kind, count) {
94
+ return this.update((checkpoint) => this.charge(checkpoint, budgets, kind, count));
95
+ }
96
+ acceptDecision(key, state, calls) {
97
+ return this.update((checkpoint) => {
98
+ const saved = checkpoint.agents[key];
99
+ if (!saved || saved.phase !== "decide")
100
+ throw new Error("Agent is not awaiting a decision");
101
+ checkpoint.agents[key] = {
102
+ metadata: saved.metadata,
103
+ execution: saved.execution,
104
+ phase: "calls",
105
+ decision: { state, calls, admitted: false },
106
+ };
107
+ });
108
+ }
109
+ admitCalls(key, budgets, count) {
110
+ return this.update((checkpoint) => {
111
+ const saved = callingAgent(checkpoint, key);
112
+ if (saved.decision.admitted)
113
+ return;
114
+ this.charge(checkpoint, budgets, "maxCalls", count);
115
+ saved.decision.admitted = true;
116
+ });
117
+ }
118
+ async startCall(key, id, replay) {
119
+ const saved = this.decision(key)?.calls.find((call) => call.id === id);
120
+ if (!saved)
121
+ throw new Error("Saved agent call disappeared");
122
+ if (saved.status === "completed")
123
+ return { kind: "outcome", outcome: saved.outcome, reused: true };
124
+ if (saved.status === "running" && (saved.replay !== "safe" || replay !== "safe")) {
125
+ const outcome = {
126
+ id,
127
+ tool: saved.tool,
128
+ ok: false,
129
+ error: {
130
+ code: "TUBELESS_AGENT_CALL_INTERRUPTED",
131
+ message: `Tool ${saved.tool} was interrupted and may have partially run; inspect its effects before retrying`,
132
+ },
133
+ };
134
+ await this.completeCall(key, id, outcome);
135
+ return { kind: "outcome", outcome, reused: false };
136
+ }
137
+ await this.changeCall(key, id, (call) => {
138
+ if (call.status === "completed")
139
+ throw new Error("Saved agent call already completed");
140
+ return { ...call, status: "running" };
141
+ });
142
+ return { kind: "run" };
143
+ }
144
+ completeCall(key, id, outcome) {
145
+ return this.changeCall(key, id, (call) => ({ ...call, status: "completed", outcome }));
146
+ }
147
+ changeCall(key, id, change) {
148
+ return this.update((checkpoint) => {
149
+ const saved = callingAgent(checkpoint, key);
150
+ if (!saved.decision.admitted)
151
+ throw new Error("Saved call batch has not been admitted");
152
+ const index = saved.decision.calls.findIndex((call) => call.id === id);
153
+ const call = saved.decision.calls[index];
154
+ if (!call)
155
+ throw new Error("Saved agent call disappeared");
156
+ saved.decision.calls[index] = change(call);
157
+ });
158
+ }
159
+ advance(key, execution) {
160
+ return this.update((checkpoint) => {
161
+ const saved = callingAgent(checkpoint, key);
162
+ if (saved.decision.calls.some((call) => call.status !== "completed"))
163
+ throw new Error("Agent call batch has unfinished work");
164
+ checkpoint.agents[key] = { metadata: saved.metadata, execution, phase: "decide" };
165
+ });
166
+ }
167
+ finish(key, result) {
168
+ return this.update((checkpoint) => {
169
+ const saved = checkpoint.agents[key];
170
+ if (!saved || saved.phase !== "decide")
171
+ throw new Error("Agent is not awaiting a finish decision");
172
+ checkpoint.agents[key] = {
173
+ metadata: saved.metadata,
174
+ execution: saved.execution,
175
+ phase: "completed",
176
+ result,
177
+ };
178
+ });
179
+ }
180
+ fail(key, error, signal) {
181
+ if (this.#failure || signal?.aborted)
182
+ return Promise.resolve();
183
+ return this.update((checkpoint) => {
184
+ const saved = checkpoint.agents[key];
185
+ if (!saved)
186
+ throw new Error("Saved agent disappeared");
187
+ checkpoint.agents[key] = {
188
+ metadata: saved.metadata,
189
+ execution: saved.execution,
190
+ phase: "failed",
191
+ failure: {
192
+ code: error instanceof Error && "code" in error && typeof error.code === "string"
193
+ ? error.code
194
+ : "TUBELESS_AGENT_EXECUTION_FAILED",
195
+ message: error instanceof Error ? error.message : String(error),
196
+ },
197
+ };
198
+ });
199
+ }
200
+ update(change) {
201
+ const write = this.#tail.then(async () => {
202
+ if (this.#failure)
203
+ throw this.#failure.error;
204
+ const checkpoint = this.roundTrip(this.#checkpoint).decoded;
205
+ change(checkpoint);
206
+ try {
207
+ const { encoded, decoded } = this.roundTrip(checkedCheckpoint(checkpoint));
208
+ const checked = checkedCheckpoint(decoded);
209
+ await this.lease.write(encoded);
210
+ this.#checkpoint = checked;
211
+ }
212
+ catch (error) {
213
+ this.#failure ??= { error };
214
+ throw error;
215
+ }
216
+ });
217
+ // A rejected transition changed only the private copy. Failed persistence requires reopening storage.
218
+ this.#tail = write.catch(() => { });
219
+ return write;
220
+ }
221
+ async close() {
222
+ await this.#tail;
223
+ await this.lease.close();
224
+ }
225
+ }
226
+ //# sourceMappingURL=checkpoint-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint-session.js","sourceRoot":"","sources":["../../src/agent/checkpoint-session.ts"],"names":[],"mappings":"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","sourcesContent":["import { agentError, limit } from \"./agent-state.js\";\nimport { plainAgentCheckpointCodec } from \"./checkpoint-codec.js\";\nimport type {\n AgentCheckpointCodec,\n AgentCheckpointLease,\n AgentCheckpointStore,\n} from \"./checkpoint-types.js\";\nimport { checkCheckpointKey } from \"./checkpoint-key.js\";\nimport { checkedCheckpoint } from \"./checkpoint-format.js\";\nimport type {\n CallOutcome,\n Checkpoint,\n SavedAgent,\n SavedCall,\n SavedDecision,\n StoredBudget,\n} from \"./checkpoint-format.js\";\n\nexport interface BudgetReference {\n key: string;\n id: string;\n}\n\ntype CallingAgent = Extract<SavedAgent, { phase: \"calls\" }>;\n\nfunction callingAgent(checkpoint: Checkpoint, key: string): CallingAgent {\n const saved = checkpoint.agents[key];\n if (!saved || saved.phase !== \"calls\") throw new Error(\"Agent has no accepted call batch\");\n return saved;\n}\n\n/** One owner for acknowledged state transitions and budgets across a durable subtree. */\nexport class AgentCheckpointSession {\n #checkpoint: Checkpoint;\n #tail = Promise.resolve();\n #failure: { error: unknown } | undefined;\n private constructor(\n readonly key: string,\n private readonly lease: AgentCheckpointLease,\n private readonly codec: AgentCheckpointCodec,\n checkpoint: Checkpoint\n ) {\n this.#checkpoint = checkpoint;\n }\n static async open(\n store: AgentCheckpointStore,\n key: string,\n codec: AgentCheckpointCodec = plainAgentCheckpointCodec\n ): Promise<AgentCheckpointSession> {\n checkCheckpointKey(key);\n const lease = await store.acquire(key);\n try {\n const bytes = await lease.read();\n const checkpoint =\n bytes === undefined\n ? { version: 1 as const, agents: {}, budgets: {} }\n : checkedCheckpoint(codec.decode(bytes));\n return new AgentCheckpointSession(key, lease, codec, checkpoint);\n } catch (error) {\n await lease.close();\n throw error;\n }\n }\n private roundTrip<T>(value: T): { encoded: string; decoded: T } {\n const encoded = this.codec.encode(value);\n const decoded = this.codec.decode(encoded);\n if (this.codec.encode(decoded) !== encoded)\n throw agentError(\n \"TUBELESS_AGENT_CHECKPOINT_CODEC\",\n \"Agent checkpoint codec must round-trip deterministically\"\n );\n // SAFETY: codecs promise lossless round trips; the default checks finite plain data.\n return { encoded, decoded: decoded as T };\n }\n agent(key: string): SavedAgent | undefined {\n const value = this.#checkpoint.agents[key];\n return value === undefined ? undefined : this.roundTrip(value).decoded;\n }\n decision(key: string): SavedDecision | undefined {\n const saved = this.agent(key);\n return saved?.phase === \"calls\" ? saved.decision : undefined;\n }\n budget(key: string): Readonly<StoredBudget> {\n const saved = this.#checkpoint.budgets[key];\n if (!saved) throw new Error(\"Saved agent budget disappeared\");\n return { ...saved, limits: { ...saved.limits } };\n }\n async enter(\n key: string,\n metadata: SavedAgent[\"metadata\"],\n budget: Pick<StoredBudget, \"depth\" | \"limits\">,\n initialize: () => SavedAgent[\"execution\"]\n ): Promise<SavedAgent> {\n const saved = this.agent(key);\n if (saved) {\n const restored = this.budget(key);\n if (this.codec.encode(saved.metadata) !== this.codec.encode(metadata))\n throw agentError(\n \"TUBELESS_AGENT_CHECKPOINT_MISMATCH\",\n \"Agent checkpoint definition, inputs or workspace differ; use a new execution key\"\n );\n if (\n this.codec.encode({ depth: restored.depth, limits: restored.limits }) !==\n this.codec.encode(budget)\n )\n throw agentError(\n \"TUBELESS_AGENT_CHECKPOINT_MISMATCH\",\n \"Saved agent limits or delegation depth differ\"\n );\n return saved;\n }\n await this.update((checkpoint) => {\n checkpoint.budgets[key] = { ...budget, maxCalls: 0, maxDecisions: 0 };\n checkpoint.agents[key] = { metadata, execution: initialize(), phase: \"decide\" };\n });\n const entered = this.agent(key);\n if (!entered) throw new Error(\"Saved agent disappeared\");\n return entered;\n }\n private charge(\n checkpoint: Checkpoint,\n budgets: readonly BudgetReference[],\n kind: \"maxCalls\" | \"maxDecisions\",\n count: number\n ): void {\n for (const { key, id } of budgets) {\n const budget = checkpoint.budgets[key];\n if (!budget) throw new Error(\"Saved agent budget disappeared\");\n if (count > budget.limits[kind] - budget[kind])\n limit(kind, budget.limits[kind], budget[kind], count, id);\n }\n for (const { key } of budgets) checkpoint.budgets[key]![kind] += count;\n }\n reserve(\n budgets: readonly BudgetReference[],\n kind: \"maxCalls\" | \"maxDecisions\",\n count: number\n ): Promise<void> {\n return this.update((checkpoint) => this.charge(checkpoint, budgets, kind, count));\n }\n acceptDecision(key: string, state: unknown, calls: SavedCall[]): Promise<void> {\n return this.update((checkpoint) => {\n const saved = checkpoint.agents[key];\n if (!saved || saved.phase !== \"decide\") throw new Error(\"Agent is not awaiting a decision\");\n checkpoint.agents[key] = {\n metadata: saved.metadata,\n execution: saved.execution,\n phase: \"calls\",\n decision: { state, calls, admitted: false },\n };\n });\n }\n admitCalls(key: string, budgets: readonly BudgetReference[], count: number): Promise<void> {\n return this.update((checkpoint) => {\n const saved = callingAgent(checkpoint, key);\n if (saved.decision.admitted) return;\n this.charge(checkpoint, budgets, \"maxCalls\", count);\n saved.decision.admitted = true;\n });\n }\n async startCall(\n key: string,\n id: string,\n replay: \"safe\" | \"unsafe\"\n ): Promise<{ kind: \"run\" } | { kind: \"outcome\"; outcome: CallOutcome; reused: boolean }> {\n const saved = this.decision(key)?.calls.find((call) => call.id === id);\n if (!saved) throw new Error(\"Saved agent call disappeared\");\n if (saved.status === \"completed\")\n return { kind: \"outcome\", outcome: saved.outcome, reused: true };\n if (saved.status === \"running\" && (saved.replay !== \"safe\" || replay !== \"safe\")) {\n const outcome: CallOutcome = {\n id,\n tool: saved.tool,\n ok: false,\n error: {\n code: \"TUBELESS_AGENT_CALL_INTERRUPTED\",\n message: `Tool ${saved.tool} was interrupted and may have partially run; inspect its effects before retrying`,\n },\n };\n await this.completeCall(key, id, outcome);\n return { kind: \"outcome\", outcome, reused: false };\n }\n await this.changeCall(key, id, (call) => {\n if (call.status === \"completed\") throw new Error(\"Saved agent call already completed\");\n return { ...call, status: \"running\" };\n });\n return { kind: \"run\" };\n }\n completeCall(key: string, id: string, outcome: CallOutcome): Promise<void> {\n return this.changeCall(key, id, (call) => ({ ...call, status: \"completed\", outcome }));\n }\n private changeCall(\n key: string,\n id: string,\n change: (call: SavedCall) => SavedCall\n ): Promise<void> {\n return this.update((checkpoint) => {\n const saved = callingAgent(checkpoint, key);\n if (!saved.decision.admitted) throw new Error(\"Saved call batch has not been admitted\");\n const index = saved.decision.calls.findIndex((call) => call.id === id);\n const call = saved.decision.calls[index];\n if (!call) throw new Error(\"Saved agent call disappeared\");\n saved.decision.calls[index] = change(call);\n });\n }\n advance(key: string, execution: SavedAgent[\"execution\"]): Promise<void> {\n return this.update((checkpoint) => {\n const saved = callingAgent(checkpoint, key);\n if (saved.decision.calls.some((call) => call.status !== \"completed\"))\n throw new Error(\"Agent call batch has unfinished work\");\n checkpoint.agents[key] = { metadata: saved.metadata, execution, phase: \"decide\" };\n });\n }\n finish(key: string, result: unknown): Promise<void> {\n return this.update((checkpoint) => {\n const saved = checkpoint.agents[key];\n if (!saved || saved.phase !== \"decide\")\n throw new Error(\"Agent is not awaiting a finish decision\");\n checkpoint.agents[key] = {\n metadata: saved.metadata,\n execution: saved.execution,\n phase: \"completed\",\n result,\n };\n });\n }\n fail(key: string, error: unknown, signal?: AbortSignal): Promise<void> {\n if (this.#failure || signal?.aborted) return Promise.resolve();\n return this.update((checkpoint) => {\n const saved = checkpoint.agents[key];\n if (!saved) throw new Error(\"Saved agent disappeared\");\n checkpoint.agents[key] = {\n metadata: saved.metadata,\n execution: saved.execution,\n phase: \"failed\",\n failure: {\n code:\n error instanceof Error && \"code\" in error && typeof error.code === \"string\"\n ? error.code\n : \"TUBELESS_AGENT_EXECUTION_FAILED\",\n message: error instanceof Error ? error.message : String(error),\n },\n };\n });\n }\n private update(change: (checkpoint: Checkpoint) => void): Promise<void> {\n const write = this.#tail.then(async () => {\n if (this.#failure) throw this.#failure.error;\n const checkpoint = this.roundTrip(this.#checkpoint).decoded;\n change(checkpoint);\n try {\n const { encoded, decoded } = this.roundTrip(checkedCheckpoint(checkpoint));\n const checked = checkedCheckpoint(decoded);\n await this.lease.write(encoded);\n this.#checkpoint = checked;\n } catch (error) {\n this.#failure ??= { error };\n throw error;\n }\n });\n // A rejected transition changed only the private copy. Failed persistence requires reopening storage.\n this.#tail = write.catch(() => {});\n return write;\n }\n async close(): Promise<void> {\n await this.#tail;\n await this.lease.close();\n }\n}\n"]}
@@ -0,0 +1,31 @@
1
+ /** Exclusive ownership of one execution's acknowledged checkpoint bytes. */
2
+ export interface AgentCheckpointLease {
3
+ read(): Promise<string | undefined>;
4
+ /** Atomically replace the checkpoint; resolve only once it is durably stored. */
5
+ write(checkpoint: string): Promise<void>;
6
+ /** Release ownership without deleting the execution. */
7
+ close(): Promise<void>;
8
+ }
9
+ /** Pluggable checkpoint persistence. A key may have only one live lease. */
10
+ export interface AgentCheckpointStore {
11
+ acquire(key: string): Promise<AgentCheckpointLease>;
12
+ }
13
+ /** Lossless serialization for persisted state, validated arguments and outcomes. */
14
+ export interface AgentCheckpointCodec {
15
+ encode(value: unknown): string;
16
+ decode(checkpoint: string): unknown;
17
+ }
18
+ /** Resume the same execution key on subsequent invocations with the same definition and inputs. */
19
+ export interface AgentDurability<Options extends object> {
20
+ readonly store: AgentCheckpointStore;
21
+ readonly key: string | ((options: Options) => string);
22
+ /** Defaults to finite plain data, including undefined and sparse arrays. */
23
+ readonly codec?: AgentCheckpointCodec;
24
+ }
25
+ /** Stable durable identities for business idempotency and cross-attempt correlation. */
26
+ export interface AgentExecutionIdentity {
27
+ readonly id: string;
28
+ readonly agent: string;
29
+ readonly turn: number;
30
+ readonly call?: string;
31
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=checkpoint-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint-types.js","sourceRoot":"","sources":["../../src/agent/checkpoint-types.ts"],"names":[],"mappings":"","sourcesContent":["/** Exclusive ownership of one execution's acknowledged checkpoint bytes. */\nexport interface AgentCheckpointLease {\n read(): Promise<string | undefined>;\n /** Atomically replace the checkpoint; resolve only once it is durably stored. */\n write(checkpoint: string): Promise<void>;\n /** Release ownership without deleting the execution. */\n close(): Promise<void>;\n}\n\n/** Pluggable checkpoint persistence. A key may have only one live lease. */\nexport interface AgentCheckpointStore {\n acquire(key: string): Promise<AgentCheckpointLease>;\n}\n\n/** Lossless serialization for persisted state, validated arguments and outcomes. */\nexport interface AgentCheckpointCodec {\n encode(value: unknown): string;\n decode(checkpoint: string): unknown;\n}\n\n/** Resume the same execution key on subsequent invocations with the same definition and inputs. */\nexport interface AgentDurability<Options extends object> {\n readonly store: AgentCheckpointStore;\n readonly key: string | ((options: Options) => string);\n /** Defaults to finite plain data, including undefined and sparse arrays. */\n readonly codec?: AgentCheckpointCodec;\n}\n\n/** Stable durable identities for business idempotency and cross-attempt correlation. */\nexport interface AgentExecutionIdentity {\n readonly id: string;\n readonly agent: string;\n readonly turn: number;\n readonly call?: string;\n}\n"]}
@@ -1,13 +1,17 @@
1
1
  import { createSteps, definePipeline } from "../core/pipeline.js";
2
2
  import { STEP_AGENT } from "../core/pipeline-step-metadata.js";
3
- import { agentError, checkSchema, descriptorFingerprint, jsonDescriptor, ownState, } from "./agent-state.js";
3
+ import { agentError, checkSchema, descriptorFingerprint, jsonDescriptor } from "./agent-state.js";
4
4
  import { compileTool } from "./tools.js";
5
5
  import { defaultTools } from "./default-tools.js";
6
- import { resolvedLimits } from "./execution-scope.js";
6
+ import { resolvedLimits, agentScope } from "./execution-scope.js";
7
7
  import { createAgentTurn } from "./turn.js";
8
- import { runAgentInvocation } from "./invocation.js";
8
+ import { initialAgentExecution, runAgentInvocation } from "./invocation.js";
9
+ import { markAgent } from "./agent-identity.js";
9
10
  export function compileAgent(definition, resolveCwd = false) {
10
11
  const config = { ...definition };
12
+ if (config.durability &&
13
+ (typeof config.implementationVersion !== "string" || !config.implementationVersion.trim()))
14
+ throw agentError("TUBELESS_AGENT_INVALID_DEFINITION", "Durable agents require an explicit implementationVersion");
11
15
  checkSchema(config.inputSchema, "Agent input");
12
16
  if (typeof config.initialState !== "function" ||
13
17
  typeof config.decide !== "function" ||
@@ -32,12 +36,8 @@ export function compileAgent(definition, resolveCwd = false) {
32
36
  maxIterations: limits.maxTurns,
33
37
  dryRun: config.dryRun ? undefined : "skip",
34
38
  initialState: (_inputs, context) => {
35
- return {
36
- state: ownState(config.initialState(context.options)),
37
- turn: 1,
38
- stateVersion: 0,
39
- calls: 0,
40
- };
39
+ const scope = agentScope(context);
40
+ return initialAgentExecution(() => config.initialState(context.options), scope.journal?.agent(scope.agentKey)?.execution);
41
41
  },
42
42
  mapOptions: (execution, _inputs, context) => ({
43
43
  execution,
@@ -48,7 +48,7 @@ export function compileAgent(definition, resolveCwd = false) {
48
48
  });
49
49
  const compiledAgent = agent;
50
50
  const run = compiledAgent.run;
51
- compiledAgent.run = (inputs, context) => runAgentInvocation({ environment: config.environment, limits, resolveCwd }, context, (scoped) => run(inputs, scoped));
51
+ compiledAgent.run = (inputs, context) => runAgentInvocation({ ...config, limits, resolveCwd, definition: pipeline.definition }, context, (scoped) => run(inputs, scoped));
52
52
  Object.defineProperty(agent, STEP_AGENT, {
53
53
  value: Object.freeze({
54
54
  limits,
@@ -69,6 +69,7 @@ export function compileAgent(definition, resolveCwd = false) {
69
69
  steps: [compiledAgent],
70
70
  finalize: compiledAgent,
71
71
  });
72
+ markAgent(pipeline);
72
73
  // SAFETY: the sole iteration step inherits Options, publishes the once-validated Result,
73
74
  // and is the only target. This restores deferred generic inference at the factory boundary.
74
75
  return pipeline;
@@ -1 +1 @@
1
- {"version":3,"file":"compile-agent.js","sourceRoot":"","sources":["../../src/agent/compile-agent.ts"],"names":[],"mappings":"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","sourcesContent":["import { createSteps, definePipeline } from \"../core/pipeline.js\";\nimport { STEP_AGENT } from \"../core/pipeline-step-metadata.js\";\nimport type {\n Pipeline,\n PipelineDefinitionSnapshot,\n StandardSchemaV1,\n} from \"../core/pipeline-types.js\";\nimport type { AnyStep } from \"../core/pipeline-steps.js\";\nimport {\n agentError,\n checkSchema,\n descriptorFingerprint,\n jsonDescriptor,\n ownState,\n} from \"./agent-state.js\";\nimport { compileTool } from \"./tools.js\";\nimport { defaultTools } from \"./default-tools.js\";\nimport { resolvedLimits } from \"./execution-scope.js\";\nimport { createAgentTurn, type TurnState } from \"./turn.js\";\nimport { runAgentInvocation } from \"./invocation.js\";\nimport type {\n AgentDefinition,\n AgentDecisionContext,\n AgentState,\n Awaitable,\n Input,\n Output,\n Tools,\n} from \"./agent-types.js\";\n\n/** Accept raw or already-owned pending state; the turn snapshots it before tools run. */\nexport type RuntimeAgentDefinition<\n Id extends string,\n Options extends StandardSchemaV1<object, object>,\n Result extends StandardSchemaV1,\n State,\n Registry extends Tools,\n> = Omit<AgentDefinition<Id, Options, Result, State, Registry>, \"decide\" | \"dryRun\"> & {\n decide(\n state: AgentState<State>,\n context: AgentDecisionContext<Output<Options>>\n ): Awaitable<{\n decision: unknown;\n state: State | AgentState<State>;\n }>;\n dryRun?(\n state: AgentState<State>,\n context: AgentDecisionContext<Output<Options>>\n ): Awaitable<{\n decision: unknown;\n state: State | AgentState<State>;\n }>;\n};\n\nexport function compileAgent<\n const Id extends string,\n const Options extends StandardSchemaV1<object, object>,\n const Result extends StandardSchemaV1,\n State,\n const Registry extends Tools = {},\n>(\n definition: RuntimeAgentDefinition<Id, Options, Result, State, Registry>,\n resolveCwd = false\n): Pipeline<Input<Options>, Output<Result>, \"agent\", \"agent\", Id> & {\n readonly optionsSchema: Options;\n readonly definition: PipelineDefinitionSnapshot;\n} {\n const config = { ...definition };\n checkSchema(config.inputSchema, \"Agent input\");\n if (\n typeof config.initialState !== \"function\" ||\n typeof config.decide !== \"function\" ||\n (config.reduce !== undefined && typeof config.reduce !== \"function\") ||\n (config.dryRun !== undefined && typeof config.dryRun !== \"function\")\n )\n throw agentError(\n \"TUBELESS_AGENT_INVALID_DEFINITION\",\n \"Agent requires initialState and decide callbacks, and callable reduce/dryRun when supplied\"\n );\n const limits = resolvedLimits(config.limits);\n const resultJsonSchema = jsonDescriptor(\n config.resultSchema,\n config.resultJsonSchema,\n \"Agent result\"\n );\n const entries = Object.entries({ ...defaultTools, ...config.tools }).sort(([a], [b]) =>\n a < b ? -1 : a > b ? 1 : 0\n );\n if (entries.length > 4096)\n throw agentError(\n \"TUBELESS_AGENT_INVALID_DEFINITION\",\n \"Agent capability inventory exceeds 4096 tools\"\n );\n const registry = new Map(\n entries.map(([name, tool]) => {\n if (!/^[A-Za-z][A-Za-z0-9_-]{0,127}$/.test(name))\n throw agentError(\"TUBELESS_AGENT_INVALID_DEFINITION\", `Invalid tool name: ${name}`);\n return [name, compileTool(config.id, name, tool)];\n })\n );\n const capabilities = Object.freeze(\n [...registry.values()].map(({ name, description, inputJsonSchema }) =>\n Object.freeze({ name, description, inputJsonSchema })\n )\n );\n const turn = createAgentTurn(config, registry, limits, { capabilities, resultJsonSchema });\n const { iteratePipeline } = createSteps(config.inputSchema);\n const agent = iteratePipeline(\"agent\", {\n pipeline: turn,\n maxIterations: limits.maxTurns,\n dryRun: config.dryRun ? undefined : \"skip\",\n initialState: (_inputs, context): TurnState<State> => {\n return {\n state: ownState(config.initialState(context.options)),\n turn: 1,\n stateVersion: 0,\n calls: 0,\n };\n },\n mapOptions: (execution, _inputs, context) => ({\n execution,\n options: context.options,\n agentRunId: context.runId,\n }),\n transition: (result) => result,\n });\n const compiledAgent: AnyStep<Output<Options>> = agent;\n const run = compiledAgent.run;\n compiledAgent.run = (inputs, context) =>\n runAgentInvocation({ environment: config.environment, limits, resolveCwd }, context, (scoped) =>\n run(inputs, scoped)\n );\n Object.defineProperty(agent, STEP_AGENT, {\n value: Object.freeze({\n limits,\n resultSchemaFingerprint: descriptorFingerprint(resultJsonSchema),\n capabilities: Object.freeze(\n [...registry.values()].map((tool) =>\n Object.freeze({\n name: tool.name,\n description: tool.description,\n inputSchemaFingerprint: descriptorFingerprint(tool.inputJsonSchema),\n identity: tool.pipeline.definition.identity,\n })\n )\n ),\n }),\n });\n const pipeline = definePipeline({\n id: config.id,\n name: config.name,\n description: config.description,\n implementationVersion: config.implementationVersion,\n steps: [compiledAgent],\n finalize: compiledAgent,\n });\n // SAFETY: the sole iteration step inherits Options, publishes the once-validated Result,\n // and is the only target. This restores deferred generic inference at the factory boundary.\n return pipeline as unknown as Pipeline<Input<Options>, Output<Result>, \"agent\", \"agent\", Id> & {\n readonly optionsSchema: Options;\n readonly definition: PipelineDefinitionSnapshot;\n };\n}\n"]}
1
+ {"version":3,"file":"compile-agent.js","sourceRoot":"","sources":["../../src/agent/compile-agent.ts"],"names":[],"mappings":"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","sourcesContent":["import { createSteps, definePipeline } from \"../core/pipeline.js\";\nimport { STEP_AGENT } from \"../core/pipeline-step-metadata.js\";\nimport type {\n Pipeline,\n PipelineDefinitionSnapshot,\n StandardSchemaV1,\n} from \"../core/pipeline-types.js\";\nimport type { AnyStep } from \"../core/pipeline-steps.js\";\nimport { agentError, checkSchema, descriptorFingerprint, jsonDescriptor } from \"./agent-state.js\";\nimport { compileTool } from \"./tools.js\";\nimport { defaultTools } from \"./default-tools.js\";\nimport { resolvedLimits, agentScope } from \"./execution-scope.js\";\nimport { createAgentTurn, type TurnState } from \"./turn.js\";\nimport { initialAgentExecution, runAgentInvocation } from \"./invocation.js\";\nimport { markAgent } from \"./agent-identity.js\";\nimport type {\n AgentDefinition,\n AgentDecisionContext,\n AgentState,\n Awaitable,\n Input,\n Output,\n Tools,\n} from \"./agent-types.js\";\n\n/** Accept raw or already-owned pending state; the turn snapshots it before tools run. */\nexport type RuntimeAgentDefinition<\n Id extends string,\n Options extends StandardSchemaV1<object, object>,\n Result extends StandardSchemaV1,\n State,\n Registry extends Tools,\n> = Omit<AgentDefinition<Id, Options, Result, State, Registry>, \"decide\" | \"dryRun\"> & {\n decide(\n state: AgentState<State>,\n context: AgentDecisionContext<Output<Options>>\n ): Awaitable<{\n decision: unknown;\n state: State | AgentState<State>;\n }>;\n dryRun?(\n state: AgentState<State>,\n context: AgentDecisionContext<Output<Options>>\n ): Awaitable<{\n decision: unknown;\n state: State | AgentState<State>;\n }>;\n};\n\nexport function compileAgent<\n const Id extends string,\n const Options extends StandardSchemaV1<object, object>,\n const Result extends StandardSchemaV1,\n State,\n const Registry extends Tools = {},\n>(\n definition: RuntimeAgentDefinition<Id, Options, Result, State, Registry>,\n resolveCwd = false\n): Pipeline<Input<Options>, Output<Result>, \"agent\", \"agent\", Id> & {\n readonly optionsSchema: Options;\n readonly definition: PipelineDefinitionSnapshot;\n} {\n const config = { ...definition };\n if (\n config.durability &&\n (typeof config.implementationVersion !== \"string\" || !config.implementationVersion.trim())\n )\n throw agentError(\n \"TUBELESS_AGENT_INVALID_DEFINITION\",\n \"Durable agents require an explicit implementationVersion\"\n );\n checkSchema(config.inputSchema, \"Agent input\");\n if (\n typeof config.initialState !== \"function\" ||\n typeof config.decide !== \"function\" ||\n (config.reduce !== undefined && typeof config.reduce !== \"function\") ||\n (config.dryRun !== undefined && typeof config.dryRun !== \"function\")\n )\n throw agentError(\n \"TUBELESS_AGENT_INVALID_DEFINITION\",\n \"Agent requires initialState and decide callbacks, and callable reduce/dryRun when supplied\"\n );\n const limits = resolvedLimits(config.limits);\n const resultJsonSchema = jsonDescriptor(\n config.resultSchema,\n config.resultJsonSchema,\n \"Agent result\"\n );\n const entries = Object.entries({ ...defaultTools, ...config.tools }).sort(([a], [b]) =>\n a < b ? -1 : a > b ? 1 : 0\n );\n if (entries.length > 4096)\n throw agentError(\n \"TUBELESS_AGENT_INVALID_DEFINITION\",\n \"Agent capability inventory exceeds 4096 tools\"\n );\n const registry = new Map(\n entries.map(([name, tool]) => {\n if (!/^[A-Za-z][A-Za-z0-9_-]{0,127}$/.test(name))\n throw agentError(\"TUBELESS_AGENT_INVALID_DEFINITION\", `Invalid tool name: ${name}`);\n return [name, compileTool(config.id, name, tool)];\n })\n );\n const capabilities = Object.freeze(\n [...registry.values()].map(({ name, description, inputJsonSchema }) =>\n Object.freeze({ name, description, inputJsonSchema })\n )\n );\n const turn = createAgentTurn(config, registry, limits, { capabilities, resultJsonSchema });\n const { iteratePipeline } = createSteps(config.inputSchema);\n const agent = iteratePipeline(\"agent\", {\n pipeline: turn,\n maxIterations: limits.maxTurns,\n dryRun: config.dryRun ? undefined : \"skip\",\n initialState: (_inputs, context): TurnState<State> => {\n const scope = agentScope(context)!;\n return initialAgentExecution(\n () => config.initialState(context.options),\n scope.journal?.agent(scope.agentKey)?.execution\n );\n },\n mapOptions: (execution, _inputs, context) => ({\n execution,\n options: context.options,\n agentRunId: context.runId,\n }),\n transition: (result) => result,\n });\n const compiledAgent: AnyStep<Output<Options>> = agent;\n const run = compiledAgent.run;\n compiledAgent.run = (inputs, context) =>\n runAgentInvocation(\n { ...config, limits, resolveCwd, definition: pipeline.definition },\n context,\n (scoped) => run(inputs, scoped)\n );\n Object.defineProperty(agent, STEP_AGENT, {\n value: Object.freeze({\n limits,\n resultSchemaFingerprint: descriptorFingerprint(resultJsonSchema),\n capabilities: Object.freeze(\n [...registry.values()].map((tool) =>\n Object.freeze({\n name: tool.name,\n description: tool.description,\n inputSchemaFingerprint: descriptorFingerprint(tool.inputJsonSchema),\n identity: tool.pipeline.definition.identity,\n })\n )\n ),\n }),\n });\n const pipeline = definePipeline({\n id: config.id,\n name: config.name,\n description: config.description,\n implementationVersion: config.implementationVersion,\n steps: [compiledAgent],\n finalize: compiledAgent,\n });\n markAgent(pipeline);\n // SAFETY: the sole iteration step inherits Options, publishes the once-validated Result,\n // and is the only target. This restores deferred generic inference at the factory boundary.\n return pipeline as unknown as Pipeline<Input<Options>, Output<Result>, \"agent\", \"agent\", Id> & {\n readonly optionsSchema: Options;\n readonly definition: PipelineDefinitionSnapshot;\n };\n}\n"]}
@@ -28,5 +28,5 @@ export declare function decisionEnvelope(value: unknown): {
28
28
  kind: "continue";
29
29
  calls: readonly unknown[];
30
30
  };
31
- export declare function prepareCalls(values: readonly unknown[], registry: ReadonlyMap<string, CompiledTool>, context: PipelineStepContext<object>): Promise<PreparedCall[]>;
31
+ export declare function prepareCalls(values: readonly unknown[], registry: ReadonlyMap<string, CompiledTool>, context: PipelineStepContext<object>, turn: number): Promise<PreparedCall[]>;
32
32
  export {};
@@ -29,7 +29,7 @@ export function decisionEnvelope(value) {
29
29
  // Leave call traversal to prepareCalls, after the turn admits the batch by length.
30
30
  return { kind: "continue", calls: value.calls };
31
31
  }
32
- export async function prepareCalls(values, registry, context) {
32
+ export async function prepareCalls(values, registry, context, turn) {
33
33
  const ids = new Set();
34
34
  const calls = Array.from(values, (call) => {
35
35
  if (!record(call) ||
@@ -57,7 +57,7 @@ export async function prepareCalls(values, registry, context) {
57
57
  throwIfAborted(context.signal, "Agent batch validation");
58
58
  let invocation;
59
59
  if (tool.kind === "pipeline") {
60
- const scope = agentScope(context).delegate();
60
+ const scope = agentScope(context).delegate(turn, call.id);
61
61
  const input = tool.mapOptions
62
62
  ? await validateStandardSchema(tool.inputSchema, call.input, `Agent tool ${call.tool} input`)
63
63
  : call.input;
@@ -1 +1 @@
1
- {"version":3,"file":"decision.js","sourceRoot":"","sources":["../../src/agent/decision.ts"],"names":[],"mappings":"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","sourcesContent":["import { PreparedOptions } from \"../core/prepared-options.js\";\nimport { agentScope, type AgentExecutionScope } from \"./execution-scope.js\";\nimport type { PipelinePlan, PipelineStepContext } from \"../core/pipeline-types.js\";\nimport { validateStandardSchema } from \"../core/pipeline-validation.js\";\nimport { throwIfAborted } from \"../utilities/abort.js\";\nimport { agentError } from \"./agent-state.js\";\nimport type { CompiledTool } from \"./tools.js\";\n\ntype PreparedTool =\n | {\n kind: \"handler\";\n tool: Extract<CompiledTool, { kind: \"handler\" }>;\n input: unknown;\n }\n | {\n kind: \"pipeline\";\n tool: Extract<CompiledTool, { kind: \"pipeline\" }>;\n options: object;\n preparedOptions: PreparedOptions;\n scope: AgentExecutionScope;\n };\n\nexport type PreparedCall = PreparedTool & {\n id: string;\n plan: PipelinePlan;\n};\n\nfunction invalid(message: string): never {\n throw agentError(\"TUBELESS_AGENT_INVALID_DECISION\", message);\n}\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return (\n value !== null &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null)\n );\n}\n\nfunction keys(value: Record<string, unknown>, expected: readonly string[]): boolean {\n return (\n Reflect.ownKeys(value).length === expected.length &&\n expected.every((key) => Object.hasOwn(value, key))\n );\n}\n\nexport function decisionEnvelope(\n value: unknown\n): { kind: \"finish\"; result: unknown } | { kind: \"continue\"; calls: readonly unknown[] } {\n if (!record(value)) return invalid(\"Agent decision must be a plain object\");\n if (value.kind === \"finish\" && keys(value, [\"kind\", \"result\"]))\n return { kind: \"finish\", result: value.result };\n if (\n value.kind !== \"continue\" ||\n !keys(value, [\"kind\", \"calls\"]) ||\n !Array.isArray(value.calls) ||\n value.calls.length === 0\n )\n return invalid(\"Agent decision must finish(result) or continue with a nonempty calls array\");\n // Leave call traversal to prepareCalls, after the turn admits the batch by length.\n return { kind: \"continue\", calls: value.calls };\n}\n\nexport async function prepareCalls(\n values: readonly unknown[],\n registry: ReadonlyMap<string, CompiledTool>,\n context: PipelineStepContext<object>\n): Promise<PreparedCall[]> {\n const ids = new Set<string>();\n const calls = Array.from(values, (call: unknown) => {\n if (\n !record(call) ||\n !keys(call, [\"id\", \"tool\", \"input\"]) ||\n typeof call.id !== \"string\" ||\n !call.id.trim() ||\n call.id.length > 256 ||\n typeof call.tool !== \"string\" ||\n !call.tool.trim()\n )\n return invalid(\"Each call requires a nonblank id (up to 256 characters), tool, and input\");\n if (ids.has(call.id)) return invalid(`Duplicate agent call id: ${call.id}`);\n ids.add(call.id);\n return { id: call.id, tool: call.tool, input: call.input };\n });\n // Resolve the complete registry membership before invoking any argument validators.\n const entries = calls.map((call) => {\n const tool = registry.get(call.tool);\n if (!tool) return invalid(`Unknown agent tool: ${call.tool}`);\n return { call, tool };\n });\n const prepared: PreparedCall[] = [];\n for (const { call, tool } of entries) {\n throwIfAborted(context.signal, \"Agent batch validation\");\n let invocation: PreparedTool;\n if (tool.kind === \"pipeline\") {\n const scope = agentScope(context)!.delegate();\n const input = tool.mapOptions\n ? await validateStandardSchema(\n tool.inputSchema,\n call.input,\n `Agent tool ${call.tool} input`\n )\n : call.input;\n // SAFETY: the private preparation boundary checks object shape, even for schema-less children.\n const options = tool.mapOptions ? tool.mapOptions(input) : (input as object);\n const preparedOptions = await PreparedOptions.prepare(\n tool.pipeline.optionsSchema,\n options,\n `Pipeline ${tool.pipeline.id} options`\n );\n invocation = { kind: \"pipeline\", tool, options, preparedOptions, scope };\n } else {\n const input = await validateStandardSchema(\n tool.inputSchema,\n call.input,\n `Agent tool ${call.tool} input`\n );\n invocation = { kind: \"handler\", tool, input };\n }\n throwIfAborted(context.signal, \"Agent batch validation\");\n const plan = tool.pipeline.plan({ dryRun: context.dryRun, cache: context.cachePolicy });\n if (!plan.ok) return invalid(`Agent tool ${call.tool} has an invalid plan`);\n prepared.push({ ...invocation, id: call.id, plan });\n }\n return prepared;\n}\n"]}
1
+ {"version":3,"file":"decision.js","sourceRoot":"","sources":["../../src/agent/decision.ts"],"names":[],"mappings":"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","sourcesContent":["import { PreparedOptions } from \"../core/prepared-options.js\";\nimport { agentScope, type AgentExecutionScope } from \"./execution-scope.js\";\nimport type { PipelinePlan, PipelineStepContext } from \"../core/pipeline-types.js\";\nimport { validateStandardSchema } from \"../core/pipeline-validation.js\";\nimport { throwIfAborted } from \"../utilities/abort.js\";\nimport { agentError } from \"./agent-state.js\";\nimport type { CompiledTool } from \"./tools.js\";\n\ntype PreparedTool =\n | {\n kind: \"handler\";\n tool: Extract<CompiledTool, { kind: \"handler\" }>;\n input: unknown;\n }\n | {\n kind: \"pipeline\";\n tool: Extract<CompiledTool, { kind: \"pipeline\" }>;\n options: object;\n preparedOptions: PreparedOptions;\n scope: AgentExecutionScope;\n };\n\nexport type PreparedCall = PreparedTool & {\n id: string;\n plan: PipelinePlan;\n};\n\nfunction invalid(message: string): never {\n throw agentError(\"TUBELESS_AGENT_INVALID_DECISION\", message);\n}\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return (\n value !== null &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null)\n );\n}\n\nfunction keys(value: Record<string, unknown>, expected: readonly string[]): boolean {\n return (\n Reflect.ownKeys(value).length === expected.length &&\n expected.every((key) => Object.hasOwn(value, key))\n );\n}\n\nexport function decisionEnvelope(\n value: unknown\n): { kind: \"finish\"; result: unknown } | { kind: \"continue\"; calls: readonly unknown[] } {\n if (!record(value)) return invalid(\"Agent decision must be a plain object\");\n if (value.kind === \"finish\" && keys(value, [\"kind\", \"result\"]))\n return { kind: \"finish\", result: value.result };\n if (\n value.kind !== \"continue\" ||\n !keys(value, [\"kind\", \"calls\"]) ||\n !Array.isArray(value.calls) ||\n value.calls.length === 0\n )\n return invalid(\"Agent decision must finish(result) or continue with a nonempty calls array\");\n // Leave call traversal to prepareCalls, after the turn admits the batch by length.\n return { kind: \"continue\", calls: value.calls };\n}\n\nexport async function prepareCalls(\n values: readonly unknown[],\n registry: ReadonlyMap<string, CompiledTool>,\n context: PipelineStepContext<object>,\n turn: number\n): Promise<PreparedCall[]> {\n const ids = new Set<string>();\n const calls = Array.from(values, (call: unknown) => {\n if (\n !record(call) ||\n !keys(call, [\"id\", \"tool\", \"input\"]) ||\n typeof call.id !== \"string\" ||\n !call.id.trim() ||\n call.id.length > 256 ||\n typeof call.tool !== \"string\" ||\n !call.tool.trim()\n )\n return invalid(\"Each call requires a nonblank id (up to 256 characters), tool, and input\");\n if (ids.has(call.id)) return invalid(`Duplicate agent call id: ${call.id}`);\n ids.add(call.id);\n return { id: call.id, tool: call.tool, input: call.input };\n });\n // Resolve the complete registry membership before invoking any argument validators.\n const entries = calls.map((call) => {\n const tool = registry.get(call.tool);\n if (!tool) return invalid(`Unknown agent tool: ${call.tool}`);\n return { call, tool };\n });\n const prepared: PreparedCall[] = [];\n for (const { call, tool } of entries) {\n throwIfAborted(context.signal, \"Agent batch validation\");\n let invocation: PreparedTool;\n if (tool.kind === \"pipeline\") {\n const scope = agentScope(context)!.delegate(turn, call.id);\n const input = tool.mapOptions\n ? await validateStandardSchema(\n tool.inputSchema,\n call.input,\n `Agent tool ${call.tool} input`\n )\n : call.input;\n // SAFETY: the private preparation boundary checks object shape, even for schema-less children.\n const options = tool.mapOptions ? tool.mapOptions(input) : (input as object);\n const preparedOptions = await PreparedOptions.prepare(\n tool.pipeline.optionsSchema,\n options,\n `Pipeline ${tool.pipeline.id} options`\n );\n invocation = { kind: \"pipeline\", tool, options, preparedOptions, scope };\n } else {\n const input = await validateStandardSchema(\n tool.inputSchema,\n call.input,\n `Agent tool ${call.tool} input`\n );\n invocation = { kind: \"handler\", tool, input };\n }\n throwIfAborted(context.signal, \"Agent batch validation\");\n const plan = tool.pipeline.plan({ dryRun: context.dryRun, cache: context.cachePolicy });\n if (!plan.ok) return invalid(`Agent tool ${call.tool} has an invalid plan`);\n prepared.push({ ...invocation, id: call.id, plan });\n }\n return prepared;\n}\n"]}
@@ -44,10 +44,10 @@ export declare const defaultTools: Readonly<{
44
44
  list: import("./agent-types.js").AgentTool<{} & {
45
45
  path?: string | null | undefined;
46
46
  }, {
47
- entries: readonly ({
48
- kind: "directory" | "file" | "other" | "symlink";
47
+ entries: readonly {
49
48
  name: string;
50
- } & {})[];
49
+ kind: "file" | "directory" | "symlink" | "other";
50
+ }[];
51
51
  path: string;
52
52
  truncated: boolean;
53
53
  } & {}>;
@@ -56,11 +56,11 @@ export declare const defaultTools: Readonly<{
56
56
  } & {
57
57
  path?: string | null | undefined;
58
58
  }, {
59
- matches: readonly ({
60
- line: number;
59
+ matches: readonly {
61
60
  path: string;
61
+ line: number;
62
62
  text: string;
63
- } & {})[];
63
+ }[];
64
64
  skippedFiles: number;
65
65
  truncated: boolean;
66
66
  } & {}>;