@agent-compose/sdk 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +145 -33
- package/dist/agent/agent-loop.d.ts +83 -5
- package/dist/agent/run-agent.d.ts +34 -9
- package/dist/client.d.ts +247 -99
- package/dist/index.d.ts +26 -11
- package/dist/index.js +1967 -745
- package/dist/processors/builtins.d.ts +35 -0
- package/dist/processors/index.d.ts +4 -0
- package/dist/processors/processor.d.ts +91 -0
- package/dist/processors/processor.test.d.ts +1 -0
- package/dist/processors/runner.d.ts +19 -0
- package/dist/request-context/index.d.ts +2 -0
- package/dist/request-context/request-context.d.ts +159 -0
- package/dist/request-context/request-context.test.d.ts +1 -0
- package/dist/runtimes/claude.d.ts +27 -50
- package/dist/runtimes/openai-desktop.js +1918 -741
- package/dist/runtimes/vercel.d.ts +34 -0
- package/dist/runtimes/vercel.js +474 -0
- package/dist/sandbox.d.ts +29 -25
- package/dist/step-invocation/__tests__/invoker.test.d.ts +1 -0
- package/dist/step-invocation/__tests__/protocol.test.d.ts +1 -0
- package/dist/step-invocation/__tests__/server.test.d.ts +1 -0
- package/dist/step-invocation/index.d.ts +25 -0
- package/dist/step-invocation/invoker.d.ts +65 -0
- package/dist/step-invocation/protocol.d.ts +44 -0
- package/dist/step-invocation/server.d.ts +63 -0
- package/dist/step-invocation/types.d.ts +72 -0
- package/dist/tools/coding.d.ts +49 -0
- package/dist/tools/coding.test.d.ts +1 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/types/events.d.ts +36 -0
- package/dist/types/execution-context.d.ts +22 -0
- package/dist/types/runtime.d.ts +32 -0
- package/dist/types/sandbox-environment.d.ts +5 -2
- package/dist/types/sandbox.d.ts +14 -12
- package/dist/types/workflow-metadata.d.ts +51 -0
- package/dist/types/workflow-plan.d.ts +19 -0
- package/dist/types/workflow.d.ts +57 -17
- package/dist/utils/bundler.d.ts +62 -3
- package/dist/workflow-steps/__tests__/observability.test.d.ts +1 -0
- package/dist/workflow-steps/index.d.ts +10 -0
- package/dist/workflow-steps/observability.d.ts +58 -0
- package/dist/workflow-steps/runner.d.ts +96 -0
- package/dist/workflow-steps/step.d.ts +25 -0
- package/dist/workflow-steps/types.d.ts +135 -0
- package/dist/workflow-steps/workflow-steps.test.d.ts +1 -0
- package/dist/workflow-steps/workflow.d.ts +50 -0
- package/dist/workflows/engine.d.ts +27 -13
- package/dist/workflows/invoke-child.d.ts +10 -0
- package/package.json +25 -15
- package/src/agent/agent-loop.ts +197 -26
- package/src/agent/run-agent.ts +40 -15
- package/src/client.ts +326 -76
- package/src/index.ts +124 -10
- package/src/processors/builtins.ts +72 -0
- package/src/processors/index.ts +15 -0
- package/src/processors/processor.ts +103 -0
- package/src/processors/runner.ts +42 -0
- package/src/request-context/index.ts +17 -0
- package/src/request-context/request-context.ts +302 -0
- package/src/runtimes/claude.ts +123 -254
- package/src/runtimes/vercel.ts +180 -0
- package/src/sandbox.ts +53 -21
- package/src/step-invocation/index.ts +33 -0
- package/src/step-invocation/invoker.ts +204 -0
- package/src/step-invocation/protocol.ts +57 -0
- package/src/step-invocation/server.ts +184 -0
- package/src/step-invocation/types.ts +70 -0
- package/src/tools/coding.ts +126 -0
- package/src/tools/index.ts +8 -0
- package/src/types/events.ts +40 -0
- package/src/types/execution-context.ts +30 -0
- package/src/types/runtime.ts +24 -0
- package/src/types/sandbox-environment.ts +7 -5
- package/src/types/sandbox.ts +16 -12
- package/src/types/workflow-metadata.ts +84 -0
- package/src/types/workflow-plan.ts +24 -0
- package/src/types/workflow.ts +139 -25
- package/src/utils/bundler.ts +198 -18
- package/src/utils/source-loader.ts +2 -2
- package/src/workflow-steps/index.ts +30 -0
- package/src/workflow-steps/observability.ts +103 -0
- package/src/workflow-steps/runner.ts +244 -0
- package/src/workflow-steps/step.ts +38 -0
- package/src/workflow-steps/types.ts +134 -0
- package/src/workflow-steps/workflow.ts +95 -0
- package/src/workflows/engine.ts +69 -40
- package/src/workflows/invoke-child.ts +29 -0
package/src/client.ts
CHANGED
|
@@ -14,8 +14,10 @@
|
|
|
14
14
|
import { ofetch } from "ofetch";
|
|
15
15
|
import { AgentComposeError } from "./errors.js";
|
|
16
16
|
import { parseSseStream } from "./sse.js";
|
|
17
|
-
import type { RunEvent } from "./types/events.js";
|
|
18
17
|
import type { SandboxNetworkPolicy } from "./sandbox.js";
|
|
18
|
+
import type { RunEvent } from "./types/events.js";
|
|
19
|
+
import type { WorkflowPlan } from "./types/workflow-plan.js";
|
|
20
|
+
import type { WorkflowManifest } from "./utils/bundler.js";
|
|
19
21
|
|
|
20
22
|
/** UUID-v4-ish — matches the server-side predicate. Used to auto-detect
|
|
21
23
|
* that `process.env.RUN_ID` was injected by the runner sandbox (rather
|
|
@@ -48,13 +50,237 @@ export interface RegisterResult {
|
|
|
48
50
|
id: string;
|
|
49
51
|
name: string;
|
|
50
52
|
version: string;
|
|
51
|
-
runtimes?:
|
|
53
|
+
runtimes?: RegisteredRuntime[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface RegisteredRuntime {
|
|
57
|
+
id: string;
|
|
58
|
+
name: string;
|
|
59
|
+
version: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface RuntimeSourceInput {
|
|
63
|
+
name: string;
|
|
64
|
+
source: string;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface RegisterWorkflowInput {
|
|
68
|
+
name: string;
|
|
69
|
+
source: string;
|
|
70
|
+
/** Structured attestation produced by `bundleWorkflow`. The server
|
|
71
|
+
* requires this on every registration; it proves the source was
|
|
72
|
+
* bundled by a `defineWorkflow`-aware toolchain. The server validates
|
|
73
|
+
* the manifest's shape and verifies `manifest.sourceHash` matches
|
|
74
|
+
* sha256(source) — the source bytes themselves are never parsed or
|
|
75
|
+
* executed on the server. */
|
|
76
|
+
manifest: WorkflowManifest;
|
|
77
|
+
version?: string;
|
|
78
|
+
schedule?: string;
|
|
79
|
+
runtimes?: RuntimeSourceInput[];
|
|
80
|
+
networkPolicy?: unknown;
|
|
81
|
+
placeholders?: Record<string, string>;
|
|
82
|
+
/** Reference to a snapshot the runner should boot from at run start. */
|
|
83
|
+
snapshot?: string;
|
|
84
|
+
/** If true, runs default to capturing a long-lived sandbox snapshot on success. */
|
|
85
|
+
saveSnapshot?: boolean;
|
|
86
|
+
/** Provider-neutral execution plan detected by the CLI bundler. */
|
|
87
|
+
workflowPlan?: WorkflowPlan;
|
|
88
|
+
/** Workflow Memory extraction config. Defaults to "default" when omitted. */
|
|
89
|
+
memory?: "default" | false | { workflow: string };
|
|
90
|
+
/** Factory slug. Defaults to `"default"`. */
|
|
91
|
+
factorySlug?: string;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export type RunState = "running" | "success" | "failed" | "abandoned" | "canceled";
|
|
95
|
+
|
|
96
|
+
export interface InvokeWorkflowOptions {
|
|
97
|
+
/** Per-invocation snapshot override: run UUID, workflow name, or `name@version`. */
|
|
98
|
+
snapshot?: string;
|
|
99
|
+
/** Per-invocation snapshot capture override. */
|
|
100
|
+
saveSnapshot?: boolean;
|
|
101
|
+
/** Per-invocation network policy override. Replaces the template-level
|
|
102
|
+
* policy for this run only — registered metadata is not mutated. */
|
|
103
|
+
networkPolicy?: SandboxNetworkPolicy;
|
|
104
|
+
/** Per-invocation placeholder override. Maps secret names referenced in
|
|
105
|
+
* `networkPolicy` ($VAR) to the values the runner should see for env
|
|
106
|
+
* vars after brokering. Replaces the template-level placeholders for
|
|
107
|
+
* this run only — registered metadata is not mutated. */
|
|
108
|
+
placeholders?: Record<string, string>;
|
|
109
|
+
/** Explicit parent run id. Pass `null` to suppress ambient RUN_ID auto-detection. */
|
|
110
|
+
parentRunId?: string | null;
|
|
111
|
+
/** Agent loop inside the parent run that caused this invoke, when applicable. */
|
|
112
|
+
agentId?: string | null;
|
|
113
|
+
/** Factory slug. Defaults to `"default"`. */
|
|
114
|
+
factorySlug?: string;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface InvokeAndWaitOptions extends InvokeWorkflowOptions {
|
|
118
|
+
timeoutMs?: number;
|
|
119
|
+
pollIntervalMs?: number;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface InvokeResult {
|
|
123
|
+
id: string;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface ListSnapshotsOptions {
|
|
127
|
+
workflow?: string;
|
|
128
|
+
limit?: number;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface TemplateRow {
|
|
132
|
+
name: string;
|
|
133
|
+
version: string;
|
|
134
|
+
factorySlug: string;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface ListTemplatesOptions {
|
|
138
|
+
factorySlug?: string;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface CreateFactoryInput {
|
|
142
|
+
slug: string;
|
|
143
|
+
name: string;
|
|
144
|
+
description?: string;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export interface UpdateFactoryInput {
|
|
148
|
+
name?: string;
|
|
149
|
+
description?: string;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export interface SecretOptions {
|
|
153
|
+
factorySlug?: string;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface SetSecretResult {
|
|
157
|
+
key: string;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export interface SecretListEntry {
|
|
161
|
+
key: string;
|
|
162
|
+
createdAt: string;
|
|
163
|
+
updatedAt: string;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export interface CreateApiKeyInput {
|
|
167
|
+
name?: string;
|
|
168
|
+
scopes?: string[];
|
|
169
|
+
expiresAt?: string;
|
|
170
|
+
factorySlug?: string;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export interface StreamRunLogsOptions {
|
|
174
|
+
lastEventId?: number;
|
|
175
|
+
signal?: AbortSignal;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export interface RunStatus<TOutput = unknown> {
|
|
179
|
+
id: string;
|
|
180
|
+
status: RunState;
|
|
181
|
+
output?: TOutput;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export interface RunDetail<TOutput = unknown> {
|
|
185
|
+
runId: string;
|
|
186
|
+
title: string;
|
|
187
|
+
metadata: Record<string, unknown>;
|
|
188
|
+
outcome: string;
|
|
189
|
+
startedAt: string;
|
|
190
|
+
endedAt: string | null;
|
|
191
|
+
durationMs: number | null;
|
|
192
|
+
failureReason: string | null;
|
|
193
|
+
input: unknown;
|
|
194
|
+
output: TOutput | null;
|
|
195
|
+
lifecycleEvents: Array<{ at: string; type: string; payload: unknown }>;
|
|
196
|
+
children?: RunDetail[];
|
|
52
197
|
}
|
|
53
198
|
|
|
54
|
-
export interface
|
|
199
|
+
export interface TimelineEvent {
|
|
200
|
+
kind: string;
|
|
201
|
+
at: string;
|
|
202
|
+
seq: number;
|
|
203
|
+
type: string;
|
|
204
|
+
payload: Record<string, unknown>;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export type EventSubjectType = "run" | "agent" | "workflow" | "factory";
|
|
208
|
+
|
|
209
|
+
export interface EventRow {
|
|
55
210
|
id: string;
|
|
56
|
-
|
|
57
|
-
|
|
211
|
+
teamId: string;
|
|
212
|
+
subjectType: EventSubjectType | string;
|
|
213
|
+
subjectId: string;
|
|
214
|
+
runId: string | null;
|
|
215
|
+
agentId: string | null;
|
|
216
|
+
workflowId: string | null;
|
|
217
|
+
factoryId: string | null;
|
|
218
|
+
name: string;
|
|
219
|
+
body: unknown;
|
|
220
|
+
summary: string | null;
|
|
221
|
+
confidence: string | null;
|
|
222
|
+
timestamp: string;
|
|
223
|
+
attributes: Record<string, unknown>;
|
|
224
|
+
propagate: boolean;
|
|
225
|
+
idempotencyKey: string | null;
|
|
226
|
+
createdAt: string;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export interface ReportEventInput {
|
|
230
|
+
name: string;
|
|
231
|
+
body: unknown;
|
|
232
|
+
summary?: string;
|
|
233
|
+
confidence?: number;
|
|
234
|
+
timestamp?: string | Date;
|
|
235
|
+
attributes?: Record<string, unknown>;
|
|
236
|
+
propagate?: boolean;
|
|
237
|
+
idempotencyKey?: string;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export interface ListEventsOptions {
|
|
241
|
+
factorySlug?: string;
|
|
242
|
+
limit?: number;
|
|
243
|
+
/** Case-insensitive substring match. Server uses `ILIKE %name%`, so
|
|
244
|
+
* `"mem"` matches `memory.fact`, `memory.usage`, etc. Pass the
|
|
245
|
+
* full event name for an effectively-exact filter (any string is a
|
|
246
|
+
* substring of itself). */
|
|
247
|
+
name?: string;
|
|
248
|
+
/** Date-range lower bound: only include events at or after this
|
|
249
|
+
* timestamp. Used by the dashboard's range toggle (1h / 24h / 7d
|
|
250
|
+
* / 30d). Same semantics as `from` on the runs list endpoint. */
|
|
251
|
+
from?: string;
|
|
252
|
+
/** Timestamp cursor for "load older" pagination. Pass the
|
|
253
|
+
* `timestamp` of the last row from the previous page; the server
|
|
254
|
+
* returns rows strictly older than that. Distinct from `from`:
|
|
255
|
+
* `from` filters a date range, `before` walks the page boundary.
|
|
256
|
+
* Both can be supplied together for a paginated range-query. */
|
|
257
|
+
before?: string;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export interface ListEventsResult {
|
|
261
|
+
events: EventRow[];
|
|
262
|
+
has_more: boolean;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/** One captured stdout or stderr line from a run's sandbox subprocess.
|
|
266
|
+
* `id` is per-run monotonically increasing — pass the highest `id`
|
|
267
|
+
* you've seen as `afterId` to paginate forward. */
|
|
268
|
+
export interface RunLogLine {
|
|
269
|
+
id: number;
|
|
270
|
+
at: string;
|
|
271
|
+
stream: "stdout" | "stderr";
|
|
272
|
+
line: string;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export interface ListRunLogsOptions {
|
|
276
|
+
/** Return only lines with `id > afterId` (forward pagination). */
|
|
277
|
+
afterId?: number;
|
|
278
|
+
/** Max lines (server clamps to [1, 1000], defaults to 200). */
|
|
279
|
+
limit?: number;
|
|
280
|
+
/** Stream direction. `"asc"` (default) returns the oldest lines first
|
|
281
|
+
* — use with `afterId` to paginate forward. `"desc"` returns the newest
|
|
282
|
+
* lines first — use to fetch the last N lines of a finished run. */
|
|
283
|
+
direction?: "asc" | "desc";
|
|
58
284
|
}
|
|
59
285
|
|
|
60
286
|
/** Row shape returned by `GET /api-keys`. */
|
|
@@ -133,27 +359,7 @@ export class AgentComposeClient {
|
|
|
133
359
|
|
|
134
360
|
/** Register (or update) a workflow template inside a factory. Defaults to
|
|
135
361
|
* the team's `default` factory when `factorySlug` is omitted. */
|
|
136
|
-
register(payload: {
|
|
137
|
-
name: string;
|
|
138
|
-
source: string;
|
|
139
|
-
version?: string;
|
|
140
|
-
schedule?: string;
|
|
141
|
-
runtimes?: Array<{ name: string; source: string }>;
|
|
142
|
-
networkPolicy?: unknown;
|
|
143
|
-
placeholders?: Record<string, string>;
|
|
144
|
-
/** Reference to a snapshot the runner should boot from at run start.
|
|
145
|
-
* A run UUID, workflow name, or `name@version`. The referenced
|
|
146
|
-
* workflow must have been registered with `--build` (or any prior
|
|
147
|
-
* successful run with `saveSnapshot: true`). Per-invocation
|
|
148
|
-
* `invoke({ snapshot })` overrides this default. */
|
|
149
|
-
snapshot?: string;
|
|
150
|
-
/** If true, runs default to capturing a long-lived sandbox snapshot on
|
|
151
|
-
* success. Individual invocations can override via
|
|
152
|
-
* `invoke(..., { saveSnapshot })`. */
|
|
153
|
-
saveSnapshot?: boolean;
|
|
154
|
-
/** Factory slug. Defaults to `"default"`. */
|
|
155
|
-
factorySlug?: string;
|
|
156
|
-
}): Promise<RegisterResult> {
|
|
362
|
+
register(payload: RegisterWorkflowInput): Promise<RegisterResult> {
|
|
157
363
|
const { factorySlug = DEFAULT_FACTORY, ...body } = payload;
|
|
158
364
|
return this.fetch(templatePath(factorySlug), { method: "POST", body });
|
|
159
365
|
}
|
|
@@ -183,15 +389,8 @@ export class AgentComposeClient {
|
|
|
183
389
|
invoke(
|
|
184
390
|
name: string,
|
|
185
391
|
input?: Record<string, unknown>,
|
|
186
|
-
opts?:
|
|
187
|
-
|
|
188
|
-
saveSnapshot?: boolean;
|
|
189
|
-
parentRunId?: string | null;
|
|
190
|
-
factorySlug?: string;
|
|
191
|
-
networkPolicy?: SandboxNetworkPolicy;
|
|
192
|
-
placeholders?: Record<string, string>;
|
|
193
|
-
},
|
|
194
|
-
): Promise<{ id: string }> {
|
|
392
|
+
opts?: InvokeWorkflowOptions,
|
|
393
|
+
): Promise<InvokeResult> {
|
|
195
394
|
const parentRunId = opts?.parentRunId === undefined
|
|
196
395
|
? detectAmbientParentRunId()
|
|
197
396
|
: opts.parentRunId;
|
|
@@ -200,11 +399,12 @@ export class AgentComposeClient {
|
|
|
200
399
|
method: "POST",
|
|
201
400
|
body: {
|
|
202
401
|
input,
|
|
203
|
-
...(opts?.snapshot
|
|
204
|
-
...(opts?.saveSnapshot
|
|
205
|
-
...(parentRunId ? { parentRunId } : {}),
|
|
402
|
+
...(opts?.snapshot !== undefined ? { snapshot: opts.snapshot } : {}),
|
|
403
|
+
...(opts?.saveSnapshot !== undefined ? { saveSnapshot: opts.saveSnapshot } : {}),
|
|
206
404
|
...(opts?.networkPolicy !== undefined ? { networkPolicy: opts.networkPolicy } : {}),
|
|
207
405
|
...(opts?.placeholders !== undefined ? { placeholders: opts.placeholders } : {}),
|
|
406
|
+
...(parentRunId ? { parentRunId } : {}),
|
|
407
|
+
...(opts?.agentId ? { agentId: opts.agentId } : {}),
|
|
208
408
|
},
|
|
209
409
|
});
|
|
210
410
|
}
|
|
@@ -216,33 +416,20 @@ export class AgentComposeClient {
|
|
|
216
416
|
* Defaults: `timeoutMs = 30min`, `pollIntervalMs = 1000ms`. Tune down for
|
|
217
417
|
* tests, tune up for long-running workflows. The parent-child auto-
|
|
218
418
|
* detection from `invoke()` applies here too. */
|
|
219
|
-
async invokeAndWait(
|
|
419
|
+
async invokeAndWait<TOutput = unknown>(
|
|
220
420
|
name: string,
|
|
221
421
|
input?: Record<string, unknown>,
|
|
222
|
-
opts?:
|
|
223
|
-
|
|
224
|
-
saveSnapshot?: boolean;
|
|
225
|
-
parentRunId?: string | null;
|
|
226
|
-
factorySlug?: string;
|
|
227
|
-
networkPolicy?: SandboxNetworkPolicy;
|
|
228
|
-
placeholders?: Record<string, string>;
|
|
229
|
-
timeoutMs?: number;
|
|
230
|
-
pollIntervalMs?: number;
|
|
231
|
-
},
|
|
232
|
-
): Promise<RunStatus> {
|
|
422
|
+
opts?: InvokeAndWaitOptions,
|
|
423
|
+
): Promise<RunStatus<TOutput>> {
|
|
233
424
|
const timeoutMs = opts?.timeoutMs ?? 30 * 60 * 1000;
|
|
234
425
|
const pollMs = opts?.pollIntervalMs ?? 1000;
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
...(opts?.factorySlug !== undefined ? { factorySlug: opts.factorySlug } : {}),
|
|
240
|
-
...(opts?.networkPolicy !== undefined ? { networkPolicy: opts.networkPolicy } : {}),
|
|
241
|
-
...(opts?.placeholders !== undefined ? { placeholders: opts.placeholders } : {}),
|
|
242
|
-
});
|
|
426
|
+
// InvokeAndWaitOptions extends InvokeWorkflowOptions, so we can forward
|
|
427
|
+
// `opts` directly — invoke() picks only the fields it sends, so the
|
|
428
|
+
// extra `timeoutMs` / `pollIntervalMs` never leak into the request body.
|
|
429
|
+
const { id: runId } = await this.invoke(name, input, opts);
|
|
243
430
|
const deadline = Date.now() + timeoutMs;
|
|
244
431
|
while (Date.now() < deadline) {
|
|
245
|
-
const status = await this.getStatus(runId);
|
|
432
|
+
const status = await this.getStatus<TOutput>(runId);
|
|
246
433
|
if (status.status === "success" || status.status === "failed" || status.status === "abandoned") {
|
|
247
434
|
return status;
|
|
248
435
|
}
|
|
@@ -255,7 +442,7 @@ export class AgentComposeClient {
|
|
|
255
442
|
}
|
|
256
443
|
|
|
257
444
|
/** List runs this account has captured snapshots for. */
|
|
258
|
-
async listSnapshots(opts?:
|
|
445
|
+
async listSnapshots(opts?: ListSnapshotsOptions): Promise<SnapshotListEntry[]> {
|
|
259
446
|
const q = new URLSearchParams();
|
|
260
447
|
if (opts?.workflow) q.set("workflow", opts.workflow);
|
|
261
448
|
if (opts?.limit != null) q.set("limit", String(opts.limit));
|
|
@@ -271,20 +458,88 @@ export class AgentComposeClient {
|
|
|
271
458
|
}
|
|
272
459
|
|
|
273
460
|
/** Poll run status. */
|
|
274
|
-
getStatus(runId: string): Promise<RunStatus
|
|
461
|
+
getStatus<TOutput = unknown>(runId: string): Promise<RunStatus<TOutput>> {
|
|
275
462
|
return this.fetch(`/api/v1/workflows/${runId}/status`);
|
|
276
463
|
}
|
|
277
464
|
|
|
465
|
+
/** Full run detail, including input/output and lifecycle events. */
|
|
466
|
+
getRun<TOutput = unknown>(runId: string): Promise<RunDetail<TOutput>> {
|
|
467
|
+
return this.fetch(`/api/v1/workflows/${encodeURIComponent(runId)}`);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/** Ordered lifecycle timeline for one run. */
|
|
471
|
+
async getRunTimeline(runId: string, opts?: { limit?: number; offset?: number }): Promise<TimelineEvent[]> {
|
|
472
|
+
const q = new URLSearchParams();
|
|
473
|
+
if (opts?.limit !== undefined) q.set("limit", String(opts.limit));
|
|
474
|
+
if (opts?.offset !== undefined) q.set("offset", String(opts.offset));
|
|
475
|
+
const body = await this.fetch<{ events: TimelineEvent[] }>(
|
|
476
|
+
`/api/v1/workflows/${encodeURIComponent(runId)}/timeline${q.toString() ? `?${q}` : ""}`,
|
|
477
|
+
);
|
|
478
|
+
return body.events;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/** Report a durable event against a run. Events are late-binding facts
|
|
482
|
+
* like quality.accepted, defect.regression, or intervention.override. */
|
|
483
|
+
async reportEvent(runId: string, input: ReportEventInput): Promise<EventRow> {
|
|
484
|
+
const body = {
|
|
485
|
+
...input,
|
|
486
|
+
...(input.timestamp instanceof Date ? { timestamp: input.timestamp.toISOString() } : {}),
|
|
487
|
+
};
|
|
488
|
+
const response = await this.fetch<{ event: EventRow }>(`/api/v1/workflows/${encodeURIComponent(runId)}/events`, {
|
|
489
|
+
method: "POST",
|
|
490
|
+
body,
|
|
491
|
+
});
|
|
492
|
+
return response.event;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
async listRunEvents(runId: string): Promise<EventRow[]> {
|
|
496
|
+
const body = await this.fetch<{ events: EventRow[] }>(`/api/v1/workflows/${encodeURIComponent(runId)}/events`);
|
|
497
|
+
return body.events;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/** List events ingested into a factory, newest first. Supports
|
|
501
|
+
* case-insensitive substring filter (`name`) and timestamp-cursor
|
|
502
|
+
* pagination (`before`). Returns `{ events, has_more }` — the
|
|
503
|
+
* `has_more` flag is the signal to render a "load more" affordance
|
|
504
|
+
* or fire a follow-up request with `before = events.at(-1).timestamp`. */
|
|
505
|
+
async listFactoryEvents(opts?: ListEventsOptions): Promise<ListEventsResult> {
|
|
506
|
+
const factorySlug = opts?.factorySlug ?? DEFAULT_FACTORY;
|
|
507
|
+
const q = new URLSearchParams();
|
|
508
|
+
if (opts?.limit != null) q.set("limit", String(opts.limit));
|
|
509
|
+
if (opts?.name) q.set("name", opts.name);
|
|
510
|
+
if (opts?.from) q.set("from", opts.from);
|
|
511
|
+
if (opts?.before) q.set("before", opts.before);
|
|
512
|
+
return this.fetch<ListEventsResult>(
|
|
513
|
+
`/api/v1/factories/${encodeURIComponent(factorySlug)}/events${q.toString() ? `?${q}` : ""}`,
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/** Fetch captured stdout / stderr lines for a run, ordered by insertion
|
|
518
|
+
* sequence. Pass `afterId` (the highest `id` from a prior page) for
|
|
519
|
+
* forward pagination — useful for tail-style polling without
|
|
520
|
+
* re-fetching the whole stream. `limit` defaults to 200 server-side and
|
|
521
|
+
* is clamped to [1, 1000]. */
|
|
522
|
+
async listRunLogs(runId: string, opts?: ListRunLogsOptions): Promise<RunLogLine[]> {
|
|
523
|
+
const q = new URLSearchParams();
|
|
524
|
+
if (opts?.afterId !== undefined) q.set("afterId", String(opts.afterId));
|
|
525
|
+
if (opts?.limit !== undefined) q.set("limit", String(opts.limit));
|
|
526
|
+
if (opts?.direction !== undefined) q.set("direction", opts.direction);
|
|
527
|
+
const body = await this.fetch<{ logs: RunLogLine[] }>(
|
|
528
|
+
`/api/v1/workflows/${encodeURIComponent(runId)}/logs${q.toString() ? `?${q}` : ""}`,
|
|
529
|
+
);
|
|
530
|
+
return body.logs;
|
|
531
|
+
}
|
|
532
|
+
|
|
278
533
|
/** List registered workflow templates. When `factorySlug` is supplied,
|
|
279
534
|
* scopes to that factory; otherwise returns every template the team can
|
|
280
535
|
* see across every factory in one round trip — each row carries its
|
|
281
536
|
* `factorySlug` so callers can route per-template actions to the right
|
|
282
537
|
* factory. */
|
|
283
|
-
async listTemplates(opts?:
|
|
538
|
+
async listTemplates(opts?: ListTemplatesOptions): Promise<TemplateRow[]> {
|
|
284
539
|
const path = opts?.factorySlug
|
|
285
540
|
? templatePath(opts.factorySlug)
|
|
286
541
|
: "/api/v1/templates";
|
|
287
|
-
const body = await this.fetch<{ templates:
|
|
542
|
+
const body = await this.fetch<{ templates: TemplateRow[] }>(path);
|
|
288
543
|
return body.templates;
|
|
289
544
|
}
|
|
290
545
|
|
|
@@ -299,7 +554,7 @@ export class AgentComposeClient {
|
|
|
299
554
|
|
|
300
555
|
/** Create a factory. `slug` must be lowercase kebab-case and unique
|
|
301
556
|
* within the team. */
|
|
302
|
-
createFactory(payload:
|
|
557
|
+
createFactory(payload: CreateFactoryInput): Promise<FactoryRow> {
|
|
303
558
|
return this.fetch<FactoryRow>("/api/v1/factories", { method: "POST", body: payload });
|
|
304
559
|
}
|
|
305
560
|
|
|
@@ -309,7 +564,7 @@ export class AgentComposeClient {
|
|
|
309
564
|
}
|
|
310
565
|
|
|
311
566
|
/** Rename or describe a factory. */
|
|
312
|
-
updateFactory(slug: string, updates:
|
|
567
|
+
updateFactory(slug: string, updates: UpdateFactoryInput): Promise<FactoryRow> {
|
|
313
568
|
return this.fetch<FactoryRow>(`/api/v1/factories/${encodeURIComponent(slug)}`, { method: "PATCH", body: updates });
|
|
314
569
|
}
|
|
315
570
|
|
|
@@ -324,7 +579,7 @@ export class AgentComposeClient {
|
|
|
324
579
|
// `factorySlug` defaults to `"default"`.
|
|
325
580
|
|
|
326
581
|
/** Create or update a workflow secret. Value is stored in GCP Secret Manager. */
|
|
327
|
-
setSecret(workflowName: string, key: string, value: string, opts?:
|
|
582
|
+
setSecret(workflowName: string, key: string, value: string, opts?: SecretOptions): Promise<SetSecretResult> {
|
|
328
583
|
const factorySlug = opts?.factorySlug ?? DEFAULT_FACTORY;
|
|
329
584
|
return this.fetch(templatePath(factorySlug, workflowName, "secrets"), {
|
|
330
585
|
method: "POST",
|
|
@@ -333,7 +588,7 @@ export class AgentComposeClient {
|
|
|
333
588
|
}
|
|
334
589
|
|
|
335
590
|
/** List secret keys registered for a workflow (metadata only — values are never returned). */
|
|
336
|
-
async listSecrets(workflowName: string, opts?:
|
|
591
|
+
async listSecrets(workflowName: string, opts?: SecretOptions): Promise<SecretListEntry[]> {
|
|
337
592
|
const factorySlug = opts?.factorySlug ?? DEFAULT_FACTORY;
|
|
338
593
|
const body = await this.fetch<{ secrets: Array<{ secretKey: string; createdAt: string; updatedAt: string }> }>(
|
|
339
594
|
templatePath(factorySlug, workflowName, "secrets"),
|
|
@@ -342,7 +597,7 @@ export class AgentComposeClient {
|
|
|
342
597
|
}
|
|
343
598
|
|
|
344
599
|
/** Delete a workflow secret. */
|
|
345
|
-
deleteSecret(workflowName: string, key: string, opts?:
|
|
600
|
+
deleteSecret(workflowName: string, key: string, opts?: SecretOptions): Promise<void> {
|
|
346
601
|
const factorySlug = opts?.factorySlug ?? DEFAULT_FACTORY;
|
|
347
602
|
return this.fetch(templatePath(factorySlug, workflowName, "secrets", key), { method: "DELETE" });
|
|
348
603
|
}
|
|
@@ -355,12 +610,7 @@ export class AgentComposeClient {
|
|
|
355
610
|
*
|
|
356
611
|
* When `factorySlug` is set, the new key is restricted to that factory.
|
|
357
612
|
* Factory-scoped keys can only mint other keys bound to the same factory. */
|
|
358
|
-
createApiKey(input: {
|
|
359
|
-
name?: string;
|
|
360
|
-
scopes?: string[];
|
|
361
|
-
expiresAt?: string;
|
|
362
|
-
factorySlug?: string;
|
|
363
|
-
}): Promise<ApiKeyCreated> {
|
|
613
|
+
createApiKey(input: CreateApiKeyInput): Promise<ApiKeyCreated> {
|
|
364
614
|
return this.fetch<ApiKeyCreated>("/api-keys", { method: "POST", body: input });
|
|
365
615
|
}
|
|
366
616
|
|
|
@@ -398,7 +648,7 @@ export class AgentComposeClient {
|
|
|
398
648
|
* `lastEventId` enables resume — pass the highest `seq` you've already
|
|
399
649
|
* processed to receive only events you missed.
|
|
400
650
|
*
|
|
401
|
-
* `
|
|
651
|
+
* `event` can be used to abort the stream from the caller side.
|
|
402
652
|
*
|
|
403
653
|
* Uses raw `fetch` (not ofetch) because SSE requires access to the
|
|
404
654
|
* response's `ReadableStream`, which ofetch consumes when parsing. Auth
|
|
@@ -406,7 +656,7 @@ export class AgentComposeClient {
|
|
|
406
656
|
* non-2xx responses throw the same `AgentComposeError`. */
|
|
407
657
|
async *streamRunLogs(
|
|
408
658
|
runId: string,
|
|
409
|
-
opts?:
|
|
659
|
+
opts?: StreamRunLogsOptions,
|
|
410
660
|
): AsyncGenerator<RunEvent> {
|
|
411
661
|
const headers: Record<string, string> = { Authorization: `Bearer ${this.apiKey}` };
|
|
412
662
|
if (opts?.lastEventId && opts.lastEventId > 0) {
|