@managoat/fountain-sdk 1.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 (55) hide show
  1. package/CHANGELOG.md +653 -0
  2. package/LICENSE +202 -0
  3. package/README.md +445 -0
  4. package/dist/client.d.ts +190 -0
  5. package/dist/client.js +225 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/config.d.ts +49 -0
  8. package/dist/config.js +87 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/conversation.d.ts +100 -0
  11. package/dist/conversation.js +189 -0
  12. package/dist/conversation.js.map +1 -0
  13. package/dist/errors.d.ts +102 -0
  14. package/dist/errors.js +197 -0
  15. package/dist/errors.js.map +1 -0
  16. package/dist/generated/openapi.d.ts +16654 -0
  17. package/dist/generated/openapi.js +6 -0
  18. package/dist/generated/openapi.js.map +1 -0
  19. package/dist/http.d.ts +37 -0
  20. package/dist/http.js +129 -0
  21. package/dist/http.js.map +1 -0
  22. package/dist/index.d.ts +14 -0
  23. package/dist/index.js +13 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/node.d.ts +2 -0
  26. package/dist/node.js +21 -0
  27. package/dist/node.js.map +1 -0
  28. package/dist/queue.d.ts +25 -0
  29. package/dist/queue.js +64 -0
  30. package/dist/queue.js.map +1 -0
  31. package/dist/resolve.d.ts +29 -0
  32. package/dist/resolve.js +89 -0
  33. package/dist/resolve.js.map +1 -0
  34. package/dist/resources.d.ts +126 -0
  35. package/dist/resources.js +206 -0
  36. package/dist/resources.js.map +1 -0
  37. package/dist/run.d.ts +81 -0
  38. package/dist/run.js +247 -0
  39. package/dist/run.js.map +1 -0
  40. package/dist/schemas.d.ts +90 -0
  41. package/dist/schemas.js +2 -0
  42. package/dist/schemas.js.map +1 -0
  43. package/dist/sse.d.ts +58 -0
  44. package/dist/sse.js +219 -0
  45. package/dist/sse.js.map +1 -0
  46. package/dist/team.d.ts +90 -0
  47. package/dist/team.js +183 -0
  48. package/dist/team.js.map +1 -0
  49. package/dist/turn.d.ts +46 -0
  50. package/dist/turn.js +205 -0
  51. package/dist/turn.js.map +1 -0
  52. package/dist/types.d.ts +144 -0
  53. package/dist/types.js +2 -0
  54. package/dist/types.js.map +1 -0
  55. package/package.json +61 -0
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Payloads here use the API's own key names (`environment_id`, `mcp_servers`,
3
+ * `allowed_vault_ids`) rather than camelCase. That is a choice, not an
4
+ * oversight: an agent definition is the same object in the REST API, in a
5
+ * `fountain.yml` manifest and here, so one definition reads identically in all
6
+ * three and the API reference doubles as the SDK reference. Options that
7
+ * control the SDK's own behaviour — `timeoutMs`, `signal` — are camelCase,
8
+ * because those are not data.
9
+ */
10
+ /**
11
+ * List, read, define, change and delete one kind of thing.
12
+ *
13
+ * `Patch` is its own parameter rather than `Partial<Input>`: the API's update
14
+ * schemas are not simply every create field made optional, and the generated
15
+ * ones say so exactly.
16
+ */
17
+ class Collection {
18
+ http;
19
+ resolver;
20
+ path;
21
+ what;
22
+ constructor(http, resolver, path, what) {
23
+ this.http = http;
24
+ this.resolver = resolver;
25
+ this.path = path;
26
+ this.what = what;
27
+ }
28
+ /** Everything on the account. */
29
+ async list(search) {
30
+ return this.http.list(this.path, { query: { search } });
31
+ }
32
+ /** One of them, by name or id. */
33
+ async get(nameOrId) {
34
+ const { id } = await this.resolver.resolve(this.path, this.what, nameOrId);
35
+ return this.http.data("GET", `${this.path}/${id}`);
36
+ }
37
+ /** Define a new one. */
38
+ async create(input) {
39
+ const created = await this.http.data("POST", this.path, { body: input });
40
+ // A new name has to be findable by the next `run({ agent: "…" })`.
41
+ this.resolver.forget(this.path);
42
+ return created;
43
+ }
44
+ /** Change one. Only the fields you pass are touched. */
45
+ async update(nameOrId, patch) {
46
+ const { id } = await this.resolver.resolve(this.path, this.what, nameOrId);
47
+ const updated = await this.http.data("PATCH", `${this.path}/${id}`, { body: patch });
48
+ // The patch may have renamed it.
49
+ this.resolver.forget(this.path);
50
+ return updated;
51
+ }
52
+ /** Delete one. */
53
+ async delete(nameOrId) {
54
+ const { id } = await this.resolver.resolve(this.path, this.what, nameOrId);
55
+ await this.http.request("DELETE", `${this.path}/${id}`);
56
+ this.resolver.forget(this.path);
57
+ }
58
+ }
59
+ /**
60
+ * Secrets on an environment or a vault.
61
+ *
62
+ * Values are write-only: `list` returns keys, never what they are worth. That
63
+ * is the whole point — the SDK can put a credential into a sandbox and can
64
+ * never read it back out.
65
+ */
66
+ class Secrets {
67
+ http;
68
+ resolver;
69
+ parentPath;
70
+ what;
71
+ constructor(http, resolver, parentPath, what) {
72
+ this.http = http;
73
+ this.resolver = resolver;
74
+ this.parentPath = parentPath;
75
+ this.what = what;
76
+ }
77
+ /** The keys stored here. Never the values. */
78
+ async list(parent) {
79
+ return this.http.list(`${await this.parentId(parent)}/secrets`);
80
+ }
81
+ /** Store a secret, or replace one with the same key. */
82
+ async set(parent, key, value) {
83
+ return this.http.data("POST", `${await this.parentId(parent)}/secrets`, {
84
+ body: { key, value },
85
+ });
86
+ }
87
+ /** Store several at once. */
88
+ async setAll(parent, secrets) {
89
+ const base = await this.parentId(parent);
90
+ const out = [];
91
+ // Serially: these are audited writes, and a partial failure should say
92
+ // which key it stopped on rather than leave a scattered half-write.
93
+ for (const [key, value] of Object.entries(secrets)) {
94
+ out.push(await this.http.data("POST", `${base}/secrets`, { body: { key, value } }));
95
+ }
96
+ return out;
97
+ }
98
+ /** Remove one, by key. */
99
+ async delete(parent, key) {
100
+ await this.http.request("DELETE", `${await this.parentId(parent)}/secrets/${encodeURIComponent(key)}`);
101
+ }
102
+ async parentId(nameOrId) {
103
+ const { id } = await this.resolver.resolve(this.parentPath, this.what, nameOrId);
104
+ return `${this.parentPath}/${id}`;
105
+ }
106
+ }
107
+ /** Vault metadata can change without reading or replacing its secret value. */
108
+ class VaultSecrets extends Secrets {
109
+ async update(parent, key, patch) {
110
+ return this.http.data("PATCH", `${await this.parentId(parent)}/secrets/${encodeURIComponent(key)}`, { body: patch });
111
+ }
112
+ }
113
+ /** The agents on this account. */
114
+ export class Agents extends Collection {
115
+ constructor(http, resolver) {
116
+ super(http, resolver, "/api/agents", "agent");
117
+ }
118
+ }
119
+ /** The environments on this account, and their secrets. */
120
+ export class Environments extends Collection {
121
+ secrets;
122
+ constructor(http, resolver) {
123
+ super(http, resolver, "/api/environments", "environment");
124
+ this.secrets = new Secrets(http, resolver, this.path, this.what);
125
+ }
126
+ }
127
+ /**
128
+ * The provider accounts this tenant has signed in to, whose credentials
129
+ * Fountain holds (#1178). Connecting one is a browser round trip — send the
130
+ * account owner to `connect_url` from `providers()` — so there is no `create`
131
+ * here. An agent uses one by naming it in `mcp_servers`:
132
+ * `{ gmail: { connection: "<id>" } }`. Only for accounts the egress broker is
133
+ * on for; elsewhere every call is a `NotFoundError` (`connections_not_enabled`).
134
+ */
135
+ export class Connections {
136
+ http;
137
+ /** Where connections get their tokens: Google, plus the tenant's own providers (#1186). */
138
+ providers;
139
+ constructor(http) {
140
+ this.http = http;
141
+ this.providers = new ConnectionProviders(http);
142
+ }
143
+ /** Every connection on the account, active or revoked. Never a token. */
144
+ async list() {
145
+ return this.http.list("/api/connections");
146
+ }
147
+ /** One connection by id. Unenveloped, as the server answers `show`. */
148
+ async get(id) {
149
+ return this.http.request("GET", `/api/connections/${encodeURIComponent(id)}`);
150
+ }
151
+ /** Revoke at the provider and delete. Agents that name it get `connection revoked`. */
152
+ async delete(id) {
153
+ await this.http.request("DELETE", `/api/connections/${encodeURIComponent(id)}`);
154
+ }
155
+ }
156
+ /**
157
+ * Connection providers (#1186): the platform provider (Google, id `google`),
158
+ * the tenant's own OAuth apps (`kind: "oauth2"`) and the remote MCP servers
159
+ * whose authorization Fountain discovered (`kind: "mcp"`). The client secret
160
+ * is write-only. Only for accounts the egress broker is on for.
161
+ */
162
+ export class ConnectionProviders {
163
+ http;
164
+ constructor(http) {
165
+ this.http = http;
166
+ }
167
+ /** Google first, then the tenant's own. */
168
+ async list() {
169
+ return this.http.list("/api/connection-providers");
170
+ }
171
+ /** One provider; `"google"` is the platform provider. */
172
+ async get(id) {
173
+ return this.http.request("GET", `/api/connection-providers/${encodeURIComponent(id)}`);
174
+ }
175
+ /**
176
+ * Define a provider. `kind: "oauth2"` takes the tenant's app registration;
177
+ * `kind: "mcp"` takes `mcp_url` and Fountain discovers the authorization
178
+ * server and registers a client where it can.
179
+ */
180
+ async create(input) {
181
+ return this.http.request("POST", "/api/connection-providers", { body: input });
182
+ }
183
+ /** Edit a tenant provider. A blank `client_secret` keeps the stored one. */
184
+ async update(id, patch) {
185
+ return this.http.request("PATCH", `/api/connection-providers/${encodeURIComponent(id)}`, {
186
+ body: patch,
187
+ });
188
+ }
189
+ /** Delete a tenant provider and every connection on it. */
190
+ async delete(id) {
191
+ await this.http.request("DELETE", `/api/connection-providers/${encodeURIComponent(id)}`);
192
+ }
193
+ /** Run MCP discovery again on an `mcp` provider. */
194
+ async discover(id) {
195
+ return this.http.request("POST", `/api/connection-providers/${encodeURIComponent(id)}/discover`);
196
+ }
197
+ }
198
+ /** The vaults on this account, and their secrets. */
199
+ export class Vaults extends Collection {
200
+ secrets;
201
+ constructor(http, resolver) {
202
+ super(http, resolver, "/api/vaults", "vault");
203
+ this.secrets = new VaultSecrets(http, resolver, this.path, this.what);
204
+ }
205
+ }
206
+ //# sourceMappingURL=resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"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"}
package/dist/run.d.ts ADDED
@@ -0,0 +1,81 @@
1
+ import type { HttpClient } from "./http.ts";
2
+ import type { ConversationRecord as Conversation, RunEvent, RunResult } from "./types.ts";
3
+ export interface RunPlan {
4
+ /** Open the conversation (a fresh `run`), or reuse one (`send`). */
5
+ start(): Promise<{
6
+ conversation: Conversation;
7
+ turnNumber: number;
8
+ after: number;
9
+ }>;
10
+ }
11
+ export interface RunOptions {
12
+ /** Stop waiting after this many ms and throw `TimeoutError`. `0` (default) waits. */
13
+ timeoutMs?: number;
14
+ /** Abort the run's own waiting. The turn keeps going in the sandbox. */
15
+ signal?: AbortSignal;
16
+ /** Keep every log event on the result. Off by default — a long turn is a lot of rows. */
17
+ collectEvents?: boolean;
18
+ }
19
+ /**
20
+ * A turn in flight.
21
+ *
22
+ * The work starts as soon as you call `run()`; what you do with this object
23
+ * decides how much of it you see. `await` it for the answer, iterate it for
24
+ * events as they land, or read `.textStream` for just the words. All three
25
+ * read the same underlying run — there is no second request behind them.
26
+ */
27
+ export declare class Run implements Promise<RunResult>, AsyncIterable<RunEvent> {
28
+ readonly [Symbol.toStringTag]: string;
29
+ /** The conversation this turn runs in. Resolves as soon as it exists. */
30
+ readonly conversationId: Promise<string>;
31
+ /** Where a human watches it. Resolves with `conversationId`. */
32
+ readonly url: Promise<string>;
33
+ /** The full conversation record, once opened. */
34
+ readonly conversation: Promise<Conversation>;
35
+ private readonly http;
36
+ private readonly events;
37
+ private readonly completion;
38
+ private readonly opened;
39
+ private readonly abort;
40
+ private lastEventId;
41
+ private conversationIdValue;
42
+ constructor(http: HttpClient, plan: RunPlan, options?: RunOptions);
43
+ then<A = RunResult, B = never>(onfulfilled?: ((value: RunResult) => A | PromiseLike<A>) | null, onrejected?: ((reason: unknown) => B | PromiseLike<B>) | null): Promise<A | B>;
44
+ catch<B = never>(onrejected?: ((reason: unknown) => B | PromiseLike<B>) | null): Promise<RunResult | B>;
45
+ finally(onfinally?: (() => void) | null): Promise<RunResult>;
46
+ [Symbol.asyncIterator](): AsyncIterator<RunEvent>;
47
+ /** Just the words, as they arrive. */
48
+ get textStream(): AsyncIterable<string>;
49
+ /** Stop waiting. The turn keeps running in the sandbox; `interrupt()` stops that. */
50
+ cancel(): void;
51
+ /**
52
+ * Answer a permission request this turn is blocked on — the `requestId` and
53
+ * the `optionId` both come off a `{ type: "permission" }` event.
54
+ *
55
+ * ```ts
56
+ * for await (const event of run) {
57
+ * if (event.type === "permission") {
58
+ * const allow = event.request.options.find((o) => o.kind === "allow_once");
59
+ * if (allow) await run.answer(event.request.requestId, allow.optionId);
60
+ * }
61
+ * }
62
+ * ```
63
+ *
64
+ * Only an agent with an `ask` entry in its `permission_policy` produces
65
+ * these. Leave them unanswered and the server denies each one when it
66
+ * expires, so the turn finishes having skipped the work.
67
+ */
68
+ answer(requestId: string, optionId: string): Promise<void>;
69
+ /** Ask the agent to stop the turn it is on. The sandbox stays up. */
70
+ interrupt(): Promise<void>;
71
+ /** Tear the sandbox down. Nothing resumes after this. */
72
+ terminate(): Promise<void>;
73
+ /** The cursor to resume the log feed from — how a follow-up turn skips history. */
74
+ get cursor(): number;
75
+ private execute;
76
+ private follow;
77
+ /** The status as of the end of the wait, not as of the last event. */
78
+ private currentStatus;
79
+ /** The id, once known — for internal callers that already awaited the open. */
80
+ get id(): string | null;
81
+ }
package/dist/run.js ADDED
@@ -0,0 +1,247 @@
1
+ import { TurnFollower } from "./turn.js";
2
+ import { streamEvents } from "./sse.js";
3
+ import { Broadcast, deferred } from "./queue.js";
4
+ import { conversationUrl } from "./config.js";
5
+ import { TimeoutError } from "./errors.js";
6
+ const TERMINAL_CONVERSATION_STATUSES = new Set(["failed", "terminated"]);
7
+ /**
8
+ * A turn in flight.
9
+ *
10
+ * The work starts as soon as you call `run()`; what you do with this object
11
+ * decides how much of it you see. `await` it for the answer, iterate it for
12
+ * events as they land, or read `.textStream` for just the words. All three
13
+ * read the same underlying run — there is no second request behind them.
14
+ */
15
+ export class Run {
16
+ [Symbol.toStringTag] = "Run";
17
+ /** The conversation this turn runs in. Resolves as soon as it exists. */
18
+ conversationId;
19
+ /** Where a human watches it. Resolves with `conversationId`. */
20
+ url;
21
+ /** The full conversation record, once opened. */
22
+ conversation;
23
+ http;
24
+ events = new Broadcast();
25
+ completion;
26
+ opened = deferred();
27
+ abort = new AbortController();
28
+ lastEventId = 0;
29
+ conversationIdValue = null;
30
+ constructor(http, plan, options = {}) {
31
+ this.http = http;
32
+ this.conversation = this.opened.promise;
33
+ this.conversationId = hushed(this.conversation.then((c) => c.id));
34
+ this.url = hushed(this.conversation.then((c) => conversationUrl(c.id, http.config)));
35
+ this.completion = this.execute(plan, options);
36
+ // A caller may only ever iterate, or only ever read `conversationId`. None
37
+ // of these derived promises may crash the process for want of a handler —
38
+ // the failure still arrives on whichever one is actually awaited.
39
+ hushed(this.completion);
40
+ }
41
+ then(onfulfilled, onrejected) {
42
+ return this.completion.then(onfulfilled, onrejected);
43
+ }
44
+ catch(onrejected) {
45
+ return this.completion.catch(onrejected);
46
+ }
47
+ finally(onfinally) {
48
+ return this.completion.finally(onfinally);
49
+ }
50
+ [Symbol.asyncIterator]() {
51
+ return this.events[Symbol.asyncIterator]();
52
+ }
53
+ /** Just the words, as they arrive. */
54
+ get textStream() {
55
+ const events = this.events;
56
+ return {
57
+ async *[Symbol.asyncIterator]() {
58
+ for await (const event of events) {
59
+ if (event.type === "text")
60
+ yield event.text;
61
+ }
62
+ },
63
+ };
64
+ }
65
+ /** Stop waiting. The turn keeps running in the sandbox; `interrupt()` stops that. */
66
+ cancel() {
67
+ this.abort.abort();
68
+ }
69
+ /**
70
+ * Answer a permission request this turn is blocked on — the `requestId` and
71
+ * the `optionId` both come off a `{ type: "permission" }` event.
72
+ *
73
+ * ```ts
74
+ * for await (const event of run) {
75
+ * if (event.type === "permission") {
76
+ * const allow = event.request.options.find((o) => o.kind === "allow_once");
77
+ * if (allow) await run.answer(event.request.requestId, allow.optionId);
78
+ * }
79
+ * }
80
+ * ```
81
+ *
82
+ * Only an agent with an `ask` entry in its `permission_policy` produces
83
+ * these. Leave them unanswered and the server denies each one when it
84
+ * expires, so the turn finishes having skipped the work.
85
+ */
86
+ async answer(requestId, optionId) {
87
+ const id = await this.conversationId;
88
+ await this.http.request("POST", `/api/conversations/${id}/requests/${encodeURIComponent(requestId)}`, { body: { option_id: optionId } });
89
+ }
90
+ /** Ask the agent to stop the turn it is on. The sandbox stays up. */
91
+ async interrupt() {
92
+ const id = await this.conversationId;
93
+ await this.http.request("POST", `/api/conversations/${id}/interrupt`);
94
+ }
95
+ /** Tear the sandbox down. Nothing resumes after this. */
96
+ async terminate() {
97
+ const id = await this.conversationId;
98
+ await this.http.request("POST", `/api/conversations/${id}/terminate`);
99
+ }
100
+ /** The cursor to resume the log feed from — how a follow-up turn skips history. */
101
+ get cursor() {
102
+ return this.lastEventId;
103
+ }
104
+ async execute(plan, options) {
105
+ try {
106
+ const { conversation, turnNumber, after } = await plan.start();
107
+ this.conversationIdValue = conversation.id;
108
+ this.lastEventId = after;
109
+ this.opened.resolve(conversation);
110
+ const url = conversationUrl(conversation.id, this.http.config);
111
+ this.events.push({ type: "conversation", conversationId: conversation.id, conversation, url });
112
+ const result = await this.follow(conversation, turnNumber, after, options, url);
113
+ this.events.close();
114
+ return result;
115
+ }
116
+ catch (error) {
117
+ this.opened.reject(error);
118
+ this.events.close(error);
119
+ throw error;
120
+ }
121
+ }
122
+ async follow(conversation, turnNumber, after, options, url) {
123
+ const follower = new TurnFollower(turnNumber);
124
+ const collected = [];
125
+ const signal = options.signal
126
+ ? AbortSignal.any([options.signal, this.abort.signal])
127
+ : this.abort.signal;
128
+ let failure = null;
129
+ let timedOut = false;
130
+ const timeoutMs = options.timeoutMs ?? 0;
131
+ const timer = timeoutMs > 0
132
+ ? setTimeout(() => {
133
+ timedOut = true;
134
+ this.abort.abort();
135
+ }, timeoutMs)
136
+ : null;
137
+ timer?.unref?.();
138
+ try {
139
+ for await (const event of streamEvents(this.http, conversation.id, { after, signal })) {
140
+ if (typeof event.id === "number" && event.id > this.lastEventId)
141
+ this.lastEventId = event.id;
142
+ if (options.collectEvents)
143
+ collected.push(event);
144
+ this.events.push({ type: "event", event });
145
+ for (const out of follower.apply(event))
146
+ this.events.push(out);
147
+ if (follower.finished)
148
+ break;
149
+ // A stage that can mean the conversation is over. Which stages those
150
+ // are is not a list worth hard-coding — `provision/failed` stops the
151
+ // server, `setup/failed` may not, and `sandbox/done` is a suspend
152
+ // (resumable) or a reclaim (not) depending on a field. So ask the
153
+ // conversation instead of guessing: if it is terminal, no turn event
154
+ // is ever coming and waiting for one hangs forever.
155
+ if (mayEndConversation(event)) {
156
+ const status = await this.currentStatus(conversation);
157
+ if (status && TERMINAL_CONVERSATION_STATUSES.has(status)) {
158
+ failure = { reason: stageReason(event) };
159
+ break;
160
+ }
161
+ }
162
+ }
163
+ }
164
+ finally {
165
+ if (timer)
166
+ clearTimeout(timer);
167
+ }
168
+ if (timedOut) {
169
+ throw new TimeoutError(`Timed out after ${timeoutMs}ms waiting for turn ${turnNumber}. ` +
170
+ `The turn is still running — resume conversation ${conversation.id}.`, conversation.id, follower.text);
171
+ }
172
+ const status = await this.currentStatus(conversation);
173
+ if (!follower.finished) {
174
+ // The conversation died under the turn, or the caller stopped waiting.
175
+ // Either way say so, rather than reporting an empty answer as normal.
176
+ const state = failure ? "failed" : "timeout";
177
+ this.events.push({ type: "turn-end", state, exitCode: null, reason: failure?.reason ?? null });
178
+ }
179
+ const result = {
180
+ conversationId: conversation.id,
181
+ url,
182
+ turnNumber,
183
+ text: follower.text,
184
+ toolsUsed: follower.toolsUsed,
185
+ state: follower.state ?? (failure ? "failed" : "timeout"),
186
+ exitCode: follower.exitCode,
187
+ reason: follower.reason ?? failure?.reason ?? null,
188
+ status,
189
+ };
190
+ if (options.collectEvents)
191
+ result.events = collected;
192
+ return result;
193
+ }
194
+ /** The status as of the end of the wait, not as of the last event. */
195
+ async currentStatus(conversation) {
196
+ try {
197
+ const fresh = await this.http.data("GET", `/api/conversations/${conversation.id}`);
198
+ return fresh?.status ?? conversation.status ?? null;
199
+ }
200
+ catch {
201
+ return conversation.status ?? null;
202
+ }
203
+ }
204
+ /** The id, once known — for internal callers that already awaited the open. */
205
+ get id() {
206
+ return this.conversationIdValue;
207
+ }
208
+ }
209
+ /**
210
+ * Stage events worth checking the conversation's status over.
211
+ *
212
+ * `state` is a closed vocabulary — started/done/failed/interrupted — so a
213
+ * destroyed sandbox and a parked one are both `sandbox`/`done`, told apart by
214
+ * a field in the payload. Rather than encode that, treat every one of these as
215
+ * "go and ask" and let the conversation's own status decide.
216
+ */
217
+ function mayEndConversation(event) {
218
+ if (event.kind !== "stage")
219
+ return false;
220
+ if (event.stage === "turn")
221
+ return false; // the follower owns the turn's own fate
222
+ return event.state === "failed" || event.stage === "terminate" || event.stage === "sandbox";
223
+ }
224
+ /** Why a stage said it ended, when it said. */
225
+ function stageReason(event) {
226
+ let meta = event.data;
227
+ if (typeof meta === "string") {
228
+ try {
229
+ meta = JSON.parse(meta);
230
+ }
231
+ catch {
232
+ return null;
233
+ }
234
+ }
235
+ if (!meta || typeof meta !== "object")
236
+ return null;
237
+ const record = meta;
238
+ const reason = record.message ?? record.reason;
239
+ const label = typeof reason === "string" && reason ? reason : null;
240
+ return label ? `${event.stage}/${event.state}: ${label}` : `${event.stage}/${event.state}`;
241
+ }
242
+ /** Mark a promise as handled without changing what it settles to. */
243
+ function hushed(promise) {
244
+ promise.catch(() => { });
245
+ return promise;
246
+ }
247
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * The API's own types, straight from its OpenAPI document.
3
+ *
4
+ * `src/generated/openapi.ts` is produced by `npm run generate` from the same
5
+ * spec the server serves at `GET /api/openapi.json`, and CI regenerates it and
6
+ * fails on a diff. So these are not a description of the API that someone has
7
+ * to remember to update — they are the API, and a field added to a schema in
8
+ * Elixir shows up here on the next build.
9
+ *
10
+ * The hand-written layer above this one exists for the things a spec cannot
11
+ * express: what a *turn* is (many log events folded into one answer), that a
12
+ * run can be awaited or streamed, and which of 85 paths are worth a verb.
13
+ */
14
+ import type { components } from "./generated/openapi.ts";
15
+ type S = components["schemas"];
16
+ /** `T` with `K` made optional — for fields the API defaults and the generator does not. */
17
+ type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
18
+ /** A named, re-runnable agent config — runtime, model, skills, environment. */
19
+ export type Agent = S["Agent"];
20
+ /** Everything that decides how a run behaves, before the prompt. */
21
+ export type AgentInput = S["AgentRequest"];
22
+ /** A partial agent definition, for `update`. */
23
+ export type AgentPatch = S["AgentUpdate"];
24
+ /** The sandbox shape an agent runs in: packages, repos, env vars, networking. */
25
+ export type Environment = S["Environment"];
26
+ export type EnvironmentInput = S["EnvironmentRequest"];
27
+ export type EnvironmentPatch = S["EnvironmentUpdate"];
28
+ /** A free-floating bag of env-var overrides, chosen per conversation. */
29
+ export type Vault = S["Vault"];
30
+ export type VaultInput = S["VaultRequest"];
31
+ export type VaultPatch = S["VaultUpdate"];
32
+ /** One run of an agent inside a sandbox. */
33
+ export type ConversationRecord = S["Conversation"];
34
+ /** A machine, with the conversations on it. */
35
+ export type SandboxRecord = S["SandboxDetail"];
36
+ /** One directory on a sandbox, directories first (ADR 0039). */
37
+ export type SandboxListing = S["SandboxListing"];
38
+ /** One entry of a `SandboxListing`. */
39
+ export type SandboxEntry = S["SandboxEntry"];
40
+ /** One file on a sandbox, redacted; `content` is text or base64 per `encoding`. */
41
+ export type SandboxFile = S["SandboxFile"];
42
+ /** `git diff` of a repository on a sandbox, redacted. */
43
+ export type SandboxDiff = S["SandboxDiff"];
44
+ /** One prompt and everything the agent did in response. */
45
+ export type Turn = S["Turn"];
46
+ /** One row of a conversation's log feed. */
47
+ export type LogEvent = S["LogEvent"];
48
+ /** A server-parsed piece of an agent's output (`?blocks=true`). */
49
+ export type Block = S["Block"];
50
+ /** A stored secret. Values are write-only — the API never returns them. */
51
+ export type Secret = S["Secret"];
52
+ export type VaultSecret = S["VaultSecret"];
53
+ export type VaultSecretMetadataPatch = S["VaultSecretMetadataRequest"];
54
+ /** An agent that has been put on the team, with its standing conversation. */
55
+ export type Teammate = S["Teammate"];
56
+ export type TeamAddInput = S["TeamAddRequest"];
57
+ /** A cron that runs a teammate with a prompt. */
58
+ export type Schedule = S["TeamSchedule"];
59
+ /**
60
+ * Creating one. `enabled` and `one_off` are optional on the wire — the server
61
+ * defaults them to `true` and `false` — but the generator marks a property
62
+ * that carries a default as required, so they are relaxed back here.
63
+ */
64
+ export type ScheduleInput = Optional<S["TeamScheduleCreateRequest"], "enabled" | "one_off">;
65
+ export type SchedulePatch = S["TeamScheduleUpdateRequest"];
66
+ export type TeamCommsStatus = S["TeamCommsStatus"];
67
+ export type TeammateContact = S["TeammateContact"];
68
+ /** The form vocabulary: runtimes, models, providers a client can offer. */
69
+ export type Catalog = S["CatalogResponse"]["data"];
70
+ /** One hit from full-text search across the caller's conversations. */
71
+ export type SearchHit = S["SearchHit"];
72
+ /** A node in a conversation's spawn tree. */
73
+ export type ConversationTreeNode = S["ConversationTreeNode"];
74
+ export type Runner = S["Runner"];
75
+ /** A provider account the tenant signed in to once; Fountain holds the credential (#1178). */
76
+ export type Connection = S["Connection"];
77
+ /**
78
+ * Where a connection's tokens come from (#1186): the platform provider
79
+ * (Google, id `google`), the tenant's own OAuth app at a service (`oauth2`),
80
+ * or a remote MCP server whose authorization Fountain discovered (`mcp`).
81
+ */
82
+ export type ConnectionProvider = S["ConnectionProvider"];
83
+ /** Defining one. `kind: "mcp"` needs only `mcp_url`; the rest comes from discovery. */
84
+ export type ConnectionProviderInput = S["ConnectionProviderRequest"];
85
+ export type ConnectionProviderPatch = Partial<ConnectionProviderInput>;
86
+ export type Repository = S["Repository"];
87
+ export type ImageInput = S["ImageInput"];
88
+ export type AuthMe = S["AuthMeResponse"];
89
+ /** Every path and operation, for callers reaching past the wrapped verbs. */
90
+ export type { paths, components, operations } from "./generated/openapi.ts";
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":""}