stageflow 0.19.0 → 0.25.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 (120) hide show
  1. package/README.md +16 -3
  2. package/dist/a2a/configDiscovery.d.ts +9 -0
  3. package/dist/a2a/configDiscovery.js +18 -0
  4. package/dist/a2a/contracts.d.ts +93 -0
  5. package/dist/a2a/contracts.js +163 -0
  6. package/dist/a2a/limits.d.ts +14 -0
  7. package/dist/a2a/limits.js +29 -0
  8. package/dist/a2a/registry.d.ts +44 -0
  9. package/dist/a2a/registry.js +159 -0
  10. package/dist/a2a/server.d.ts +29 -0
  11. package/dist/a2a/server.js +341 -0
  12. package/dist/a2a/service.d.ts +97 -0
  13. package/dist/a2a/service.js +496 -0
  14. package/dist/a2a/store.d.ts +106 -0
  15. package/dist/a2a/store.js +245 -0
  16. package/dist/agent/activity.d.ts +5 -0
  17. package/dist/agent/activityObserver.d.ts +3 -0
  18. package/dist/agent/activityObserver.js +6 -1
  19. package/dist/agent/piAdapter.js +7 -3
  20. package/dist/agent/port.d.ts +2 -0
  21. package/dist/agent/providerInspect.d.ts +19 -0
  22. package/dist/agent/providerInspect.js +35 -0
  23. package/dist/agent/streamLogRedact.d.ts +2 -0
  24. package/dist/agent/streamLogRedact.js +13 -0
  25. package/dist/cli/a2aCommand.d.ts +8 -0
  26. package/dist/cli/a2aCommand.js +131 -0
  27. package/dist/cli/artifactCommand.js +2 -2
  28. package/dist/cli/envelopeCommand.js +2 -2
  29. package/dist/cli/exportRunCommand.js +2 -2
  30. package/dist/cli/hostClient.d.ts +43 -0
  31. package/dist/cli/hostClient.js +182 -0
  32. package/dist/cli/providersCommand.js +5 -3
  33. package/dist/cli/runCommand.d.ts +6 -5
  34. package/dist/cli/runCommand.js +23 -31
  35. package/dist/cli/runOutput.d.ts +1 -1
  36. package/dist/cli/runStageCommand.d.ts +33 -0
  37. package/dist/cli/runStageCommand.js +407 -0
  38. package/dist/cli/runsCommand.d.ts +3 -7
  39. package/dist/cli/runsCommand.js +33 -94
  40. package/dist/cli.js +20 -5
  41. package/dist/config/describePipeline.d.ts +26 -0
  42. package/dist/config/describePipeline.js +37 -0
  43. package/dist/config/loadPipeline.d.ts +13 -1
  44. package/dist/config/loadPipeline.js +34 -4
  45. package/dist/config/mergePipelineIncludes.d.ts +11 -0
  46. package/dist/config/mergePipelineIncludes.js +75 -0
  47. package/dist/config/validateCatalog.d.ts +2 -2
  48. package/dist/config/validateCatalog.js +24 -17
  49. package/dist/mcp/catalogTools.js +285 -52
  50. package/dist/mcp/controlTools.js +77 -19
  51. package/dist/mcp/deps.d.ts +3 -0
  52. package/dist/mcp/projectMcpTools.d.ts +3 -0
  53. package/dist/mcp/projectMcpTools.js +25 -0
  54. package/dist/mcp/providerTools.d.ts +3 -0
  55. package/dist/mcp/providerTools.js +17 -0
  56. package/dist/mcp/readArtifact.d.ts +9 -0
  57. package/dist/mcp/readArtifact.js +11 -0
  58. package/dist/mcp/server.js +9 -1
  59. package/dist/mcp/tailStreamLog.d.ts +8 -0
  60. package/dist/mcp/tailStreamLog.js +28 -0
  61. package/dist/mcp/toolResults.d.ts +17 -0
  62. package/dist/mcp/toolResults.js +15 -0
  63. package/dist/mcp/tools.js +4 -0
  64. package/dist/mcp/waitRun.js +4 -4
  65. package/dist/mcp/waitingGates.d.ts +1 -0
  66. package/dist/mcp/waitingGates.js +3 -2
  67. package/dist/package-meta.d.ts +1 -1
  68. package/dist/package-meta.js +1 -1
  69. package/dist/projection/projectRun.d.ts +3 -0
  70. package/dist/projection/projectRun.js +7 -0
  71. package/dist/runstore/createStore.d.ts +10 -0
  72. package/dist/runstore/createStore.js +13 -4
  73. package/dist/runstore/port.d.ts +17 -2
  74. package/dist/runstore/sqlite/SqliteRunStore.d.ts +11 -1
  75. package/dist/runstore/sqlite/SqliteRunStore.js +81 -26
  76. package/dist/runstore/sqlite/schema.d.ts +1 -1
  77. package/dist/runstore/sqlite/schema.js +6 -0
  78. package/dist/runstore/submission.d.ts +11 -0
  79. package/dist/runstore/submission.js +7 -0
  80. package/dist/runstore/workspaceLayout.d.ts +1 -0
  81. package/dist/runstore/workspaceLayout.js +3 -0
  82. package/dist/runtime/feedbackLoopCoordinator.d.ts +9 -1
  83. package/dist/runtime/feedbackLoopCoordinator.js +50 -20
  84. package/dist/runtime/feedbackLoopDecision.js +33 -1
  85. package/dist/runtime/pipelineRunner.d.ts +5 -3
  86. package/dist/runtime/pipelineRunner.js +6 -1
  87. package/dist/runtime/pipelineScheduler.js +32 -15
  88. package/dist/runtime/reloadRunCatalog.js +7 -1
  89. package/dist/runtime/resolveEnvelopeRef.d.ts +30 -0
  90. package/dist/runtime/resolveEnvelopeRef.js +79 -0
  91. package/dist/runtime/resumeReconstruct.js +2 -2
  92. package/dist/runtime/runManager.d.ts +24 -2
  93. package/dist/runtime/runManager.js +83 -19
  94. package/dist/runtime/settingsFile.d.ts +2 -0
  95. package/dist/runtime/settingsFile.js +19 -0
  96. package/dist/runtime/stageAttemptBootstrap.d.ts +3 -0
  97. package/dist/runtime/stageAttemptBootstrap.js +8 -2
  98. package/dist/runtime/stageStreamLog.d.ts +17 -0
  99. package/dist/runtime/stageStreamLog.js +89 -0
  100. package/dist/runtime/stageWorker.js +2 -1
  101. package/dist/server/bootstrap.d.ts +2 -0
  102. package/dist/server/bootstrap.js +22 -4
  103. package/dist/server/createHttpHost.js +6 -0
  104. package/dist/server/ensureGlobalService.d.ts +35 -0
  105. package/dist/server/ensureGlobalService.js +138 -0
  106. package/dist/server/http.d.ts +20 -1
  107. package/dist/server/http.js +450 -402
  108. package/dist/server/mcpHost.js +7 -8
  109. package/dist/server/operatorResults.d.ts +10 -0
  110. package/dist/server/operatorResults.js +24 -0
  111. package/dist/server/providerRoutes.d.ts +0 -6
  112. package/dist/server/providerRoutes.js +10 -18
  113. package/dist/types/pipeline.d.ts +8 -0
  114. package/dist/ui/assets/{index-DMVdl1qB.js → index-Da5EHU6M.js} +5 -5
  115. package/dist/ui/index.html +1 -1
  116. package/package.json +2 -1
  117. package/skills/stageflow/references/control-surface.md +2 -2
  118. package/skills/stageflow-run/SKILL.md +27 -9
  119. package/skills/stageflow-run/references/mcp-call.md +1 -1
  120. package/skills/stageflow-run/scripts/mcp-call.mjs +9 -0
