antpath 0.10.14 → 0.11.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 (77) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +16 -8
  3. package/dist/_shared/blueprint.d.ts +93 -108
  4. package/dist/_shared/blueprint.js +144 -78
  5. package/dist/_shared/cleanup-policy.d.ts +2 -2
  6. package/dist/_shared/cleanup-policy.js +2 -5
  7. package/dist/_shared/http.d.ts +2 -2
  8. package/dist/_shared/index.d.ts +7 -1
  9. package/dist/_shared/index.js +6 -1
  10. package/dist/_shared/mcp-proxy-url.d.ts +55 -0
  11. package/dist/_shared/mcp-proxy-url.js +65 -0
  12. package/dist/_shared/operations.d.ts +55 -8
  13. package/dist/_shared/operations.js +163 -20
  14. package/dist/_shared/provider-proxy-url.d.ts +64 -0
  15. package/dist/_shared/provider-proxy-url.js +73 -0
  16. package/dist/_shared/proxy-validation.d.ts +1 -1
  17. package/dist/_shared/proxy-validation.js +2 -2
  18. package/dist/_shared/run-unit.d.ts +23 -36
  19. package/dist/_shared/run-unit.js +30 -46
  20. package/dist/_shared/runner-event.d.ts +120 -0
  21. package/dist/_shared/runner-event.js +193 -0
  22. package/dist/_shared/runner-job.d.ts +159 -0
  23. package/dist/_shared/runner-job.js +54 -0
  24. package/dist/_shared/runtime-manifest.d.ts +191 -0
  25. package/dist/_shared/runtime-manifest.js +221 -0
  26. package/dist/_shared/runtime-types.d.ts +7 -16
  27. package/dist/_shared/sse.d.ts +74 -0
  28. package/dist/_shared/sse.js +0 -0
  29. package/dist/_shared/stable.d.ts +15 -10
  30. package/dist/_shared/stable.js +15 -10
  31. package/dist/_shared/submission.d.ts +199 -73
  32. package/dist/_shared/submission.js +409 -210
  33. package/dist/_shared/telemetry.d.ts +2 -2
  34. package/dist/_shared/telemetry.js +2 -2
  35. package/dist/_shared/template/index.d.ts +0 -1
  36. package/dist/_shared/template/index.js +0 -1
  37. package/dist/agents-md.d.ts +25 -67
  38. package/dist/agents-md.js +35 -121
  39. package/dist/agents-md.js.map +1 -1
  40. package/dist/asset-upload.d.ts +34 -0
  41. package/dist/asset-upload.js +34 -0
  42. package/dist/asset-upload.js.map +1 -1
  43. package/dist/blueprint.d.ts +3 -3
  44. package/dist/bundle.d.ts +2 -2
  45. package/dist/bundle.js +1 -1
  46. package/dist/cli.mjs +559 -105
  47. package/dist/cli.mjs.sha256 +1 -1
  48. package/dist/client.d.ts +53 -22
  49. package/dist/client.js +196 -130
  50. package/dist/client.js.map +1 -1
  51. package/dist/file.d.ts +28 -94
  52. package/dist/file.js +35 -175
  53. package/dist/file.js.map +1 -1
  54. package/dist/index.d.ts +5 -5
  55. package/dist/index.js +4 -0
  56. package/dist/index.js.map +1 -1
  57. package/dist/mcp-server.d.ts +10 -2
  58. package/dist/mcp-server.js +17 -2
  59. package/dist/mcp-server.js.map +1 -1
  60. package/dist/skill.d.ts +44 -214
  61. package/dist/skill.js +50 -284
  62. package/dist/skill.js.map +1 -1
  63. package/dist/version.d.ts +1 -1
  64. package/dist/version.js +1 -1
  65. package/dist/version.js.map +1 -1
  66. package/docs/cleanup.md +1 -1
  67. package/docs/credentials.md +2 -2
  68. package/docs/events.md +8 -8
  69. package/docs/outputs.md +2 -0
  70. package/docs/quickstart.md +18 -2
  71. package/docs/skills.md +1 -3
  72. package/docs/templates.md +6 -5
  73. package/package.json +2 -1
  74. package/dist/_shared/secrets.d.ts +0 -7
  75. package/dist/_shared/secrets.js +0 -20
  76. package/dist/_shared/template/mapper.d.ts +0 -11
  77. package/dist/_shared/template/mapper.js +0 -70
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Unified runner event schema. Both runtimes feed the same shape into
3
+ * the api.antpath.ai event pipeline:
4
+ *
5
+ * - **Anthropic Native** — the `AnthropicSseInbox` Durable Object
6
+ * consumes Anthropic's `/v1/messages/stream` SSE stream and uses
7
+ * the Anthropic adapter to translate each event into one or more
8
+ * `RunnerEvent`s.
9
+ * - **Goose Managed** — the per-run runner image POSTs batches of
10
+ * NDJSON events to `/runs/{id}/runner/events`; the Goose adapter
11
+ * translates each event into one or more `RunnerEvent`s.
12
+ *
13
+ * The downstream subscribers (dashboard, SDK `streamEvents`, observable
14
+ * spans) never see the runtime-specific wire shapes — they only see
15
+ * `RunnerEvent`s. This is the cutover boundary that makes the dual
16
+ * runtime invisible to customers.
17
+ *
18
+ * See `references/platform-rebuild-2026.md` (Wire contracts →
19
+ * runner-event).
20
+ */
21
+ import type { JsonValue } from "./submission.js";
22
+ /**
23
+ * Schema version. Bump when the shape of `RunnerEvent`, its kind set,
24
+ * or the batch envelope changes. Subscribers gate on this so a future
25
+ * v2 wire shape can land behind a feature flag.
26
+ */
27
+ export declare const RUNNER_EVENT_VERSION: 1;
28
+ /**
29
+ * The set of event kinds emitted into the unified stream. Adapters
30
+ * fold runtime-specific events into one of these — anything that
31
+ * doesn't fit is mapped to `notification` so the data is captured
32
+ * even when no UI handler exists yet.
33
+ *
34
+ * - `runtime_started` — either runtime announced "ready" (Fly
35
+ * machine running goose; Anthropic session
36
+ * accepted the first turn).
37
+ * - `assistant_text` — model text delta.
38
+ * - `tool_request` — model emitted a tool_use / function call.
39
+ * - `tool_response` — tool result delivered back to the model.
40
+ * - `skill_loaded` — a skill was loaded (Anthropic Skills API
41
+ * ref OR a workspace folder mount).
42
+ * - `file_uploaded` — a file became available to the agent
43
+ * (Files API id OR workspace path).
44
+ * - `notification` — runtime/extension notification; catch-all
45
+ * for diagnostic data.
46
+ * - `stream_error` — stream-level error (non-fatal). Subscribers
47
+ * may surface this as a UI warning; the run
48
+ * continues unless `runtime_terminal` follows.
49
+ * - `runtime_terminal` — the run reached a terminal state. The
50
+ * adapter MUST emit exactly one of these per
51
+ * run; subscribers gate on it for end-of-stream.
52
+ */
53
+ export declare const RUNNER_EVENT_KINDS: readonly ["runtime_started", "assistant_text", "tool_request", "tool_response", "skill_loaded", "file_uploaded", "notification", "stream_error", "runtime_terminal"];
54
+ export type RunnerEventKind = (typeof RUNNER_EVENT_KINDS)[number];
55
+ /**
56
+ * One event in the unified stream. `seq` is monotonically increasing
57
+ * within a single run (the adapter is responsible for assigning seqs
58
+ * — no two events with the same `seq` for the same `runId`); `tMs` is
59
+ * a millisecond-resolution timestamp that is also monotonically
60
+ * non-decreasing within a single run (an event's `tMs` is never less
61
+ * than the previous event's `tMs`). `data` carries the runtime- and
62
+ * kind-specific payload, JSON-typed so the batch round-trips through
63
+ * the database column without ad-hoc serialization.
64
+ */
65
+ export interface RunnerEvent {
66
+ readonly seq: number;
67
+ readonly tMs: number;
68
+ readonly kind: RunnerEventKind;
69
+ readonly data: Readonly<Record<string, JsonValue>>;
70
+ }
71
+ /**
72
+ * Batch envelope. The runner ships one or more events per POST so the
73
+ * inbox writes them atomically. `events` MUST be sorted by `seq`
74
+ * ascending; api.antpath.ai rejects malformed batches before touching
75
+ * Postgres.
76
+ */
77
+ export interface RunnerEventBatch {
78
+ readonly v: typeof RUNNER_EVENT_VERSION;
79
+ readonly runId: string;
80
+ readonly events: readonly RunnerEvent[];
81
+ }
82
+ /**
83
+ * Maximum number of events per batch. Bounds the size of the body
84
+ * api.antpath.ai accepts and the size of the Durable Object write.
85
+ * Larger streams are split into multiple batches; the runner is
86
+ * responsible for chunking.
87
+ */
88
+ export declare const RUNNER_EVENT_BATCH_MAX_EVENTS: 256;
89
+ /**
90
+ * Validation outcome for an inbound batch. The `ok` branch returns
91
+ * the parsed batch with frozen events; the `error` branch returns the
92
+ * code + a short human message suitable for an HTTP 400 body. Codes
93
+ * are stable strings — the dashboard / SDK may branch on them.
94
+ */
95
+ export type RunnerEventBatchValidation = {
96
+ readonly ok: true;
97
+ readonly batch: RunnerEventBatch;
98
+ } | {
99
+ readonly ok: false;
100
+ readonly code: RunnerEventBatchValidationCode;
101
+ readonly message: string;
102
+ };
103
+ export declare const RUNNER_EVENT_BATCH_VALIDATION_CODES: readonly ["invalid_envelope", "version_mismatch", "missing_run_id", "empty_batch", "batch_too_large", "invalid_event", "seq_not_monotonic", "t_ms_not_monotonic"];
104
+ export type RunnerEventBatchValidationCode = (typeof RUNNER_EVENT_BATCH_VALIDATION_CODES)[number];
105
+ /**
106
+ * Parse + validate an inbound runner event batch (untrusted input).
107
+ * Used at the api.antpath.ai ingress so adapters never have to
108
+ * re-check the wire shape, and used by tests to assert the contract.
109
+ *
110
+ * Successful validation guarantees:
111
+ * - top-level envelope matches {@link RunnerEventBatch}
112
+ * - `v === RUNNER_EVENT_VERSION`
113
+ * - `runId` is a non-empty string
114
+ * - `events` is a non-empty array of at most
115
+ * {@link RUNNER_EVENT_BATCH_MAX_EVENTS} entries
116
+ * - each event is a {@link RunnerEvent} with a known `kind`
117
+ * - `seq` is strictly increasing across the batch
118
+ * - `tMs` is non-decreasing across the batch
119
+ */
120
+ export declare function validateRunnerEventBatch(input: unknown): RunnerEventBatchValidation;
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Unified runner event schema. Both runtimes feed the same shape into
3
+ * the api.antpath.ai event pipeline:
4
+ *
5
+ * - **Anthropic Native** — the `AnthropicSseInbox` Durable Object
6
+ * consumes Anthropic's `/v1/messages/stream` SSE stream and uses
7
+ * the Anthropic adapter to translate each event into one or more
8
+ * `RunnerEvent`s.
9
+ * - **Goose Managed** — the per-run runner image POSTs batches of
10
+ * NDJSON events to `/runs/{id}/runner/events`; the Goose adapter
11
+ * translates each event into one or more `RunnerEvent`s.
12
+ *
13
+ * The downstream subscribers (dashboard, SDK `streamEvents`, observable
14
+ * spans) never see the runtime-specific wire shapes — they only see
15
+ * `RunnerEvent`s. This is the cutover boundary that makes the dual
16
+ * runtime invisible to customers.
17
+ *
18
+ * See `references/platform-rebuild-2026.md` (Wire contracts →
19
+ * runner-event).
20
+ */
21
+ /**
22
+ * Schema version. Bump when the shape of `RunnerEvent`, its kind set,
23
+ * or the batch envelope changes. Subscribers gate on this so a future
24
+ * v2 wire shape can land behind a feature flag.
25
+ */
26
+ export const RUNNER_EVENT_VERSION = 1;
27
+ /**
28
+ * The set of event kinds emitted into the unified stream. Adapters
29
+ * fold runtime-specific events into one of these — anything that
30
+ * doesn't fit is mapped to `notification` so the data is captured
31
+ * even when no UI handler exists yet.
32
+ *
33
+ * - `runtime_started` — either runtime announced "ready" (Fly
34
+ * machine running goose; Anthropic session
35
+ * accepted the first turn).
36
+ * - `assistant_text` — model text delta.
37
+ * - `tool_request` — model emitted a tool_use / function call.
38
+ * - `tool_response` — tool result delivered back to the model.
39
+ * - `skill_loaded` — a skill was loaded (Anthropic Skills API
40
+ * ref OR a workspace folder mount).
41
+ * - `file_uploaded` — a file became available to the agent
42
+ * (Files API id OR workspace path).
43
+ * - `notification` — runtime/extension notification; catch-all
44
+ * for diagnostic data.
45
+ * - `stream_error` — stream-level error (non-fatal). Subscribers
46
+ * may surface this as a UI warning; the run
47
+ * continues unless `runtime_terminal` follows.
48
+ * - `runtime_terminal` — the run reached a terminal state. The
49
+ * adapter MUST emit exactly one of these per
50
+ * run; subscribers gate on it for end-of-stream.
51
+ */
52
+ export const RUNNER_EVENT_KINDS = [
53
+ "runtime_started",
54
+ "assistant_text",
55
+ "tool_request",
56
+ "tool_response",
57
+ "skill_loaded",
58
+ "file_uploaded",
59
+ "notification",
60
+ "stream_error",
61
+ "runtime_terminal"
62
+ ];
63
+ /**
64
+ * Maximum number of events per batch. Bounds the size of the body
65
+ * api.antpath.ai accepts and the size of the Durable Object write.
66
+ * Larger streams are split into multiple batches; the runner is
67
+ * responsible for chunking.
68
+ */
69
+ export const RUNNER_EVENT_BATCH_MAX_EVENTS = 256;
70
+ export const RUNNER_EVENT_BATCH_VALIDATION_CODES = [
71
+ "invalid_envelope",
72
+ "version_mismatch",
73
+ "missing_run_id",
74
+ "empty_batch",
75
+ "batch_too_large",
76
+ "invalid_event",
77
+ "seq_not_monotonic",
78
+ "t_ms_not_monotonic"
79
+ ];
80
+ /**
81
+ * Parse + validate an inbound runner event batch (untrusted input).
82
+ * Used at the api.antpath.ai ingress so adapters never have to
83
+ * re-check the wire shape, and used by tests to assert the contract.
84
+ *
85
+ * Successful validation guarantees:
86
+ * - top-level envelope matches {@link RunnerEventBatch}
87
+ * - `v === RUNNER_EVENT_VERSION`
88
+ * - `runId` is a non-empty string
89
+ * - `events` is a non-empty array of at most
90
+ * {@link RUNNER_EVENT_BATCH_MAX_EVENTS} entries
91
+ * - each event is a {@link RunnerEvent} with a known `kind`
92
+ * - `seq` is strictly increasing across the batch
93
+ * - `tMs` is non-decreasing across the batch
94
+ */
95
+ export function validateRunnerEventBatch(input) {
96
+ if (!isRecord(input)) {
97
+ return invalid("invalid_envelope", "batch must be a JSON object");
98
+ }
99
+ if (input.v !== RUNNER_EVENT_VERSION) {
100
+ return invalid("version_mismatch", `batch.v must equal ${RUNNER_EVENT_VERSION} (got ${JSON.stringify(input.v)})`);
101
+ }
102
+ if (typeof input.runId !== "string" || input.runId.length === 0) {
103
+ return invalid("missing_run_id", "batch.runId must be a non-empty string");
104
+ }
105
+ if (!Array.isArray(input.events) || input.events.length === 0) {
106
+ return invalid("empty_batch", "batch.events must be a non-empty array");
107
+ }
108
+ if (input.events.length > RUNNER_EVENT_BATCH_MAX_EVENTS) {
109
+ return invalid("batch_too_large", `batch.events has ${input.events.length} entries; max is ${RUNNER_EVENT_BATCH_MAX_EVENTS}`);
110
+ }
111
+ let lastSeq = Number.NEGATIVE_INFINITY;
112
+ let lastTMs = Number.NEGATIVE_INFINITY;
113
+ const events = [];
114
+ for (let i = 0; i < input.events.length; i++) {
115
+ const evt = input.events[i];
116
+ if (!isRecord(evt)) {
117
+ return invalid("invalid_event", `events[${i}] must be a JSON object`);
118
+ }
119
+ if (typeof evt.seq !== "number" ||
120
+ !Number.isFinite(evt.seq) ||
121
+ !Number.isInteger(evt.seq) ||
122
+ evt.seq < 0) {
123
+ return invalid("invalid_event", `events[${i}].seq must be a non-negative integer`);
124
+ }
125
+ if (typeof evt.tMs !== "number" ||
126
+ !Number.isFinite(evt.tMs) ||
127
+ !Number.isInteger(evt.tMs) ||
128
+ evt.tMs < 0) {
129
+ return invalid("invalid_event", `events[${i}].tMs must be a non-negative integer`);
130
+ }
131
+ if (typeof evt.kind !== "string" ||
132
+ !RUNNER_EVENT_KINDS.includes(evt.kind)) {
133
+ return invalid("invalid_event", `events[${i}].kind must be one of: ${RUNNER_EVENT_KINDS.join(", ")} (got ${JSON.stringify(evt.kind)})`);
134
+ }
135
+ if (!isRecord(evt.data)) {
136
+ return invalid("invalid_event", `events[${i}].data must be a JSON object`);
137
+ }
138
+ if (!isJsonRecord(evt.data)) {
139
+ return invalid("invalid_event", `events[${i}].data must be JSON-serializable`);
140
+ }
141
+ if (evt.seq <= lastSeq) {
142
+ return invalid("seq_not_monotonic", `events[${i}].seq=${evt.seq} must be strictly greater than the previous seq=${lastSeq}`);
143
+ }
144
+ if (evt.tMs < lastTMs) {
145
+ return invalid("t_ms_not_monotonic", `events[${i}].tMs=${evt.tMs} must be >= the previous tMs=${lastTMs}`);
146
+ }
147
+ lastSeq = evt.seq;
148
+ lastTMs = evt.tMs;
149
+ events.push({
150
+ seq: evt.seq,
151
+ tMs: evt.tMs,
152
+ kind: evt.kind,
153
+ data: Object.freeze({ ...evt.data })
154
+ });
155
+ }
156
+ return {
157
+ ok: true,
158
+ batch: { v: RUNNER_EVENT_VERSION, runId: input.runId, events: Object.freeze(events) }
159
+ };
160
+ }
161
+ function invalid(code, message) {
162
+ return { ok: false, code, message };
163
+ }
164
+ function isRecord(input) {
165
+ return typeof input === "object" && input !== null && !Array.isArray(input);
166
+ }
167
+ function isJsonRecord(input) {
168
+ for (const value of Object.values(input)) {
169
+ if (!isJsonValue(value))
170
+ return false;
171
+ }
172
+ return true;
173
+ }
174
+ function isJsonValue(input) {
175
+ if (input === null)
176
+ return true;
177
+ const t = typeof input;
178
+ if (t === "string" || t === "boolean")
179
+ return true;
180
+ if (t === "number")
181
+ return Number.isFinite(input);
182
+ if (Array.isArray(input))
183
+ return input.every(isJsonValue);
184
+ if (isRecord(input)) {
185
+ for (const v of Object.values(input)) {
186
+ if (!isJsonValue(v))
187
+ return false;
188
+ }
189
+ return true;
190
+ }
191
+ return false;
192
+ }
193
+ //# sourceMappingURL=runner-event.js.map
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Per-run runner job for the Goose Managed runtime.
3
+ *
4
+ * The Goose Managed runtime runs a Goose CLI process inside a per-run
5
+ * Fly Machine. This module defines the substrate-independent surface
6
+ * the api.antpath.ai Workflow consumes: the lifecycle statuses, the
7
+ * spec the dispatcher hands to an executor, and the `RunnerJobExecutor`
8
+ * interface every substrate implements (Fly today; tests use an
9
+ * in-memory fake).
10
+ *
11
+ * The Anthropic Native runtime does NOT route through this surface —
12
+ * Anthropic hosts the runtime. Only providers whose runtime Antpath
13
+ * hosts (deepseek, openai, gemini, mistral, plus the customer opt-in
14
+ * `runtime: "managed"` for anthropic) consume the executor.
15
+ *
16
+ * See `references/platform-rebuild-2026.md` (Wire contracts → runner-job).
17
+ */
18
+ import type { RunProvider } from "./submission.js";
19
+ /**
20
+ * Runner-job lifecycle statuses, in the order the api.antpath.ai
21
+ * Workflow walks them. The shared list is the source of truth — keep
22
+ * the DB CHECK constraint on `provider_runtime_jobs.status` in
23
+ * lockstep.
24
+ */
25
+ export declare const PROVIDER_RUNTIME_JOB_STATUSES: readonly ["queued", "provisioning", "running", "stopping", "terminated", "failed"];
26
+ export type ProviderRuntimeJobStatus = (typeof PROVIDER_RUNTIME_JOB_STATUSES)[number];
27
+ /**
28
+ * Substrate identifier — the executor implementation behind the job.
29
+ * `fly` is the only kind today; the platform-rebuild-2026 migration
30
+ * dropped the `railway` kind. Listed as a tuple so adding a new
31
+ * substrate is one line + a matching executor implementation.
32
+ */
33
+ export declare const PROVIDER_RUNTIME_KINDS: readonly ["fly"];
34
+ export type ProviderRuntimeKind = (typeof PROVIDER_RUNTIME_KINDS)[number];
35
+ /**
36
+ * What the api.antpath.ai Workflow hands an executor to start a new
37
+ * runner job. The runner-image, env vars, region, and resource budget
38
+ * are decided ahead of time so the executor only has to call the
39
+ * substrate API.
40
+ */
41
+ export interface RunnerJobSpec {
42
+ readonly runId: string;
43
+ readonly workspaceId: string;
44
+ readonly provider: RunProvider;
45
+ /**
46
+ * Container image reference (Docker registry name + sha256 digest).
47
+ * Pinned by the Workflow at provision time; not derived from the
48
+ * submission so customers cannot select an arbitrary image.
49
+ */
50
+ readonly image: string;
51
+ /**
52
+ * Environment variables the executor must set on the container.
53
+ * The Workflow injects:
54
+ * - `ANTPATH_RUN_ID` + `ANTPATH_API_BASE` + `ANTPATH_RUNNER_TOKEN`
55
+ * so the runner can call back to api.antpath.ai for manifests
56
+ * and event POSTs.
57
+ * - `ANTHROPIC_BASE_URL` + `ANTHROPIC_AUTH_TOKEN` (or the
58
+ * equivalent provider proxy URL + bearer) so Goose talks to
59
+ * LiteLLM through the run-scoped proxy.
60
+ * - `ANTPATH_MCP_BASE` if the submission carries MCP servers.
61
+ */
62
+ readonly env: Readonly<Record<string, string>>;
63
+ /**
64
+ * Hard ceiling on the substrate-side run duration. The runner image
65
+ * also enforces its own timeout; this is the last line of defence
66
+ * against a wedged container.
67
+ */
68
+ readonly maxRunDurationMs: number;
69
+ /**
70
+ * Substrate region (e.g. `"lhr"` for Fly London). Co-located with
71
+ * the LiteLLM gateway so the LLM call doesn't cross a region
72
+ * boundary inside the trust zone.
73
+ */
74
+ readonly region: string;
75
+ /**
76
+ * Optional resource budget. Each substrate maps these to its own
77
+ * machine sizing primitives (Fly: `vm.cpus` + `vm.memory_mb`).
78
+ * Omitting accepts the substrate default.
79
+ */
80
+ readonly resources?: {
81
+ readonly cpus: number;
82
+ readonly memoryMb: number;
83
+ };
84
+ }
85
+ /**
86
+ * Substrate-side identifiers for a started job. The Fly executor
87
+ * returns `appName` + `machineId`; tests with the in-memory fake
88
+ * return deterministic values. The handle MUST round-trip through
89
+ * Postgres (`provider_runtime_jobs.fly_app_name` /
90
+ * `.fly_machine_id`) so a restarted Worker can poll status without
91
+ * needing the in-memory executor state.
92
+ */
93
+ export interface RunnerJobHandle {
94
+ readonly appName: string;
95
+ readonly machineId: string;
96
+ }
97
+ /**
98
+ * Optional resource metrics returned by `getStatus`. Surface what the
99
+ * substrate publishes; absent fields are reported as `undefined`. The
100
+ * Workflow forwards these into the `run_events` stream under the
101
+ * `notification` kind so dashboards have a cheap signal that the job
102
+ * is alive and within budget.
103
+ */
104
+ export interface ResourceStats {
105
+ readonly cpuPercent?: number;
106
+ readonly memoryMb?: number;
107
+ readonly networkRxBytes?: number;
108
+ readonly networkTxBytes?: number;
109
+ }
110
+ export interface RunnerJobStatusSnapshot {
111
+ readonly status: ProviderRuntimeJobStatus;
112
+ readonly terminalErrorClass?: string;
113
+ readonly terminalErrorMessage?: string;
114
+ readonly resourceStats?: ResourceStats;
115
+ }
116
+ /**
117
+ * The substrate-independent runner-job surface. Implementations live
118
+ * in `apps/api/src/runtimes/goose/runners/<kind>/` (e.g.
119
+ * `runners/fly/`); test fakes live alongside.
120
+ *
121
+ * Method semantics:
122
+ * - `start(spec)` provisions the runtime container and returns the
123
+ * substrate-specific ids the Workflow should persist in
124
+ * `provider_runtime_jobs`. MUST be idempotent under retry by
125
+ * `spec.runId` — duplicate calls return the same ids.
126
+ * - `getStatus(handle)` polls the substrate for the current status
127
+ * plus any new terminal error info and optional resource metrics.
128
+ * - `stop(handle)` initiates a graceful shutdown of the container.
129
+ * Used on cancel, timeout, and at provider-terminal cleanup.
130
+ * MUST be idempotent — operators may invoke it manually on a
131
+ * stuck job. `graceMs` is an upper bound on the substrate's
132
+ * SIGTERM → SIGKILL window.
133
+ * - `tailLogs(handle, lines?)` returns the most recent stdout/err
134
+ * bytes from the container (best-effort; substrates without log
135
+ * retention may return `null`). Used by the dashboard "view logs"
136
+ * button.
137
+ * - `getConsoleUrl(handle)` returns a human-clickable URL into the
138
+ * substrate console for on-call debugging. Optional — substrates
139
+ * without a console simply omit the method.
140
+ */
141
+ export interface RunnerJobExecutor {
142
+ start(spec: RunnerJobSpec): Promise<RunnerJobHandle>;
143
+ getStatus(handle: RunnerJobHandle): Promise<RunnerJobStatusSnapshot>;
144
+ stop(handle: RunnerJobHandle, opts?: {
145
+ readonly graceMs?: number;
146
+ }): Promise<void>;
147
+ tailLogs?(handle: RunnerJobHandle, lines?: number): Promise<string | null>;
148
+ getConsoleUrl?(handle: RunnerJobHandle): string;
149
+ }
150
+ /**
151
+ * Thrown when a submission selects a provider whose runtime is not
152
+ * yet implemented (e.g. a future provider added to RUN_PROVIDERS
153
+ * before its executor lands). Surfaced uniformly so the dashboard
154
+ * and the SDK render the same error code.
155
+ */
156
+ export declare class RunnerRuntimeNotImplementedError extends Error {
157
+ readonly provider: RunProvider;
158
+ constructor(provider: RunProvider);
159
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Per-run runner job for the Goose Managed runtime.
3
+ *
4
+ * The Goose Managed runtime runs a Goose CLI process inside a per-run
5
+ * Fly Machine. This module defines the substrate-independent surface
6
+ * the api.antpath.ai Workflow consumes: the lifecycle statuses, the
7
+ * spec the dispatcher hands to an executor, and the `RunnerJobExecutor`
8
+ * interface every substrate implements (Fly today; tests use an
9
+ * in-memory fake).
10
+ *
11
+ * The Anthropic Native runtime does NOT route through this surface —
12
+ * Anthropic hosts the runtime. Only providers whose runtime Antpath
13
+ * hosts (deepseek, openai, gemini, mistral, plus the customer opt-in
14
+ * `runtime: "managed"` for anthropic) consume the executor.
15
+ *
16
+ * See `references/platform-rebuild-2026.md` (Wire contracts → runner-job).
17
+ */
18
+ /**
19
+ * Runner-job lifecycle statuses, in the order the api.antpath.ai
20
+ * Workflow walks them. The shared list is the source of truth — keep
21
+ * the DB CHECK constraint on `provider_runtime_jobs.status` in
22
+ * lockstep.
23
+ */
24
+ export const PROVIDER_RUNTIME_JOB_STATUSES = [
25
+ "queued",
26
+ "provisioning",
27
+ "running",
28
+ "stopping",
29
+ "terminated",
30
+ "failed"
31
+ ];
32
+ /**
33
+ * Substrate identifier — the executor implementation behind the job.
34
+ * `fly` is the only kind today; the platform-rebuild-2026 migration
35
+ * dropped the `railway` kind. Listed as a tuple so adding a new
36
+ * substrate is one line + a matching executor implementation.
37
+ */
38
+ export const PROVIDER_RUNTIME_KINDS = ["fly"];
39
+ /**
40
+ * Thrown when a submission selects a provider whose runtime is not
41
+ * yet implemented (e.g. a future provider added to RUN_PROVIDERS
42
+ * before its executor lands). Surfaced uniformly so the dashboard
43
+ * and the SDK render the same error code.
44
+ */
45
+ export class RunnerRuntimeNotImplementedError extends Error {
46
+ provider;
47
+ constructor(provider) {
48
+ super(`runner runtime for provider "${provider}" is not implemented yet — ` +
49
+ `see references/platform-rebuild-2026.md (implementation phases)`);
50
+ this.name = "RunnerRuntimeNotImplementedError";
51
+ this.provider = provider;
52
+ }
53
+ }
54
+ //# sourceMappingURL=runner-job.js.map