@loopingai/core 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.
Files changed (238) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +279 -0
  3. package/dist/a2a/agent-stub.d.ts +61 -0
  4. package/dist/a2a/agent-stub.d.ts.map +1 -0
  5. package/dist/a2a/agent-stub.js +2 -0
  6. package/dist/a2a/agent-stub.js.map +1 -0
  7. package/dist/a2a/card.d.ts +119 -0
  8. package/dist/a2a/card.d.ts.map +1 -0
  9. package/dist/a2a/card.js +115 -0
  10. package/dist/a2a/card.js.map +1 -0
  11. package/dist/a2a/context.d.ts +14 -0
  12. package/dist/a2a/context.d.ts.map +1 -0
  13. package/dist/a2a/context.js +55 -0
  14. package/dist/a2a/context.js.map +1 -0
  15. package/dist/a2a/executor.d.ts +85 -0
  16. package/dist/a2a/executor.d.ts.map +1 -0
  17. package/dist/a2a/executor.js +107 -0
  18. package/dist/a2a/executor.js.map +1 -0
  19. package/dist/a2a/index.d.ts +18 -0
  20. package/dist/a2a/index.d.ts.map +1 -0
  21. package/dist/a2a/index.js +17 -0
  22. package/dist/a2a/index.js.map +1 -0
  23. package/dist/a2a/notify.d.ts +75 -0
  24. package/dist/a2a/notify.d.ts.map +1 -0
  25. package/dist/a2a/notify.js +161 -0
  26. package/dist/a2a/notify.js.map +1 -0
  27. package/dist/a2a/parts.d.ts +46 -0
  28. package/dist/a2a/parts.d.ts.map +1 -0
  29. package/dist/a2a/parts.js +95 -0
  30. package/dist/a2a/parts.js.map +1 -0
  31. package/dist/a2a/task-store.d.ts +45 -0
  32. package/dist/a2a/task-store.d.ts.map +1 -0
  33. package/dist/a2a/task-store.js +100 -0
  34. package/dist/a2a/task-store.js.map +1 -0
  35. package/dist/a2a/task.d.ts +86 -0
  36. package/dist/a2a/task.d.ts.map +1 -0
  37. package/dist/a2a/task.js +16 -0
  38. package/dist/a2a/task.js.map +1 -0
  39. package/dist/a2a/verify.d.ts +64 -0
  40. package/dist/a2a/verify.d.ts.map +1 -0
  41. package/dist/a2a/verify.js +122 -0
  42. package/dist/a2a/verify.js.map +1 -0
  43. package/dist/agent/budget.d.ts +47 -0
  44. package/dist/agent/budget.d.ts.map +1 -0
  45. package/dist/agent/budget.js +43 -0
  46. package/dist/agent/budget.js.map +1 -0
  47. package/dist/agent/control.d.ts +110 -0
  48. package/dist/agent/control.d.ts.map +1 -0
  49. package/dist/agent/control.js +115 -0
  50. package/dist/agent/control.js.map +1 -0
  51. package/dist/agent/final-reply.d.ts +49 -0
  52. package/dist/agent/final-reply.d.ts.map +1 -0
  53. package/dist/agent/final-reply.js +52 -0
  54. package/dist/agent/final-reply.js.map +1 -0
  55. package/dist/agent/history.d.ts +83 -0
  56. package/dist/agent/history.d.ts.map +1 -0
  57. package/dist/agent/history.js +117 -0
  58. package/dist/agent/history.js.map +1 -0
  59. package/dist/agent/index.d.ts +17 -0
  60. package/dist/agent/index.d.ts.map +1 -0
  61. package/dist/agent/index.js +17 -0
  62. package/dist/agent/index.js.map +1 -0
  63. package/dist/agent/inference.d.ts +52 -0
  64. package/dist/agent/inference.d.ts.map +1 -0
  65. package/dist/agent/inference.js +79 -0
  66. package/dist/agent/inference.js.map +1 -0
  67. package/dist/agent/model.d.ts +75 -0
  68. package/dist/agent/model.d.ts.map +1 -0
  69. package/dist/agent/model.js +62 -0
  70. package/dist/agent/model.js.map +1 -0
  71. package/dist/agent/session.d.ts +92 -0
  72. package/dist/agent/session.d.ts.map +1 -0
  73. package/dist/agent/session.js +80 -0
  74. package/dist/agent/session.js.map +1 -0
  75. package/dist/config.d.ts +159 -0
  76. package/dist/config.d.ts.map +1 -0
  77. package/dist/config.js +92 -0
  78. package/dist/config.js.map +1 -0
  79. package/dist/contract/index.d.ts +10 -0
  80. package/dist/contract/index.d.ts.map +1 -0
  81. package/dist/contract/index.js +9 -0
  82. package/dist/contract/index.js.map +1 -0
  83. package/dist/contract/plugin.d.ts +163 -0
  84. package/dist/contract/plugin.d.ts.map +1 -0
  85. package/dist/contract/plugin.js +39 -0
  86. package/dist/contract/plugin.js.map +1 -0
  87. package/dist/contract/recipe.d.ts +170 -0
  88. package/dist/contract/recipe.d.ts.map +1 -0
  89. package/dist/contract/recipe.js +2 -0
  90. package/dist/contract/recipe.js.map +1 -0
  91. package/dist/contract/validation.d.ts +86 -0
  92. package/dist/contract/validation.d.ts.map +1 -0
  93. package/dist/contract/validation.js +76 -0
  94. package/dist/contract/validation.js.map +1 -0
  95. package/dist/db/db.d.ts +131 -0
  96. package/dist/db/db.d.ts.map +1 -0
  97. package/dist/db/db.js +91 -0
  98. package/dist/db/db.js.map +1 -0
  99. package/dist/db/index.d.ts +9 -0
  100. package/dist/db/index.d.ts.map +1 -0
  101. package/dist/db/index.js +9 -0
  102. package/dist/db/index.js.map +1 -0
  103. package/dist/db/migrations/index.d.ts +21 -0
  104. package/dist/db/migrations/index.d.ts.map +1 -0
  105. package/dist/db/migrations/index.js +54 -0
  106. package/dist/db/migrations/index.js.map +1 -0
  107. package/dist/db/models/subtasks.d.ts +102 -0
  108. package/dist/db/models/subtasks.d.ts.map +1 -0
  109. package/dist/db/models/subtasks.js +285 -0
  110. package/dist/db/models/subtasks.js.map +1 -0
  111. package/dist/db/models/tasks.d.ts +92 -0
  112. package/dist/db/models/tasks.d.ts.map +1 -0
  113. package/dist/db/models/tasks.js +212 -0
  114. package/dist/db/models/tasks.js.map +1 -0
  115. package/dist/db/schema.d.ts +488 -0
  116. package/dist/db/schema.d.ts.map +1 -0
  117. package/dist/db/schema.js +91 -0
  118. package/dist/db/schema.js.map +1 -0
  119. package/dist/env.d.ts +46 -0
  120. package/dist/env.d.ts.map +1 -0
  121. package/dist/env.js +40 -0
  122. package/dist/env.js.map +1 -0
  123. package/dist/index.d.ts +20 -0
  124. package/dist/index.d.ts.map +1 -0
  125. package/dist/index.js +18 -0
  126. package/dist/index.js.map +1 -0
  127. package/dist/platform.d.ts +47 -0
  128. package/dist/platform.d.ts.map +1 -0
  129. package/dist/platform.js +47 -0
  130. package/dist/platform.js.map +1 -0
  131. package/dist/runtime/index.d.ts +86 -0
  132. package/dist/runtime/index.d.ts.map +1 -0
  133. package/dist/runtime/index.js +123 -0
  134. package/dist/runtime/index.js.map +1 -0
  135. package/dist/runtime/tool-families.d.ts +33 -0
  136. package/dist/runtime/tool-families.d.ts.map +1 -0
  137. package/dist/runtime/tool-families.js +62 -0
  138. package/dist/runtime/tool-families.js.map +1 -0
  139. package/dist/subagent/fingerprint.d.ts +38 -0
  140. package/dist/subagent/fingerprint.d.ts.map +1 -0
  141. package/dist/subagent/fingerprint.js +97 -0
  142. package/dist/subagent/fingerprint.js.map +1 -0
  143. package/dist/subagent/index.d.ts +147 -0
  144. package/dist/subagent/index.d.ts.map +1 -0
  145. package/dist/subagent/index.js +299 -0
  146. package/dist/subagent/index.js.map +1 -0
  147. package/dist/subagent/prompt.d.ts +34 -0
  148. package/dist/subagent/prompt.d.ts.map +1 -0
  149. package/dist/subagent/prompt.js +46 -0
  150. package/dist/subagent/prompt.js.map +1 -0
  151. package/dist/subagent/run.d.ts +151 -0
  152. package/dist/subagent/run.d.ts.map +1 -0
  153. package/dist/subagent/run.js +491 -0
  154. package/dist/subagent/run.js.map +1 -0
  155. package/dist/subagent/workspace.d.ts +65 -0
  156. package/dist/subagent/workspace.d.ts.map +1 -0
  157. package/dist/subagent/workspace.js +53 -0
  158. package/dist/subagent/workspace.js.map +1 -0
  159. package/dist/subtasks/catalog.d.ts +40 -0
  160. package/dist/subtasks/catalog.d.ts.map +1 -0
  161. package/dist/subtasks/catalog.js +36 -0
  162. package/dist/subtasks/catalog.js.map +1 -0
  163. package/dist/subtasks/decomposition.d.ts +90 -0
  164. package/dist/subtasks/decomposition.d.ts.map +1 -0
  165. package/dist/subtasks/decomposition.js +205 -0
  166. package/dist/subtasks/decomposition.js.map +1 -0
  167. package/dist/subtasks/delegate.d.ts +77 -0
  168. package/dist/subtasks/delegate.d.ts.map +1 -0
  169. package/dist/subtasks/delegate.js +102 -0
  170. package/dist/subtasks/delegate.js.map +1 -0
  171. package/dist/subtasks/index.d.ts +11 -0
  172. package/dist/subtasks/index.d.ts.map +1 -0
  173. package/dist/subtasks/index.js +11 -0
  174. package/dist/subtasks/index.js.map +1 -0
  175. package/dist/subtasks/scheduler.d.ts +49 -0
  176. package/dist/subtasks/scheduler.d.ts.map +1 -0
  177. package/dist/subtasks/scheduler.js +48 -0
  178. package/dist/subtasks/scheduler.js.map +1 -0
  179. package/dist/subtasks/subtask-types.d.ts +100 -0
  180. package/dist/subtasks/subtask-types.d.ts.map +1 -0
  181. package/dist/subtasks/subtask-types.js +111 -0
  182. package/dist/subtasks/subtask-types.js.map +1 -0
  183. package/dist/subtasks/types.d.ts +321 -0
  184. package/dist/subtasks/types.d.ts.map +1 -0
  185. package/dist/subtasks/types.js +16 -0
  186. package/dist/subtasks/types.js.map +1 -0
  187. package/dist/testing/auth.d.ts +12 -0
  188. package/dist/testing/auth.d.ts.map +1 -0
  189. package/dist/testing/auth.js +25 -0
  190. package/dist/testing/auth.js.map +1 -0
  191. package/dist/testing/do.d.ts +30 -0
  192. package/dist/testing/do.d.ts.map +1 -0
  193. package/dist/testing/do.js +26 -0
  194. package/dist/testing/do.js.map +1 -0
  195. package/dist/testing/fake-session.d.ts +27 -0
  196. package/dist/testing/fake-session.d.ts.map +1 -0
  197. package/dist/testing/fake-session.js +38 -0
  198. package/dist/testing/fake-session.js.map +1 -0
  199. package/dist/testing/fixtures.d.ts +27 -0
  200. package/dist/testing/fixtures.d.ts.map +1 -0
  201. package/dist/testing/fixtures.js +67 -0
  202. package/dist/testing/fixtures.js.map +1 -0
  203. package/dist/testing/index.d.ts +31 -0
  204. package/dist/testing/index.d.ts.map +1 -0
  205. package/dist/testing/index.js +31 -0
  206. package/dist/testing/index.js.map +1 -0
  207. package/dist/testing/mock-model.d.ts +43 -0
  208. package/dist/testing/mock-model.d.ts.map +1 -0
  209. package/dist/testing/mock-model.js +62 -0
  210. package/dist/testing/mock-model.js.map +1 -0
  211. package/dist/testing/node.d.ts +24 -0
  212. package/dist/testing/node.d.ts.map +1 -0
  213. package/dist/testing/node.js +24 -0
  214. package/dist/testing/node.js.map +1 -0
  215. package/dist/testing/vcr-global-setup.d.ts +3 -0
  216. package/dist/testing/vcr-global-setup.d.ts.map +1 -0
  217. package/dist/testing/vcr-global-setup.js +9 -0
  218. package/dist/testing/vcr-global-setup.js.map +1 -0
  219. package/dist/testing/vcr-shared.d.ts +21 -0
  220. package/dist/testing/vcr-shared.d.ts.map +1 -0
  221. package/dist/testing/vcr-shared.js +21 -0
  222. package/dist/testing/vcr-shared.js.map +1 -0
  223. package/dist/testing/vcr-spec.d.ts +17 -0
  224. package/dist/testing/vcr-spec.d.ts.map +1 -0
  225. package/dist/testing/vcr-spec.js +72 -0
  226. package/dist/testing/vcr-spec.js.map +1 -0
  227. package/dist/testing/vcr.d.ts +81 -0
  228. package/dist/testing/vcr.d.ts.map +1 -0
  229. package/dist/testing/vcr.js +211 -0
  230. package/dist/testing/vcr.js.map +1 -0
  231. package/dist/worker/index.d.ts +62 -0
  232. package/dist/worker/index.d.ts.map +1 -0
  233. package/dist/worker/index.js +194 -0
  234. package/dist/worker/index.js.map +1 -0
  235. package/eslint-rules/index.js +31 -0
  236. package/eslint-rules/no-deprecated-object-properties.js +81 -0
  237. package/package.json +147 -0
  238. package/scripts/generate-keys.mjs +53 -0