@@ -0,0 +1,341 @@
1
+ import { AgentCard, Role, TaskState, } from "@a2a-js/sdk";
2
+ import { JsonRpcTransportHandler, ServerCallContext, validateVersion } from "@a2a-js/sdk/server";
3
+ import { A2AError, RequestMalformedError, TaskNotCancelableError, TaskNotFoundError, UnsupportedOperationError, } from "@a2a-js/sdk/errors";
4
+ import { PACKAGE_VERSION } from "../package-meta.js";
5
+ import { A2aApplicationError } from "./contracts.js";
6
+ import { loadPublicationRegistry } from "./registry.js";
7
+ import { createA2aInvocations } from "./service.js";
8
+ export const A2A_BODY_LIMIT = 1024 * 1024;
9
+ /** Single source of truth for the two sub-routes so the URL builders below and the router in `createA2aHost` can never drift apart. */
10
+ const CONTRACT_ROUTE_PREFIX = "/a2a/contracts/";
11
+ const ARTIFACT_ROUTE_PREFIX = "/a2a/artifacts/";
12
+ function contractUrl(publicUrl, publicationId) {
13
+ return publicUrl + CONTRACT_ROUTE_PREFIX + publicationId;
14
+ }
15
+ function artifactUrl(publicUrl, taskId, artifactId) {
16
+ return publicUrl + ARTIFACT_ROUTE_PREFIX + taskId + "/" + artifactId;
17
+ }
18
+ export function publicationCard(registry, caller) {
19
+ return AgentCard.fromJSON({
20
+ name: "Stageflow",
21
+ description: "Invoke published Stageflow pipelines as A2A capabilities.",
22
+ version: PACKAGE_VERSION,
23
+ supportedInterfaces: [{ url: registry.publicUrl + "/a2a", protocolBinding: "JSONRPC", protocolVersion: "1.0" }],
24
+ capabilities: { streaming: false, pushNotifications: false, extendedAgentCard: true },
25
+ securitySchemes: { bearer: { httpAuthSecurityScheme: { scheme: "bearer" } } },
26
+ securityRequirements: [{ schemes: { bearer: { list: [] } } }],
27
+ defaultInputModes: ["application/json"],
28
+ defaultOutputModes: ["application/json"],
29
+ skills: registry.list(caller).map((publication) => ({
30
+ id: publication.id,
31
+ name: publication.name,
32
+ description: publication.description + " Contract: " + contractUrl(registry.publicUrl, publication.id),
33
+ tags: ["pipeline"],
34
+ inputModes: ["application/json"],
35
+ outputModes: ["application/json"],
36
+ })),
37
+ });
38
+ }
39
+ function mapState(state) {
40
+ switch (state) {
41
+ case "submitted":
42
+ return TaskState.TASK_STATE_SUBMITTED;
43
+ case "working":
44
+ return TaskState.TASK_STATE_WORKING;
45
+ case "input-required":
46
+ return TaskState.TASK_STATE_INPUT_REQUIRED;
47
+ case "completed":
48
+ return TaskState.TASK_STATE_COMPLETED;
49
+ case "failed":
50
+ return TaskState.TASK_STATE_FAILED;
51
+ }
52
+ }
53
+ function dataPart(value) {
54
+ return { content: { $case: "data", value }, metadata: undefined, filename: "", mediaType: "application/json" };
55
+ }
56
+ function urlPart(url, filename, mediaType) {
57
+ return { content: { $case: "url", value: url }, metadata: undefined, filename, mediaType };
58
+ }
59
+ function statusMessage(taskId, contextId, parts) {
60
+ return {
61
+ messageId: "status-" + taskId + "-" + Date.now().toString(36),
62
+ contextId,
63
+ taskId,
64
+ role: Role.ROLE_AGENT,
65
+ parts,
66
+ metadata: undefined,
67
+ extensions: [],
68
+ referenceTaskIds: [],
69
+ };
70
+ }
71
+ function toWireTask(publicUrl, task) {
72
+ const parts = [];
73
+ if (task.state === "input-required" && task.questions) {
74
+ parts.push(dataPart({ questions: task.questions }));
75
+ }
76
+ const artifacts = [];
77
+ if (task.result) {
78
+ if (task.result.payload !== undefined) {
79
+ artifacts.push({
80
+ artifactId: "result",
81
+ name: "result",
82
+ description: task.result.summary,
83
+ parts: [dataPart(task.result.payload)],
84
+ metadata: undefined,
85
+ extensions: [],
86
+ });
87
+ }
88
+ for (const file of task.result.artifacts) {
89
+ artifacts.push({
90
+ artifactId: file.id,
91
+ name: file.name,
92
+ description: "",
93
+ parts: [urlPart(artifactUrl(publicUrl, task.id, file.id), file.name, file.mediaType ?? "application/octet-stream")],
94
+ metadata: undefined,
95
+ extensions: [],
96
+ });
97
+ }
98
+ }
99
+ return {
100
+ id: task.id,
101
+ contextId: task.contextId,
102
+ status: {
103
+ state: mapState(task.state),
104
+ message: parts.length > 0 ? statusMessage(task.id, task.contextId, parts) : undefined,
105
+ timestamp: task.updatedAt,
106
+ },
107
+ artifacts,
108
+ history: [],
109
+ // Only ever set for a "standalone" (ADR-0001 run_stage) task — see PublicTask.runId.
110
+ // This is how a caller learns the run id it needs to chain into its next
111
+ // run_stage call via envelope_ref (ADR-0002); invoke's published-capability
112
+ // tasks keep the run id opaque, unchanged from before this field existed.
113
+ metadata: task.runId ? { runId: task.runId } : undefined,
114
+ };
115
+ }
116
+ function mapApplicationError(err) {
117
+ if (err instanceof A2aApplicationError) {
118
+ if (err.category === "not-found") {
119
+ throw new TaskNotFoundError({ message: err.message });
120
+ }
121
+ if (err.category === "busy" || err.category === "export-failed") {
122
+ throw new A2AError({ message: err.message, metadata: { category: err.category } });
123
+ }
124
+ throw new RequestMalformedError({ message: err.message, metadata: { category: err.category } });
125
+ }
126
+ throw err;
127
+ }
128
+ function realHandler(card, invocations, publicUrl) {
129
+ const unsupportedStream = async function* () {
130
+ throw new UnsupportedOperationError("Streaming is not enabled");
131
+ };
132
+ const pushUnsupported = async () => {
133
+ throw new UnsupportedOperationError("Push notifications are not enabled");
134
+ };
135
+ return {
136
+ getAgentCard: async () => card,
137
+ getAuthenticatedExtendedAgentCard: async () => card,
138
+ async sendMessage(params, context) {
139
+ if (!params.message)
140
+ throw new RequestMalformedError({ message: "A message is required" });
141
+ try {
142
+ const task = await invocations.send({ id: context.user.userName }, params.message);
143
+ return toWireTask(publicUrl, task);
144
+ }
145
+ catch (err) {
146
+ return mapApplicationError(err);
147
+ }
148
+ },
149
+ async getTask(params, context) {
150
+ try {
151
+ const task = await invocations.get({ id: context.user.userName }, params.id);
152
+ return toWireTask(publicUrl, task);
153
+ }
154
+ catch (err) {
155
+ return mapApplicationError(err);
156
+ }
157
+ },
158
+ async listTasks(params, context) {
159
+ try {
160
+ const tasks = await invocations.list({ id: context.user.userName }, params.contextId || undefined);
161
+ const size = params.pageSize && params.pageSize > 0 ? Math.min(params.pageSize, 100) : 50;
162
+ const limited = tasks.slice(0, size);
163
+ return { tasks: limited.map((task) => toWireTask(publicUrl, task)), nextPageToken: "", pageSize: limited.length, totalSize: tasks.length };
164
+ }
165
+ catch (err) {
166
+ return mapApplicationError(err);
167
+ }
168
+ },
169
+ async cancelTask(params, context) {
170
+ try {
171
+ await invocations.get({ id: context.user.userName }, params.id);
172
+ }
173
+ catch (err) {
174
+ return mapApplicationError(err);
175
+ }
176
+ throw new TaskNotCancelableError({ message: "Active pipeline cancellation is not available yet" });
177
+ },
178
+ sendMessageStream: unsupportedStream,
179
+ resubscribe: unsupportedStream,
180
+ createTaskPushNotificationConfig: pushUnsupported,
181
+ getTaskPushNotificationConfig: pushUnsupported,
182
+ listTaskPushNotificationConfigs: pushUnsupported,
183
+ deleteTaskPushNotificationConfig: pushUnsupported,
184
+ };
185
+ }
186
+ function respond(res, status, value) {
187
+ res.writeHead(status, { "Content-Type": "application/json", "Cache-Control": "no-store", "Vary": "Authorization" });
188
+ res.end(JSON.stringify(value));
189
+ }
190
+ async function readBody(req) {
191
+ const chunks = [];
192
+ let length = 0;
193
+ for await (const chunk of req) {
194
+ const bytes = Buffer.from(chunk);
195
+ length += bytes.length;
196
+ if (length > A2A_BODY_LIMIT)
197
+ throw new Error("body_too_large");
198
+ chunks.push(bytes);
199
+ }
200
+ return Buffer.concat(chunks).toString("utf8");
201
+ }
202
+ const RETENTION_SWEEP_INTERVAL_MS = 60 * 60 * 1000;
203
+ export async function createA2aHost(runtime, configPath, env = process.env) {
204
+ let registry;
205
+ let invocations;
206
+ const status = { state: "disabled" };
207
+ if (configPath) {
208
+ status.configPath = configPath;
209
+ try {
210
+ registry = await loadPublicationRegistry(configPath, env);
211
+ status.configPath = registry.configPath;
212
+ status.state = "enabled";
213
+ invocations = createA2aInvocations(registry, runtime.manager, runtime.runStore, runtime.rootDir, runtime.connection);
214
+ }
215
+ catch {
216
+ status.state = "configuration_error";
217
+ }
218
+ }
219
+ const sweep = invocations
220
+ ? setInterval(() => {
221
+ invocations.pruneExpired().catch(() => undefined);
222
+ }, RETENTION_SWEEP_INTERVAL_MS).unref()
223
+ : undefined;
224
+ return {
225
+ status,
226
+ async pruneExpired(now) {
227
+ return (await invocations?.pruneExpired(now)) ?? { removedTasks: 0, removedMessages: 0 };
228
+ },
229
+ close() {
230
+ if (sweep)
231
+ clearInterval(sweep);
232
+ invocations?.close();
233
+ },
234
+ async handle(req, res, pathname) {
235
+ const isRoute = pathname === "/a2a" ||
236
+ pathname === "/.well-known/agent-card.json" ||
237
+ pathname.startsWith(CONTRACT_ROUTE_PREFIX) ||
238
+ pathname.startsWith(ARTIFACT_ROUTE_PREFIX);
239
+ if (!isRoute)
240
+ return false;
241
+ if (!registry || !invocations) {
242
+ respond(res, status.state === "disabled" ? 404 : 503, { error: "A2A unavailable" });
243
+ return true;
244
+ }
245
+ const caller = registry.authenticate(req.headers.authorization);
246
+ if (!caller) {
247
+ res.setHeader("WWW-Authenticate", 'Bearer realm="stageflow-a2a"');
248
+ respond(res, 401, { error: "Authentication required" });
249
+ return true;
250
+ }
251
+ if (pathname.startsWith(ARTIFACT_ROUTE_PREFIX)) {
252
+ if (req.method !== "GET") {
253
+ res.setHeader("Allow", "GET");
254
+ respond(res, 405, { error: "Method not allowed" });
255
+ return true;
256
+ }
257
+ const segments = pathname.slice(ARTIFACT_ROUTE_PREFIX.length).split("/");
258
+ if (segments.length !== 2) {
259
+ respond(res, 404, { error: "Artifact not found" });
260
+ return true;
261
+ }
262
+ try {
263
+ const artifact = await invocations.readArtifact({ id: caller }, segments[0], segments[1]);
264
+ res.writeHead(200, {
265
+ "Content-Type": artifact.mediaType ?? "application/octet-stream",
266
+ "Content-Length": artifact.bytes.length,
267
+ "Cache-Control": "no-store",
268
+ "Vary": "Authorization",
269
+ });
270
+ res.end(artifact.bytes);
271
+ }
272
+ catch {
273
+ respond(res, 404, { error: "Artifact not found" });
274
+ }
275
+ return true;
276
+ }
277
+ const card = publicationCard(registry, caller);
278
+ if (pathname !== "/a2a") {
279
+ if (req.method !== "GET") {
280
+ res.setHeader("Allow", "GET");
281
+ respond(res, 405, { error: "Method not allowed" });
282
+ }
283
+ else if (pathname === "/.well-known/agent-card.json") {
284
+ respond(res, 200, AgentCard.toJSON(card));
285
+ }
286
+ else {
287
+ const publication = registry.get(caller, pathname.slice(CONTRACT_ROUTE_PREFIX.length));
288
+ if (!publication)
289
+ respond(res, 404, { error: "Contract not found" });
290
+ else
291
+ respond(res, 200, {
292
+ contractVersion: 1,
293
+ capability: publication.id,
294
+ revision: publication.revision,
295
+ executionEnabled: true,
296
+ inputSchema: publication.inputSchema,
297
+ outputSchema: publication.outputSchema,
298
+ artifacts: publication.results.artifacts,
299
+ });
300
+ }
301
+ return true;
302
+ }
303
+ if (req.method !== "POST") {
304
+ res.setHeader("Allow", "POST");
305
+ respond(res, 405, { error: "Method not allowed" });
306
+ return true;
307
+ }
308
+ if (req.headers["content-type"]?.split(";")[0].trim().toLowerCase() !== "application/json") {
309
+ respond(res, 415, { error: "Expected application/json" });
310
+ return true;
311
+ }
312
+ if (Number(req.headers["content-length"]) > A2A_BODY_LIMIT) {
313
+ respond(res, 413, { error: "Request too large" });
314
+ return true;
315
+ }
316
+ const version = req.headers["a2a-version"];
317
+ try {
318
+ validateVersion(typeof version === "string" ? version : "0.3", card, "JSONRPC");
319
+ }
320
+ catch (error) {
321
+ respond(res, 400, { jsonrpc: "2.0", id: null, error: JsonRpcTransportHandler.mapToJSONRPCError(error) });
322
+ return true;
323
+ }
324
+ req.setTimeout(30_000, () => req.destroy());
325
+ try {
326
+ const body = await readBody(req);
327
+ const context = new ServerCallContext({ user: { isAuthenticated: true, userName: caller }, requestedVersion: "1.0" });
328
+ const result = await new JsonRpcTransportHandler(realHandler(card, invocations, registry.publicUrl)).handle(body, context);
329
+ respond(res, 200, result);
330
+ }
331
+ catch (error) {
332
+ if (!res.destroyed)
333
+ respond(res, error instanceof Error && error.message === "body_too_large" ? 413 : 400, { error: "Invalid request body" });
334
+ }
335
+ finally {
336
+ req.setTimeout(0);
337
+ }
338
+ return true;
339
+ },
340
+ };
341
+ }
@@ -0,0 +1,97 @@
1
+ import type { RunStore } from "../runstore/port.js";
2
+ import type { RunManager } from "../runtime/runManager.js";
3
+ import type { PublicationRegistry } from "./registry.js";
4
+ import { type IncomingMessage } from "./contracts.js";
5
+ import type Database from "better-sqlite3";
6
+ import { A2aStore, type TaskState } from "./store.js";
7
+ import { RateLimiter } from "./limits.js";
8
+ export type Caller = {
9
+ id: string;
10
+ };
11
+ export type PublicQuestion = {
12
+ handle: string;
13
+ message: string;
14
+ };
15
+ export type PublicArtifact = {
16
+ id: string;
17
+ name: string;
18
+ mediaType?: string;
19
+ size: number;
20
+ };
21
+ export type PublicTask = {
22
+ id: string;
23
+ contextId: string;
24
+ state: TaskState;
25
+ publication: string;
26
+ createdAt: string;
27
+ updatedAt: string;
28
+ questions?: PublicQuestion[];
29
+ waitingForOperator?: boolean;
30
+ result?: {
31
+ summary: string;
32
+ payload?: Record<string, unknown>;
33
+ artifacts: PublicArtifact[];
34
+ };
35
+ /**
36
+ * The underlying run id — only ever populated for a "standalone" (ADR-0001
37
+ * run_stage) task. Published-capability (`invoke`) tasks keep the run id
38
+ * opaque, unchanged from before this field existed. Exposing it here is
39
+ * what makes ADR-0002's `envelope_ref` chaining ({runId, stageId}) usable
40
+ * from an A2A caller in the first place: run_stage's response is the only
41
+ * place a caller can learn the run id of a standalone call it just made,
42
+ * to hand to its *next* run_stage call.
43
+ */
44
+ runId?: string;
45
+ };
46
+ export type ArtifactRead = {
47
+ bytes: Buffer;
48
+ name: string;
49
+ mediaType?: string;
50
+ };
51
+ export declare class A2aInvocations {
52
+ private readonly registry;
53
+ private readonly manager;
54
+ private readonly runStore;
55
+ /** Base directory a `stage`/`pipeline` filesystem reference in a run_stage call resolves against. */
56
+ private readonly rootDir;
57
+ private readonly store;
58
+ private readonly rateLimiter;
59
+ constructor(registry: PublicationRegistry, manager: RunManager, runStore: RunStore,
60
+ /** Base directory a `stage`/`pipeline` filesystem reference in a run_stage call resolves against. */
61
+ rootDir: string, store: A2aStore, rateLimiter?: RateLimiter);
62
+ close(): void;
63
+ /** Deletes terminal tasks and message tombstones past their retention window. Call periodically; the core logic takes an explicit clock so it stays deterministic to test. */
64
+ pruneExpired(now?: Date): Promise<{
65
+ removedTasks: number;
66
+ removedMessages: number;
67
+ }>;
68
+ private checkRate;
69
+ send(caller: Caller, raw: IncomingMessage): Promise<PublicTask>;
70
+ get(caller: Caller, taskId: string): Promise<PublicTask>;
71
+ list(caller: Caller, contextId: string | undefined): Promise<PublicTask[]>;
72
+ readArtifact(caller: Caller, taskId: string, artifactId: string): Promise<ArtifactRead>;
73
+ private requireOwnedTask;
74
+ /**
75
+ * (caller, messageId) dedup shared by invoke and answer: a resend of a message already recorded with
76
+ * the same content hash replays its prior outcome; a resend with different content is a conflict.
77
+ * Returns undefined only for a message this caller has not sent before.
78
+ */
79
+ private replayOrThrow;
80
+ private invoke;
81
+ /**
82
+ * ADR-0001's wildcard-access operation: run any catalog or inline
83
+ * stage/pipeline directly. Deliberately does NOT call `this.registry.get`/
84
+ * `.list` — that allowlist lookup is the entire mechanism `invoke` uses to
85
+ * restrict a caller to its published capabilities, and this operation's
86
+ * whole point is to bypass it. The caller is still authenticated (by the
87
+ * time `send` reaches here) and still rate-limited/admission-capped like
88
+ * any other task.
89
+ */
90
+ private runStandalone;
91
+ private answer;
92
+ private maybeFinalize;
93
+ /** The five PublicTask fields every projection shares; call sites layer in only what differs per state. */
94
+ private buildTask;
95
+ private projectTask;
96
+ }
97
+ export declare function createA2aInvocations(registry: PublicationRegistry, manager: RunManager, runStore: RunStore, rootDir: string, connection?: Database.Database, rateLimiter?: RateLimiter): A2aInvocations;