@@ -0,0 +1,321 @@
1
+ import type { ResolvedRecipe, SubtaskParams } from "../contract/recipe.js";
2
+ export type SubtaskStatus = "pending" | "running" | "completed" | "failed" | "skipped" | "canceled";
3
+ /** A per-caller, SQLite-assigned, monotonically increasing Subtask identifier. */
4
+ export type SubtaskId = number;
5
+ /**
6
+ * An exact, verbatim snapshot of one selected Session history message, copied
7
+ * onto the Subtask at decomposition time. The decomposition model selects which
8
+ * messages to reference; it never rewrites their content. User-turn provenance
9
+ * (author/channel) is already inline in the message text's `<turn>` wrapper.
10
+ */
11
+ export interface SubtaskReference {
12
+ role: "user" | "assistant";
13
+ text: string;
14
+ }
15
+ /**
16
+ * One part of a Subtask's result. Text-only today; file/data kinds are additive
17
+ * later. Internal to the agent — the terminal A2A Task collapses these to a
18
+ * single text reply for the gateway/human.
19
+ */
20
+ export interface SubtaskResultPart {
21
+ kind: "text";
22
+ text: string;
23
+ }
24
+ /**
25
+ * Creation input for one Subtask, before it is persisted. `dependsOn` uses
26
+ * draft-local keys (not yet-unknown {@link SubtaskId}s); the data layer resolves
27
+ * them to SQLite-assigned ids when the decomposition is created. `ordinal` is
28
+ * derived from the draft's position in the decomposition array.
29
+ */
30
+ export interface SubtaskDraft {
31
+ localKey: string;
32
+ type: string;
33
+ prompt: string;
34
+ references: SubtaskReference[];
35
+ /** Draft-local keys of prerequisite drafts. */
36
+ dependsOn: string[];
37
+ /** The type's required inputs, already validated for shape. */
38
+ params: SubtaskParams;
39
+ }
40
+ /**
41
+ * Session state the parent resolved *from* a Subtask's params at execution
42
+ * start — the part of an execution's context the model can never supply.
43
+ *
44
+ * Deliberately outside {@link RecipeExecutionRequest}: it is not part of an
45
+ * execution's identity and it can change under us, so fingerprinting it would
46
+ * make a retry look like a different request. It travels as a separate argument,
47
+ * the same discipline as the chunk number.
48
+ */
49
+ export type SubtaskRuntime = Record<string, unknown>;
50
+ /**
51
+ * Narrow a {@link SubtaskRuntime} to the shape a plugin resolved for itself.
52
+ *
53
+ * Runtime is an open bag because core cannot know what a domain needs — the
54
+ * predecessor repo declared ARC's four fields (`cardId`, `cookies`, `guid`,
55
+ * `frame`) right here in the delegation types, which meant core imported a
56
+ * domain's types and every unrelated agent carried them. A plugin now writes and
57
+ * reads its own slice, and the only thing core does with the bag is carry it.
58
+ *
59
+ * The unchecked cast is the point: the plugin that wrote the slice is the plugin
60
+ * reading it, so the assertion is local and its blast radius is one module.
61
+ */
62
+ export declare function runtimeAs<T>(runtime: SubtaskRuntime): T;
63
+ /**
64
+ * A user-facing progress note a tool emits mid-execution (e.g. a game level-up).
65
+ * The resumable runner collects these and ends the current chunk so the parent
66
+ * DO can post them promptly; `key` is a stable dedupe id the gateway keys on.
67
+ */
68
+ export interface ProgressEvent {
69
+ key: string;
70
+ text: string;
71
+ }
72
+ /**
73
+ * One durable chunk's outcome as the facet reports it to the parent DO. `done`
74
+ * false means the run yielded a chunk boundary and the Workflow must run another
75
+ * chunk; `done` true carries the terminal {@link RecipeExecutionResult}. Progress
76
+ * events accumulated during the chunk ride along either way.
77
+ */
78
+ export type RecipeChunkResult = {
79
+ done: false;
80
+ progress: ProgressEvent[];
81
+ } | {
82
+ done: true;
83
+ result: RecipeExecutionResult;
84
+ progress: ProgressEvent[];
85
+ };
86
+ /**
87
+ * The parent DO's projection of a chunk outcome for the Workflow (RPC-safe, no
88
+ * result parts — those are persisted on the row). `status` is `running` until the
89
+ * run is `done`, then the terminal Subtask status.
90
+ */
91
+ export interface SubtaskChunkOutcome {
92
+ done: boolean;
93
+ status: SubtaskStatus;
94
+ progress: ProgressEvent[];
95
+ }
96
+ /**
97
+ * Generated output of one completed prerequisite Subtask, loaded by the parent
98
+ * from its durable row for a dependent's invocation. `type` is the
99
+ * prerequisite's semantic type — used only to label the rendered section;
100
+ * dependency output is always presented as generated, never as conversation
101
+ * evidence.
102
+ */
103
+ export interface DependencyResult {
104
+ subtaskId: SubtaskId;
105
+ type: string;
106
+ resultParts: SubtaskResultPart[];
107
+ }
108
+ /**
109
+ * RPC-safe input for one isolated `RecipeSubagent` execution, assembled by the
110
+ * parent at execution start: the already-resolved (and code-validated) Recipe,
111
+ * the Subtask's non-session prompt, its verbatim reference snapshots, and the
112
+ * generated results of its completed dependencies. The child re-validates the
113
+ * Recipe defensively but never resolves one itself.
114
+ */
115
+ export interface RecipeExecutionRequest {
116
+ taskId: string;
117
+ subtaskId: SubtaskId;
118
+ /**
119
+ * The Subtask's semantic type — what the work *is*, and what owns the params
120
+ * contract. Distinct from `recipe.key`, which names the execution
121
+ * configuration it runs under: several types may share one Recipe.
122
+ */
123
+ type: string;
124
+ recipe: ResolvedRecipe;
125
+ prompt: string;
126
+ references: SubtaskReference[];
127
+ dependencyResults: DependencyResult[];
128
+ /**
129
+ * The Subtask's validated params. Part of the execution's identity — two plays
130
+ * of different games are different work — so this IS fingerprinted, unlike
131
+ * {@link SubtaskRuntime}, which is deliberately excluded: the leased scorecard
132
+ * can legitimately differ between two chunks of one run, and must not make a
133
+ * retry look like a different execution.
134
+ */
135
+ params: SubtaskParams;
136
+ }
137
+ /**
138
+ * Terminal outcome of one `RecipeSubagent` execution (RPC-safe). `modelId` is a
139
+ * diagnostic only — which model produced the outcome (null when validation
140
+ * failed before any model call); it is never persisted on the Subtask row.
141
+ * Transient platform faults are not results: they throw so the enclosing
142
+ * Workflow step can retry.
143
+ */
144
+ export type RecipeExecutionResult = {
145
+ status: "completed";
146
+ resultParts: SubtaskResultPart[];
147
+ modelId: string;
148
+ } | {
149
+ status: "failed";
150
+ error: string;
151
+ modelId: string | null;
152
+ };
153
+ /**
154
+ * One Subtask as the delegating model emits it. The model selects references
155
+ * by **catalog index only** — it never emits reference text, and application code
156
+ * snapshots the catalog entry's exact role+text onto the Subtask (see
157
+ * `agent/subtasks/decomposition.ts`). `dependsOn` uses draft-local keys, resolved
158
+ * to SQLite-assigned {@link SubtaskId}s by the data layer.
159
+ */
160
+ export interface SubtaskProposal {
161
+ localKey: string;
162
+ type: string;
163
+ prompt: string;
164
+ /**
165
+ * 1-based indices into the ephemeral, per-round reference catalog. Optional:
166
+ * omitted when the subtask needs no verbatim history, and always absent from a
167
+ * *reconstructed* historical call, whose references were resolved rounds ago.
168
+ */
169
+ referenceIndexes?: number[];
170
+ /** Draft-local keys of prerequisite proposals. */
171
+ dependsOn: string[];
172
+ /** The type's required inputs; omitted for a type that takes none. */
173
+ params?: SubtaskParams;
174
+ }
175
+ /**
176
+ * The model's complete `delegate` call: the acknowledgment the user sees while
177
+ * the work runs, plus one through eight Subtask proposals. Validated against the
178
+ * round's ephemeral catalog before anything is persisted; invalid output fails
179
+ * the attempt (and, with both models exhausted, the round) rather than being
180
+ * silently repaired.
181
+ */
182
+ export interface DecompositionProposal {
183
+ reply: string;
184
+ subtasks: SubtaskProposal[];
185
+ }
186
+ /**
187
+ * Terminal outcome of one main-agent round (RPC-safe).
188
+ *
189
+ * `replied` is the terminal answer — the round chose to answer the user rather
190
+ * than delegate, and the Workflow delivers it. `delegated` means the round's
191
+ * Subtask rows are durable and Phase 2 should run them, after which another round
192
+ * begins. `failed` means both models produced unusable output; no Subtask is ever
193
+ * synthesized to cover for it. `canceled` means the caller cancelled during the
194
+ * round: nothing was persisted and nothing was published. Transient platform
195
+ * faults are not results: they throw so the enclosing Workflow step can retry
196
+ * (mirrors {@link RecipeExecutionResult}).
197
+ *
198
+ * `turns` is what this round cost, which the Workflow meters against the Task's
199
+ * budget. This is the **only** type that carries it, and it carries it because the
200
+ * count has to cross an RPC boundary to reach a Workflow in another isolate;
201
+ * everything inside the DO shares one mutable {@link file://../budget.ts TurnBudget}
202
+ * instead. The field is attached in a single place — see `runTaskTurn` — so no
203
+ * branch can drop it and no branch can invent it.
204
+ *
205
+ * The idempotent recovery paths — a round replayed from durable rows rather than
206
+ * re-inferred — therefore report **0** structurally: they return before any model
207
+ * runs, so the budget they hand back is untouched. That is exact on a clean
208
+ * replay, where the Workflow's own cached step return already carries the original
209
+ * number, and under-counts by one round when a step crashed mid-flight and re-ran.
210
+ * Accepted rather than fixed: a replying round writes no durable row at all, so
211
+ * nothing exists to hang a per-round count on, and the wall clock bounds the
212
+ * crash-loop case anyway.
213
+ */
214
+ export type TurnTaskResult = {
215
+ status: "replied";
216
+ reply: string;
217
+ turns: number;
218
+ } | {
219
+ status: "delegated";
220
+ reply: string;
221
+ subtasks: Subtask[];
222
+ turns: number;
223
+ } | {
224
+ status: "failed";
225
+ error: string;
226
+ turns: number;
227
+ } | {
228
+ status: "canceled";
229
+ turns: number;
230
+ };
231
+ /**
232
+ * Distributive `Omit` — applies per member, so the discriminated union survives.
233
+ * A plain `Omit<TurnTaskResult, "turns">` collapses all four into one loose shape
234
+ * whose `reply` and `subtasks` are independently optional.
235
+ */
236
+ type WithoutTurns<T> = T extends unknown ? Omit<T, "turns"> : never;
237
+ /**
238
+ * What a round decided, before its cost is attached. The DO's round logic returns
239
+ * this and lets one wrapper bill the budget, rather than every branch remembering
240
+ * to report a number it did not compute.
241
+ */
242
+ export type TurnVerdict = WithoutTurns<TurnTaskResult>;
243
+ /**
244
+ * One branch's outcome as a later round sees it — a plain, RPC-safe subset of the
245
+ * durable {@link Subtask} row, loaded across **every** round in stable ordinal
246
+ * order. Completed, failed, and skipped branches are all included so the reply
247
+ * can use available successes and disclose relevant failures.
248
+ *
249
+ * Carries `round`, `prompt` and `dependsOn` — not for composing, but for
250
+ * reconstructing the per-round `delegate` call that produced these branches (see
251
+ * `agent/subtasks/delegate.ts`). Unlike {@link SubtaskNode}, this projection is
252
+ * built inside the DO and returns only a reply, so the 1 MiB Workflow-step cap
253
+ * that keeps the scheduler's view narrow does not apply. `references` still stays
254
+ * out: it is unbounded history text, and the call's shape does not need it.
255
+ */
256
+ export interface CompositionBranch {
257
+ subtaskId: SubtaskId;
258
+ round: number;
259
+ ordinal: number;
260
+ type: string;
261
+ prompt: string;
262
+ dependsOn: SubtaskId[];
263
+ params: SubtaskParams;
264
+ status: SubtaskStatus;
265
+ resultParts: SubtaskResultPart[] | null;
266
+ error: string | null;
267
+ }
268
+ /**
269
+ * The `scan:<n>` wave projection (RPC-safe): either the caller cancelled, or the
270
+ * refreshed DAG after blocked branches were skipped. Returning the verdict with
271
+ * the nodes is what lets the Workflow drop its separate cancellation probe — one
272
+ * round trip, and no gap between asking and acting.
273
+ */
274
+ export type SubtaskScan = {
275
+ canceled: true;
276
+ } | {
277
+ canceled: false;
278
+ nodes: SubtaskNode[];
279
+ };
280
+ /**
281
+ * The scheduler's view of one Subtask (Phase 2) — everything needed to pick the
282
+ * next dependency-ready wave, and nothing else.
283
+ *
284
+ * Deliberately excludes `prompt`, `references`, and `resultParts`: a Workflow
285
+ * step return is capped at 1 MiB, and a reference is a verbatim history snapshot
286
+ * bounded only by `MAX_INBOUND_TEXT_BYTES`, so a wave scan returning full rows
287
+ * would overflow on a large task. The durable rows — not Workflow state — are the
288
+ * source of truth, so the Workflow carries ids and statuses and re-reads the rest
289
+ * through the parent when it actually needs it.
290
+ */
291
+ export interface SubtaskNode {
292
+ id: SubtaskId;
293
+ ordinal: number;
294
+ status: SubtaskStatus;
295
+ dependsOn: SubtaskId[];
296
+ }
297
+ /** Durable state owned by the main agent for one delegated unit of work. */
298
+ export interface Subtask {
299
+ id: SubtaskId;
300
+ taskId: string;
301
+ /** The main-agent round that delegated this Subtask (0-based). */
302
+ round: number;
303
+ /** Position within the parent Task, increasing across every round. */
304
+ ordinal: number;
305
+ type: string;
306
+ recipeId: string | null;
307
+ recipeVersion: number | null;
308
+ prompt: string;
309
+ references: SubtaskReference[];
310
+ dependsOn: SubtaskId[];
311
+ /** The type's required inputs, validated at delegation time. */
312
+ params: SubtaskParams;
313
+ status: SubtaskStatus;
314
+ resultParts: SubtaskResultPart[] | null;
315
+ error: string | null;
316
+ createdAt: number;
317
+ updatedAt: number;
318
+ completedAt: number | null;
319
+ }
320
+ export {};
321
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/subtasks/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Narrow a {@link SubtaskRuntime} to the shape a plugin resolved for itself.
3
+ *
4
+ * Runtime is an open bag because core cannot know what a domain needs — the
5
+ * predecessor repo declared ARC's four fields (`cardId`, `cookies`, `guid`,
6
+ * `frame`) right here in the delegation types, which meant core imported a
7
+ * domain's types and every unrelated agent carried them. A plugin now writes and
8
+ * reads its own slice, and the only thing core does with the bag is carry it.
9
+ *
10
+ * The unchecked cast is the point: the plugin that wrote the slice is the plugin
11
+ * reading it, so the assertion is local and its blast radius is one module.
12
+ */
13
+ export function runtimeAs(runtime) {
14
+ return runtime;
15
+ }
16
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/subtasks/types.ts"],"names":[],"mappings":"AAyDA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,SAAS,CAAI,OAAuB;IAClD,OAAO,OAAY,CAAC;AACtB,CAAC"}
@@ -0,0 +1,12 @@
1
+ export interface GatewayTokenOptions {
2
+ audience?: string;
3
+ issuer?: string;
4
+ /** Relative string ("5m"), absolute epoch seconds, or Date. Past values expire the token. */
5
+ expiresIn?: string | number | Date;
6
+ identity?: Record<string, unknown>;
7
+ /** Claim the identity is carried in. Defaults to core's `IDENTITY_CLAIM`. */
8
+ identityClaim?: string;
9
+ }
10
+ /** Sign a short-lived EdDSA gateway JWT using the test gateway key. */
11
+ export declare function makeGatewayToken(options?: GatewayTokenOptions): Promise<string>;
12
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/testing/auth.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6FAA6F;IAC7F,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,uEAAuE;AACvE,wBAAsB,gBAAgB,CACpC,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,MAAM,CAAC,CAmBjB"}
@@ -0,0 +1,25 @@
1
+ import { importJWK, SignJWT } from "jose";
2
+ import { IDENTITY_CLAIM } from "../a2a/verify.js";
3
+ import { TEST_GATEWAY_PRIVATE_JWK, GATEWAY_ORIGIN, AGENT_ORIGIN } from "./fixtures.js";
4
+ /** Sign a short-lived EdDSA gateway JWT using the test gateway key. */
5
+ export async function makeGatewayToken(options = {}) {
6
+ const privateKey = await importJWK(TEST_GATEWAY_PRIVATE_JWK, "EdDSA");
7
+ return new SignJWT({
8
+ [options.identityClaim ?? IDENTITY_CLAIM]: options.identity ?? {
9
+ key: "custom:1:test-agent",
10
+ name: "Test Agent",
11
+ kind: "custom",
12
+ workspaceId: 1
13
+ }
14
+ })
15
+ .setProtectedHeader({
16
+ alg: "EdDSA",
17
+ kid: TEST_GATEWAY_PRIVATE_JWK.kid,
18
+ jku: `${GATEWAY_ORIGIN}/.well-known/jwks.json`
19
+ })
20
+ .setIssuer(options.issuer ?? GATEWAY_ORIGIN)
21
+ .setAudience(options.audience ?? AGENT_ORIGIN)
22
+ .setExpirationTime(options.expiresIn ?? "5m")
23
+ .sign(privateKey);
24
+ }
25
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/testing/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EACL,wBAAwB,EACxB,cAAc,EACd,YAAY,EACb,MAAM,eAAe,CAAC;AAYvB,uEAAuE;AACvE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,UAA+B,EAAE;IAEjC,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;IACtE,OAAO,IAAI,OAAO,CAAC;QACjB,CAAC,OAAO,CAAC,aAAa,IAAI,cAAc,CAAC,EAAE,OAAO,CAAC,QAAQ,IAAI;YAC7D,GAAG,EAAE,qBAAqB;YAC1B,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,CAAC;SACf;KACF,CAAC;SACC,kBAAkB,CAAC;QAClB,GAAG,EAAE,OAAO;QACZ,GAAG,EAAE,wBAAwB,CAAC,GAAG;QACjC,GAAG,EAAE,GAAG,cAAc,wBAAwB;KAC/C,CAAC;SACD,SAAS,CAAC,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC;SAC3C,WAAW,CAAC,OAAO,CAAC,QAAQ,IAAI,YAAY,CAAC;SAC7C,iBAAiB,CAAC,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC;SAC5C,IAAI,CAAC,UAAU,CAAC,CAAC;AACtB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { AgentDB, type AgentDBOptions } from "../db/db.js";
2
+ /**
3
+ * Durable Object test helpers.
4
+ *
5
+ * The predecessor hardcoded its own DO binding and exposed one `with*` wrapper
6
+ * per named `AgentDB` domain — including one for a domain that belonged to a
7
+ * plugin. Both are parameterized here: a consumer binds their namespace once,
8
+ * and {@link DoTestHelpers.withDb} hands over the whole `AgentDB` rather than
9
+ * pre-selecting a table.
10
+ */
11
+ export interface DoTestHelpers {
12
+ /** Fresh, unique DO stub per test — state never leaks between tests. */
13
+ freshStub(label: string): DurableObjectStub;
14
+ /** Run `fn` inside a fresh DO instance with a migrated {@link AgentDB}. */
15
+ withDb<T>(label: string, fn: (db: AgentDB) => T): Promise<T>;
16
+ }
17
+ /**
18
+ * `ctx` is protected in the DO type system but public at runtime. Cast once so
19
+ * callers don't repeat the assertion.
20
+ */
21
+ export declare function doStorage(instance: unknown): DurableObjectStorage;
22
+ /**
23
+ * Bind the helpers to a consumer's DO namespace.
24
+ *
25
+ * ```ts
26
+ * const { freshStub, withDb } = makeDoHelpers(env.MyAgent);
27
+ * ```
28
+ */
29
+ export declare function makeDoHelpers(ns: DurableObjectNamespace, defaults?: AgentDBOptions): DoTestHelpers;
30
+ //# sourceMappingURL=do.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"do.d.ts","sourceRoot":"","sources":["../../src/testing/do.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAE3D;;;;;;;;GAQG;AAEH,MAAM,WAAW,aAAa;IAC5B,wEAAwE;IACxE,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,iBAAiB,CAAC;IAC5C,2EAA2E;IAC3E,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,OAAO,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC9D;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,OAAO,GAAG,oBAAoB,CAEjE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,EAAE,EAAE,sBAAsB,EAC1B,QAAQ,GAAE,cAAmC,GAC5C,aAAa,CAYf"}
@@ -0,0 +1,26 @@
1
+ import { runInDurableObject } from "cloudflare:test";
2
+ import { AgentDB } from "../db/db.js";
3
+ /**
4
+ * `ctx` is protected in the DO type system but public at runtime. Cast once so
5
+ * callers don't repeat the assertion.
6
+ */
7
+ export function doStorage(instance) {
8
+ return instance.ctx.storage;
9
+ }
10
+ /**
11
+ * Bind the helpers to a consumer's DO namespace.
12
+ *
13
+ * ```ts
14
+ * const { freshStub, withDb } = makeDoHelpers(env.MyAgent);
15
+ * ```
16
+ */
17
+ export function makeDoHelpers(ns, defaults = { maxSubtasks: 8 }) {
18
+ const freshStub = (label) => ns.get(ns.idFromName(`test:${label}:${crypto.randomUUID()}`));
19
+ return {
20
+ freshStub,
21
+ withDb(label, fn) {
22
+ return runInDurableObject(freshStub(label), (instance) => fn(new AgentDB(doStorage(instance), defaults)));
23
+ }
24
+ };
25
+ }
26
+ //# sourceMappingURL=do.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"do.js","sourceRoot":"","sources":["../../src/testing/do.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAuB,MAAM,aAAa,CAAC;AAmB3D;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,QAAiB;IACzC,OAAQ,QAAuD,CAAC,GAAG,CAAC,OAAO,CAAC;AAC9E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC3B,EAA0B,EAC1B,WAA2B,EAAE,WAAW,EAAE,CAAC,EAAE;IAE7C,MAAM,SAAS,GAAG,CAAC,KAAa,EAAE,EAAE,CAClC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,KAAK,IAAI,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC;IAEhE,OAAO;QACL,SAAS;QACT,MAAM,CAAI,KAAa,EAAE,EAAsB;YAC7C,OAAO,kBAAkB,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,CACvD,EAAE,CAAC,IAAI,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC,CAC/C,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { ToolSet } from "ai";
2
+ import type { SessionMessage } from "agents/experimental/memory/session";
3
+ import type { SessionLike } from "../agent/session.js";
4
+ /**
5
+ * An in-memory {@link SessionLike} standing in for the DO's real continuous
6
+ * Session. Shared by the turn, decomposition, and composition specs so a change
7
+ * to the Session contract breaks in one place.
8
+ *
9
+ * Mirrors the two real behaviors the phased pipeline depends on:
10
+ *
11
+ * - `appendMessage` **dedupes by id** — appending an existing id is a no-op, the
12
+ * property that makes deterministic-id appends exactly-once on a step re-run.
13
+ * - `getMessage` reads the raw stored message back.
14
+ */
15
+ export declare class FakeSession implements SessionLike {
16
+ messages: SessionMessage[];
17
+ system: string;
18
+ /** Compaction overlays to report — non-empty gates the `recall` tool on. */
19
+ compactions: unknown[];
20
+ appendMessage(m: SessionMessage): void;
21
+ getHistory(): Promise<SessionMessage[]>;
22
+ getMessage(id: string): Promise<SessionMessage | null>;
23
+ refreshSystemPrompt(): Promise<string>;
24
+ tools(): Promise<ToolSet>;
25
+ getCompactions(): Promise<unknown[]>;
26
+ }
27
+ //# sourceMappingURL=fake-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fake-session.d.ts","sourceRoot":"","sources":["../../src/testing/fake-session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;;;;;;GAUG;AACH,qBAAa,WAAY,YAAW,WAAW;IAC7C,QAAQ,EAAE,cAAc,EAAE,CAAM;IAChC,MAAM,SAAsC;IAC5C,4EAA4E;IAC5E,WAAW,EAAE,OAAO,EAAE,CAAM;IAE5B,aAAa,CAAC,CAAC,EAAE,cAAc;IAIzB,UAAU;IAGV,UAAU,CAAC,EAAE,EAAE,MAAM;IAGrB,mBAAmB;IAGnB,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;IAGzB,cAAc;CAGrB"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * An in-memory {@link SessionLike} standing in for the DO's real continuous
3
+ * Session. Shared by the turn, decomposition, and composition specs so a change
4
+ * to the Session contract breaks in one place.
5
+ *
6
+ * Mirrors the two real behaviors the phased pipeline depends on:
7
+ *
8
+ * - `appendMessage` **dedupes by id** — appending an existing id is a no-op, the
9
+ * property that makes deterministic-id appends exactly-once on a step re-run.
10
+ * - `getMessage` reads the raw stored message back.
11
+ */
12
+ export class FakeSession {
13
+ messages = [];
14
+ system = "SOUL BLOCK\n\n## memory\n(empty)";
15
+ /** Compaction overlays to report — non-empty gates the `recall` tool on. */
16
+ compactions = [];
17
+ appendMessage(m) {
18
+ if (this.messages.some((existing) => existing.id === m.id))
19
+ return;
20
+ this.messages.push(m);
21
+ }
22
+ async getHistory() {
23
+ return this.messages;
24
+ }
25
+ async getMessage(id) {
26
+ return this.messages.find((m) => m.id === id) ?? null;
27
+ }
28
+ async refreshSystemPrompt() {
29
+ return this.system;
30
+ }
31
+ async tools() {
32
+ return {};
33
+ }
34
+ async getCompactions() {
35
+ return this.compactions;
36
+ }
37
+ }
38
+ //# sourceMappingURL=fake-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fake-session.js","sourceRoot":"","sources":["../../src/testing/fake-session.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,MAAM,OAAO,WAAW;IACtB,QAAQ,GAAqB,EAAE,CAAC;IAChC,MAAM,GAAG,kCAAkC,CAAC;IAC5C,4EAA4E;IAC5E,WAAW,GAAc,EAAE,CAAC;IAE5B,aAAa,CAAC,CAAiB;QAC7B,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;YAAE,OAAO;QACnE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;IACD,KAAK,CAAC,UAAU;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,EAAU;QACzB,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC;IACxD,CAAC;IACD,KAAK,CAAC,mBAAmB;QACvB,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IACD,KAAK,CAAC,KAAK;QACT,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,KAAK,CAAC,cAAc;QAClB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF"}
@@ -0,0 +1,27 @@
1
+ import { type JWK } from "jose";
2
+ import { type Message, type Task, type TaskState } from "@a2a-js/sdk";
3
+ /** The gateway origin used in all tests. Must match vitest.config.ts and the MockAgent setup. */
4
+ export declare const GATEWAY_ORIGIN = "https://gateway.test";
5
+ /** Agent origin matching `url.origin` for requests to `http://localhost`. */
6
+ export declare const AGENT_ORIGIN = "http://localhost";
7
+ /** Fixed Ed25519 private JWK used as A2A_SIGNING_KEY in tests. */
8
+ export declare const TEST_AGENT_PRIVATE_JWK: JWK & {
9
+ kid: string;
10
+ };
11
+ /** Fixed Ed25519 private JWK for signing gateway JWTs in tests. */
12
+ export declare const TEST_GATEWAY_PRIVATE_JWK: JWK & {
13
+ kid: string;
14
+ };
15
+ /** Public JWKS the gateway would serve at its `jku` (the private key minus `d`). */
16
+ export declare function gatewayPublicJwks(): string;
17
+ /**
18
+ * Build an A2A v1.0 `TaskStatus` for tests. The generated protobuf types require
19
+ * every field to be present (`message` included, holding `undefined` when there
20
+ * is none), so this keeps the specs from spelling that out each time.
21
+ */
22
+ export declare function testStatus(state: TaskState, message?: Message): NonNullable<Task["status"]>;
23
+ /** An agent-role `Message` carrying a single v1.0 text part. */
24
+ export declare function testAgentMessage(messageId: string, text: string, contextId?: string, taskId?: string): Message;
25
+ /** A complete v1.0 `Task` in the given state. */
26
+ export declare function testTask(id: string, contextId: string, state: TaskState, message?: Message): Task;
27
+ //# sourceMappingURL=fixtures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../src/testing/fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,EAAQ,KAAK,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAE5E,iGAAiG;AACjG,eAAO,MAAM,cAAc,yBAAyB,CAAC;AAErD,6EAA6E;AAC7E,eAAO,MAAM,YAAY,qBAAqB,CAAC;AAE/C,kEAAkE;AAClE,eAAO,MAAM,sBAAsB,EAAE,GAAG,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAMvD,CAAC;AAEF,mEAAmE;AACnE,eAAO,MAAM,wBAAwB,EAAE,GAAG,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAMzD,CAAC;AAEF,oFAAoF;AACpF,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,EAChB,OAAO,CAAC,EAAE,OAAO,GAChB,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAE7B;AAED,gEAAgE;AAChE,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,SAAS,SAAK,EACd,MAAM,SAAK,GACV,OAAO,CAkBT;AAED,iDAAiD;AACjD,wBAAgB,QAAQ,CACtB,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,SAAS,EAChB,OAAO,CAAC,EAAE,OAAO,GAChB,IAAI,CASN"}
@@ -0,0 +1,67 @@
1
+ import {} from "jose";
2
+ import { Role } from "@a2a-js/sdk";
3
+ /** The gateway origin used in all tests. Must match vitest.config.ts and the MockAgent setup. */
4
+ export const GATEWAY_ORIGIN = "https://gateway.test";
5
+ /** Agent origin matching `url.origin` for requests to `http://localhost`. */
6
+ export const AGENT_ORIGIN = "http://localhost";
7
+ /** Fixed Ed25519 private JWK used as A2A_SIGNING_KEY in tests. */
8
+ export const TEST_AGENT_PRIVATE_JWK = {
9
+ crv: "Ed25519",
10
+ d: "sbR9EgZV1zUY-K6ENkvSLY8c8Q9kJ9NnxsXc4GVx_1g",
11
+ x: "1dXrUHeE89GBnZbd7MjzJK-3Xvu7khZCK9ZrQauZQ6s",
12
+ kty: "OKP",
13
+ kid: "test-agent-key-1"
14
+ };
15
+ /** Fixed Ed25519 private JWK for signing gateway JWTs in tests. */
16
+ export const TEST_GATEWAY_PRIVATE_JWK = {
17
+ crv: "Ed25519",
18
+ d: "OVKcn3LDH-qybNIdUbr7T9wbmlxNk2maU4_nILbaLKY",
19
+ x: "jYiAbquXL6db7RihLvp2nsp1ShAolDI0tGOjuwsZVnI",
20
+ kty: "OKP",
21
+ kid: "test-gw-key-1"
22
+ };
23
+ /** Public JWKS the gateway would serve at its `jku` (the private key minus `d`). */
24
+ export function gatewayPublicJwks() {
25
+ const { d: _d, ...pub } = TEST_GATEWAY_PRIVATE_JWK;
26
+ return JSON.stringify({ keys: [{ ...pub, use: "sig", alg: "EdDSA" }] });
27
+ }
28
+ /**
29
+ * Build an A2A v1.0 `TaskStatus` for tests. The generated protobuf types require
30
+ * every field to be present (`message` included, holding `undefined` when there
31
+ * is none), so this keeps the specs from spelling that out each time.
32
+ */
33
+ export function testStatus(state, message) {
34
+ return { state, message, timestamp: new Date().toISOString() };
35
+ }
36
+ /** An agent-role `Message` carrying a single v1.0 text part. */
37
+ export function testAgentMessage(messageId, text, contextId = "", taskId = "") {
38
+ return {
39
+ messageId,
40
+ contextId,
41
+ taskId,
42
+ role: Role.ROLE_AGENT,
43
+ parts: [
44
+ {
45
+ content: { $case: "text", value: text },
46
+ metadata: undefined,
47
+ filename: "",
48
+ mediaType: "text/plain"
49
+ }
50
+ ],
51
+ metadata: undefined,
52
+ extensions: [],
53
+ referenceTaskIds: []
54
+ };
55
+ }
56
+ /** A complete v1.0 `Task` in the given state. */
57
+ export function testTask(id, contextId, state, message) {
58
+ return {
59
+ id,
60
+ contextId,
61
+ status: testStatus(state, message),
62
+ artifacts: [],
63
+ history: [],
64
+ metadata: undefined
65
+ };
66
+ }
67
+ //# sourceMappingURL=fixtures.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../../src/testing/fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,MAAM,MAAM,CAAC;AAChC,OAAO,EAAE,IAAI,EAA2C,MAAM,aAAa,CAAC;AAE5E,iGAAiG;AACjG,MAAM,CAAC,MAAM,cAAc,GAAG,sBAAsB,CAAC;AAErD,6EAA6E;AAC7E,MAAM,CAAC,MAAM,YAAY,GAAG,kBAAkB,CAAC;AAE/C,kEAAkE;AAClE,MAAM,CAAC,MAAM,sBAAsB,GAA0B;IAC3D,GAAG,EAAE,SAAS;IACd,CAAC,EAAE,6CAA6C;IAChD,CAAC,EAAE,6CAA6C;IAChD,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,kBAAkB;CACxB,CAAC;AAEF,mEAAmE;AACnE,MAAM,CAAC,MAAM,wBAAwB,GAA0B;IAC7D,GAAG,EAAE,SAAS;IACd,CAAC,EAAE,6CAA6C;IAChD,CAAC,EAAE,6CAA6C;IAChD,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,eAAe;CACrB,CAAC;AAEF,oFAAoF;AACpF,MAAM,UAAU,iBAAiB;IAC/B,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,GAAG,wBAAwB,CAAC;IACnD,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;AAC1E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CACxB,KAAgB,EAChB,OAAiB;IAEjB,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;AACjE,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,gBAAgB,CAC9B,SAAiB,EACjB,IAAY,EACZ,SAAS,GAAG,EAAE,EACd,MAAM,GAAG,EAAE;IAEX,OAAO;QACL,SAAS;QACT,SAAS;QACT,MAAM;QACN,IAAI,EAAE,IAAI,CAAC,UAAU;QACrB,KAAK,EAAE;YACL;gBACE,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE;gBACvC,QAAQ,EAAE,SAAS;gBACnB,QAAQ,EAAE,EAAE;gBACZ,SAAS,EAAE,YAAY;aACxB;SACF;QACD,QAAQ,EAAE,SAAS;QACnB,UAAU,EAAE,EAAE;QACd,gBAAgB,EAAE,EAAE;KACrB,CAAC;AACJ,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,QAAQ,CACtB,EAAU,EACV,SAAiB,EACjB,KAAgB,EAChB,OAAiB;IAEjB,OAAO;QACL,EAAE;QACF,SAAS;QACT,MAAM,EAAE,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC;QAClC,SAAS,EAAE,EAAE;QACb,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE,SAAS;KACpB,CAAC;AACJ,CAAC"}