@managoat/fountain-sdk 6.1.0 → 6.3.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.
@@ -63,6 +63,118 @@ export interface paths {
63
63
  patch?: never;
64
64
  trace?: never;
65
65
  };
66
+ "/api/account/chatgpt-subscriptions": {
67
+ parameters: {
68
+ query?: never;
69
+ header?: never;
70
+ path?: never;
71
+ cookie?: never;
72
+ };
73
+ /**
74
+ * List ChatGPT subscriptions
75
+ * @description Every subscription the account holds, by name, with how many it may hold and whether it may link another now. Tokens are never returned.
76
+ */
77
+ get: operations["FountainWeb.ChatGPTSubscriptionController.index"];
78
+ put?: never;
79
+ post?: never;
80
+ delete?: never;
81
+ options?: never;
82
+ head?: never;
83
+ patch?: never;
84
+ trace?: never;
85
+ };
86
+ "/api/account/chatgpt-subscriptions/attempts": {
87
+ parameters: {
88
+ query?: never;
89
+ header?: never;
90
+ path?: never;
91
+ cookie?: never;
92
+ };
93
+ /**
94
+ * List open ChatGPT sign-ins
95
+ * @description The account's pending attempts, oldest first, each with its code: what a client that lost its state reads to pick up where it was.
96
+ */
97
+ get: operations["FountainWeb.ChatGPTSubscriptionController.index_attempts"];
98
+ put?: never;
99
+ /**
100
+ * Start a ChatGPT sign-in
101
+ * @description `name` links a new subscription; `grant_id` reconnects one, which keeps the old credential serving until the new sign-in commits. The answer carries the code to type and the page to type it on. It expires in fifteen minutes. Limited to ten an hour and three open at once, per account.
102
+ */
103
+ post: operations["FountainWeb.ChatGPTSubscriptionController.create_attempt"];
104
+ delete?: never;
105
+ options?: never;
106
+ head?: never;
107
+ patch?: never;
108
+ trace?: never;
109
+ };
110
+ "/api/account/chatgpt-subscriptions/attempts/{id}": {
111
+ parameters: {
112
+ query?: never;
113
+ header?: never;
114
+ path?: never;
115
+ cookie?: never;
116
+ };
117
+ /**
118
+ * Read a ChatGPT sign-in
119
+ * @description The endpoint to poll. It reads a row and contacts nobody. An attempt that ran out of time reads `expired`.
120
+ */
121
+ get: operations["FountainWeb.ChatGPTSubscriptionController.show_attempt"];
122
+ put?: never;
123
+ post?: never;
124
+ /**
125
+ * Cancel a ChatGPT sign-in
126
+ * @description Ends a pending attempt; a sign-in approved afterwards stores nothing. Already cancelled is a 200. An attempt that has completed, failed or expired is a 409 `chatgpt_link_attempt_not_pending` carrying its `state`.
127
+ */
128
+ delete: operations["FountainWeb.ChatGPTSubscriptionController.cancel_attempt"];
129
+ options?: never;
130
+ head?: never;
131
+ patch?: never;
132
+ trace?: never;
133
+ };
134
+ "/api/account/chatgpt-subscriptions/{id}": {
135
+ parameters: {
136
+ query?: never;
137
+ header?: never;
138
+ path?: never;
139
+ cookie?: never;
140
+ };
141
+ get?: never;
142
+ put?: never;
143
+ post?: never;
144
+ /**
145
+ * Remove a disconnected ChatGPT subscription
146
+ * @description Deletes the row, which frees its place under the limit. Refused with 409 `chatgpt_grant_still_connected` until it is disconnected, and with 409 `chatgpt_grant_named_by_sets` while credential sets name it.
147
+ */
148
+ delete: operations["FountainWeb.ChatGPTSubscriptionController.delete"];
149
+ options?: never;
150
+ head?: never;
151
+ /**
152
+ * Rename a ChatGPT subscription
153
+ * @description A name is a label. Renaming changes no credential, and conversations running on the subscription are not disturbed.
154
+ */
155
+ patch: operations["FountainWeb.ChatGPTSubscriptionController.update"];
156
+ trace?: never;
157
+ };
158
+ "/api/account/chatgpt-subscriptions/{id}/disconnect": {
159
+ parameters: {
160
+ query?: never;
161
+ header?: never;
162
+ path?: never;
163
+ cookie?: never;
164
+ };
165
+ get?: never;
166
+ put?: never;
167
+ /**
168
+ * Disconnect a ChatGPT subscription
169
+ * @description Forgets the subscription's tokens and keeps its row. From the moment this returns no sandbox request may use it, inside a connection that was already open too. A credential set that names it keeps naming it, and its codex runs fail by name until the subscription is reconnected or the set is pointed elsewhere; nothing is substituted. Already disconnected is a 200. The token is not revoked at ChatGPT.
170
+ */
171
+ post: operations["FountainWeb.ChatGPTSubscriptionController.disconnect"];
172
+ delete?: never;
173
+ options?: never;
174
+ head?: never;
175
+ patch?: never;
176
+ trace?: never;
177
+ };
66
178
  "/api/account/exports": {
67
179
  parameters: {
68
180
  query?: never;
@@ -166,8 +278,8 @@ export interface paths {
166
278
  options?: never;
167
279
  head?: never;
168
280
  /**
169
- * Rename an inference credential set, or make it the default
170
- * @description Omitting a field leaves it alone. `is_default: false` is refused: a set stops being the default when another becomes it, never on its own, because an account with no default has nothing to read a credential from.
281
+ * Rename an inference credential set, make it the default, or name a ChatGPT subscription
282
+ * @description Omitting a field leaves it alone. `is_default: false` is refused: a set stops being the default when another becomes it, never on its own, because an account with no default has nothing to read a credential from. `chatgpt_grant_id` names one of the account's ChatGPT subscriptions for the set's codex runs, and `null` stops naming one. Naming one ends the set's running codex conversations with `inference_source_changed`: their source is now the subscription. An id that is not one of the account's subscriptions, and a disconnected one, are 422; sending the id the set already names changes nothing.
171
283
  */
172
284
  patch: operations["FountainWeb.InferenceCredentialSetController.update"];
173
285
  trace?: never;
@@ -827,7 +939,7 @@ export interface paths {
827
939
  put?: never;
828
940
  /**
829
941
  * Register an account
830
- * @description Creates the account and sends the verification email. The account cannot mint an API key until it is verified, so a headless bootstrap is register → `POST /api/auth/verify` with the emailed token → `POST /api/auth/token`. Rate-limited to 5 per IP per hour. On an instance with open registration disabled this answers 403 with a reason code.
942
+ * @description Creates the account and sends the verification email. The account cannot mint an API key until it is verified, so a headless bootstrap is register → `POST /api/auth/verify` with the emailed token → `POST /api/auth/token`. Rate-limited to 5 per IP per hour. On an instance with open registration disabled this answers 403 with a reason code; an instance that asks for an access code answers 403 `access_code_required` until `access_code` carries it.
831
943
  */
832
944
  post: operations["FountainWeb.RegistrationController.api_create"];
833
945
  delete?: never;
@@ -1241,7 +1353,7 @@ export interface paths {
1241
1353
  };
1242
1354
  /**
1243
1355
  * List a conversation's log events
1244
- * @description The read-model behind the SSE stream. Same rows, same fields, as JSON — fetching or archiving a conversation's output no longer requires an SSE parser. Oldest first, cursor-paginated: pass the previous page's `meta.next_cursor` as `after`. SSE remains the tail/follow mechanism.
1356
+ * @description The read-model behind the SSE stream. Same rows, same fields, as JSON — fetching or archiving a conversation's output no longer requires an SSE parser. Oldest first, cursor-paginated: pass the previous page's `meta.next_cursor` as `after`. SSE remains the tail/follow mechanism. With `order=desc` the page is the newest events instead, newest first, and `meta.next_cursor` is the page's oldest id, to pass as `before` for the page older than it; add `whole_turns=true` so no page ends inside a turn. `page.newest_cursor` of the first such page is where an SSE follow resumes (`Last-Event-ID`).
1245
1357
  */
1246
1358
  get: operations["FountainWeb.ConversationController.events"];
1247
1359
  put?: never;
@@ -1348,10 +1460,12 @@ export interface paths {
1348
1460
  get?: never;
1349
1461
  put?: never;
1350
1462
  /**
1351
- * Reapply a conversation's Agent, Environment and Vault
1352
- * @description Applies a selection to the machine this conversation already runs on, so its files stay where the agent left them. Variables, the system prompt, skills and MCP configuration are rewritten, and the next prompt reads them. An omitted field keeps its current selection; null clears the Environment override or the Vault; an empty object reapplies what is already selected.
1463
+ * Reapply a conversation's Agent, Environment, Vault and model
1464
+ * @description Applies a selection to the machine this conversation already runs on, so its files stay where the agent left them. Variables, the system prompt, skills and MCP configuration are rewritten, and the next prompt reads them. An omitted field keeps its current selection; null clears the Environment override, the Vault or the model override; an empty object reapplies what is already selected.
1465
+ *
1466
+ * `model` changes the model this conversation runs from its next turn (ADR 0061), continuing the same runtime session. It is refused with 422 `model_invalid` when the runtime cannot run it, and with 409 `inference_source_changed` when the conversation's credential does not serve it.
1353
1467
  *
1354
- * Refused with 409 `conversation_busy` while a turn runs, 409 `rebuild_required` when the selection would need the machine built again (the `field` says which one forced it), 503 while the machine is still being built, and 410 once the conversation has ended.
1468
+ * Refused with 409 `conversation_busy` while a turn runs, 409 `rebuild_required` when the selection would need the machine built again (the `field` says which one forced it; for a conversation attached to another agent's sandbox with `sandbox_id`, `shared_sandbox` while another conversation is on it and `guest` once it is alone), 503 while the machine is still being built, and 410 once the conversation has ended.
1355
1469
  */
1356
1470
  post: operations["FountainWeb.ConversationController.reapply"];
1357
1471
  delete?: never;
@@ -1891,7 +2005,7 @@ export interface paths {
1891
2005
  };
1892
2006
  /**
1893
2007
  * List a directory on a sandbox
1894
- * @description The entries of one directory, directories first then by name. Without `path`, the agent's working directory. Only a `ready` sandbox answers (`409 sandbox_not_ready`): a parked one is not woken for a read. Full scope.
2008
+ * @description The entries of one directory, directories first then by name. Without `path`, the agent's working directory. Only a `ready` sandbox answers (`409 sandbox_not_ready`): a parked one is not woken for a read. A sandbox being parked or destroyed is `503 sandbox_unavailable`; retry after the `Retry-After`. Full scope.
1895
2009
  */
1896
2010
  get: operations["FountainWeb.SandboxFilesController.index"];
1897
2011
  put?: never;
@@ -2284,6 +2398,26 @@ export interface paths {
2284
2398
  patch: operations["FountainWeb.VaultController.update (2)"];
2285
2399
  trace?: never;
2286
2400
  };
2401
+ "/api/vaults/{id}/copy": {
2402
+ parameters: {
2403
+ query?: never;
2404
+ header?: never;
2405
+ path?: never;
2406
+ cookie?: never;
2407
+ };
2408
+ get?: never;
2409
+ put?: never;
2410
+ /**
2411
+ * Copy a vault
2412
+ * @description Creates a new vault holding a copy of every secret in the source vault. Values are copied server-side and re-encrypted; no value is ever returned. `name` is required; `description` and `metadata` default to the source's. Atomic: on any failure no new vault exists. A source vault the caller does not own reads as not found.
2413
+ */
2414
+ post: operations["FountainWeb.VaultController.copy"];
2415
+ delete?: never;
2416
+ options?: never;
2417
+ head?: never;
2418
+ patch?: never;
2419
+ trace?: never;
2420
+ };
2287
2421
  "/api/vaults/{vault_id}/secrets": {
2288
2422
  parameters: {
2289
2423
  query?: never;
@@ -2705,6 +2839,8 @@ export interface components {
2705
2839
  * @enum {string|null}
2706
2840
  */
2707
2841
  sandbox_provider?: "sprites" | "e2b" | "daytona" | "runner" | null;
2842
+ /** @description ACP session config options every conversation of this agent requests (ADR 0062), such as {"effort": "high"}. A conversation's own session_config overrides these keys, and a prompt's overrides both for that turn. Null or {} requests none. */
2843
+ session_config?: components["schemas"]["SessionConfig"];
2708
2844
  /** @description Each entry is either inline (`{name, content}` — full SKILL.md text written to the sprite) or github (`{source, ref?, name?}` — installed on the sprite via the skills.sh CLI, optionally pinned to a tag/branch/sha via `ref`). Exactly one of `content` or `source` must be set on each entry. */
2709
2845
  skills?: {
2710
2846
  /** @description Full SKILL.md body for inline entries. */
@@ -2765,6 +2901,8 @@ export interface components {
2765
2901
  * @enum {string|null}
2766
2902
  */
2767
2903
  sandbox_provider?: "sprites" | "e2b" | "daytona" | "runner" | null;
2904
+ /** @description ACP session config options every conversation of this agent requests (ADR 0062), such as {"effort": "high"}. A conversation's own session_config overrides these keys, and a prompt's overrides both for that turn. Null or {} requests none. */
2905
+ session_config?: components["schemas"]["SessionConfig"];
2768
2906
  /** @description Each entry is either inline (`{name, content}` — full SKILL.md text written to the sprite) or github (`{source, ref?, name?}` — installed on the sprite via the skills.sh CLI, optionally pinned to a tag/branch/sha via `ref`). Exactly one of `content` or `source` must be set on each entry. */
2769
2907
  skills?: {
2770
2908
  /** @description Full SKILL.md body for inline entries. */
@@ -2822,6 +2960,8 @@ export interface components {
2822
2960
  * @enum {string|null}
2823
2961
  */
2824
2962
  sandbox_provider?: "sprites" | "e2b" | "daytona" | "runner" | null;
2963
+ /** @description ACP session config options every conversation of this agent requests (ADR 0062), such as {"effort": "high"}. A conversation's own session_config overrides these keys, and a prompt's overrides both for that turn. Null or {} requests none. */
2964
+ session_config?: components["schemas"]["SessionConfig"];
2825
2965
  /** @description Each entry is either inline (`{name, content}` — full SKILL.md text written to the sprite) or github (`{source, ref?, name?}` — installed on the sprite via the skills.sh CLI, optionally pinned to a tag/branch/sha via `ref`). Exactly one of `content` or `source` must be set on each entry. */
2826
2966
  skills?: {
2827
2967
  /** @description Full SKILL.md body for inline entries. */
@@ -2979,6 +3119,8 @@ export interface components {
2979
3119
  AuthMeResponse: {
2980
3120
  /** @description Whether this account's conversations run behind the egress credential broker (ADR 0019): secrets with bindings stay at the broker, a limited environment is enforced there, and /api/conversations/:id/egress has content. Connections availability is separate. Read-only; an operator sets it. */
2981
3121
  brokered?: boolean;
3122
+ /** @description Whether this account may link a new ChatGPT subscription. Listing, renaming, reconnecting, disconnecting and removing the ones it holds never depend on it. */
3123
+ chatgpt_subscriptions_enabled?: boolean;
2982
3124
  /** @description Null when billing is off. */
2983
3125
  comped?: boolean | null;
2984
3126
  /** @description Whether this account may add connections, providers, or credential bindings. Use connections_manageable to show existing credentials and their removal controls. */
@@ -3072,7 +3214,7 @@ export interface components {
3072
3214
  };
3073
3215
  /**
3074
3216
  * Block
3075
- * @description One structured piece of a log event's output — the same parse the web UI renders (`Fountain.Conversations.Blocks`). `kind` decides the other fields: `text`/`thinking` carry `body`; `plan` carries the full ordered checklist in `body` (entries with `content`, `status`, and optional `priority`, `id`, `activeForm`); `tool_use` carries `id`, `name`, `summary`, `body` (the input); `tool_result` carries `tool_id`, `body`, `error` and pairs with the `tool_use` of the same id; `init` carries `summary`, `body`; `result` carries `body`, `raw`; `error` carries `body`; `raw` carries `body`, `summary`; `permission_request` carries `request_id`, `name`, `summary` and `options` — the agent is blocked on it, and a client answers with POST /api/conversations/{id}/requests/{request_id}. Render only the options in `options`; never synthesise one the agent did not offer.
3217
+ * @description One structured piece of a log event's output — the same parse the web UI renders (`Fountain.Conversations.Blocks`). `kind` decides the other fields: `text`/`thinking` carry `body`; `plan` carries the full ordered checklist in `body` (entries with `content`, `status`, and optional `priority`, `id`, `activeForm`); `tool_use` carries `id`, `name`, `summary`, `body` (the input); `tool_result` carries `tool_id`, `body`, `error` and pairs with the `tool_use` of the same id; `init` carries `summary`, `body`; `result` carries `body`, `raw`; `error` carries `body`; `raw` carries `body`, `summary`; `permission_request` carries `request_id`, `name`, `summary` and `options` — the agent is blocked on it, and a client answers with POST /api/conversations/{id}/requests/{request_id}. Render only the options in `options`; never synthesise one the agent did not offer. `prompt` carries `body` — the prompt that opened the turn, which is the one kind not parsed out of a runtime's output. It appears only on a turn's `turn`/`started` stage event, and only when the events feed was asked for it with `blocks=true&prompts=true`.
3076
3218
  */
3077
3219
  Block: {
3078
3220
  body?: (string | null) | ({
@@ -3088,7 +3230,7 @@ export interface components {
3088
3230
  error?: boolean | null;
3089
3231
  id?: string | null;
3090
3232
  /** @enum {string} */
3091
- kind: "text" | "thinking" | "tool_use" | "tool_result" | "init" | "result" | "error" | "raw" | "permission_request" | "plan";
3233
+ kind: "text" | "thinking" | "tool_use" | "tool_result" | "init" | "result" | "error" | "raw" | "permission_request" | "plan" | "prompt";
3092
3234
  name?: string | null;
3093
3235
  /** @description permission_request only: the options the agent offered, in its order. Each carries at least `optionId` and `kind` (allow_once, allow_always, reject_once, reject_always, ...). */
3094
3236
  options?: {
@@ -3242,6 +3384,133 @@ export interface components {
3242
3384
  };
3243
3385
  };
3244
3386
  };
3387
+ /**
3388
+ * ChatGPTLinkAttempt
3389
+ * @description One device-code sign-in, for a new subscription or to reconnect one. Show `user_code` and `verification_url` to the person, then read the attempt again every `poll_interval` seconds until `state` leaves `pending`. The server does the polling of ChatGPT; reading this costs nothing upstream.
3390
+ */
3391
+ ChatGPTLinkAttempt: {
3392
+ /** @description True while a pending attempt's last poll of ChatGPT's sign-in service went unanswered. The attempt is still open and Fountain asks again, less often. */
3393
+ auth_unreachable: boolean;
3394
+ /** Format: date-time */
3395
+ expires_at: string;
3396
+ /** @description Why a `failed` attempt failed. Null otherwise. */
3397
+ failure: {
3398
+ grant: string | null;
3399
+ /** Format: uuid */
3400
+ grant_id: string | null;
3401
+ /**
3402
+ * @description `stale_grant`: the subscription was reconnected or disconnected after this attempt began, and what is there now was left alone. `account_already_linked`: the account holds this ChatGPT account already, as `grant`; reconnect that one instead. `linking_disabled`: linking was turned off for the account while this new link was open.
3403
+ * @enum {string}
3404
+ */
3405
+ reason: "stale_grant" | "account_already_linked" | "grant_limit_reached" | "grant_not_found" | "name_taken" | "owner_ineligible" | "linking_disabled" | "tenant_key_unavailable" | "invalid_sign_in" | "authorization_failed" | "exchange_failed" | "internal_error";
3406
+ } | null;
3407
+ /**
3408
+ * Format: uuid
3409
+ * @description The subscription being reconnected. Null for a new link.
3410
+ */
3411
+ grant_id: string | null;
3412
+ /** Format: uuid */
3413
+ id: string;
3414
+ /** Format: date-time */
3415
+ inserted_at: string;
3416
+ /** @enum {string} */
3417
+ kind: "link" | "reconnect";
3418
+ /** @description The name a new subscription will take. Null for a reconnect. */
3419
+ name: string | null;
3420
+ /** @description Seconds to wait between reads of this attempt. */
3421
+ poll_interval: number;
3422
+ /**
3423
+ * Format: uuid
3424
+ * @description The subscription a completed attempt linked or reconnected.
3425
+ */
3426
+ result_grant_id: string | null;
3427
+ /**
3428
+ * @description `pending`, then exactly one of the other four, which are final.
3429
+ * @enum {string}
3430
+ */
3431
+ state: "pending" | "completed" | "cancelled" | "expired" | "failed";
3432
+ /** Format: date-time */
3433
+ updated_at: string;
3434
+ /** @description The code to type at `verification_url`. Null once the attempt ends. */
3435
+ user_code: string | null;
3436
+ verification_url: string | null;
3437
+ };
3438
+ /**
3439
+ * ChatGPTLinkAttemptCreateRequest
3440
+ * @description Exactly one of the two: `name` links a new subscription under that name, `grant_id` reconnects the one it names.
3441
+ */
3442
+ ChatGPTLinkAttemptCreateRequest: {
3443
+ /** Format: uuid */
3444
+ grant_id?: string;
3445
+ name?: string;
3446
+ };
3447
+ /** ChatGPTLinkAttemptListResponse */
3448
+ ChatGPTLinkAttemptListResponse: {
3449
+ data: components["schemas"]["ChatGPTLinkAttempt"][];
3450
+ };
3451
+ /** ChatGPTLinkAttemptResponse */
3452
+ ChatGPTLinkAttemptResponse: {
3453
+ data: components["schemas"]["ChatGPTLinkAttempt"];
3454
+ };
3455
+ /**
3456
+ * ChatGPTSubscription
3457
+ * @description One ChatGPT subscription linked to the account, for the codex runtime. Fountain holds and renews its tokens; none is ever returned, and neither is the provider's account id. A credential set names one by `id`.
3458
+ */
3459
+ ChatGPTSubscription: {
3460
+ /** Format: date-time */
3461
+ access_expires_at: string | null;
3462
+ /** @description The ChatGPT account's email, shown to its owner and nobody else. */
3463
+ account_email: string | null;
3464
+ /**
3465
+ * Format: date-time
3466
+ * @description When the subscription's Codex usage resets, while that is in the future. Nothing records one for an account's subscription yet.
3467
+ */
3468
+ exhausted_until: string | null;
3469
+ /** Format: uuid */
3470
+ id: string;
3471
+ /** Format: date-time */
3472
+ inserted_at: string;
3473
+ /** Format: date-time */
3474
+ last_refreshed_at: string | null;
3475
+ /** @description Unique within the account. */
3476
+ name: string;
3477
+ plan_type: string | null;
3478
+ /** @description Whether a refresh token is stored. False once disconnected. */
3479
+ refreshable: boolean;
3480
+ /** @description The auth server's reason code when `status` is `revoked`. */
3481
+ revoked_reason: string | null;
3482
+ /**
3483
+ * @description `active` serves runs. `revoked`: the auth server refused the refresh token; reconnect it. `disconnected`: the account disconnected it; the row holds no token, still counts against the limit, and can be reconnected or removed. A set that names a subscription that is not `active` fails its codex runs by name; nothing is substituted.
3484
+ * @enum {string}
3485
+ */
3486
+ status: "active" | "revoked" | "expired" | "disconnected";
3487
+ /** Format: date-time */
3488
+ updated_at: string;
3489
+ };
3490
+ /**
3491
+ * ChatGPTSubscriptionListResponse
3492
+ * @description Every subscription the account holds, by name. Not paginated: it is capped.
3493
+ */
3494
+ ChatGPTSubscriptionListResponse: {
3495
+ /** @description How many the account holds. A disconnected one counts until removed. */
3496
+ count: number;
3497
+ data: components["schemas"]["ChatGPTSubscription"][];
3498
+ /** @description How many it may hold. */
3499
+ limit: number;
3500
+ /** @description Whether this account may link a new subscription now. False leaves every other operation here working. */
3501
+ linking_enabled: boolean;
3502
+ };
3503
+ /** ChatGPTSubscriptionResponse */
3504
+ ChatGPTSubscriptionResponse: {
3505
+ data: components["schemas"]["ChatGPTSubscription"];
3506
+ };
3507
+ /**
3508
+ * ChatGPTSubscriptionUpdateRequest
3509
+ * @description A new name. A name is a label: renaming changes no credential.
3510
+ */
3511
+ ChatGPTSubscriptionUpdateRequest: {
3512
+ name: string;
3513
+ };
3245
3514
  /**
3246
3515
  * ClaimableUser
3247
3516
  * @description A claimable principal (ADR 0044): the anonymous tenant an application opens for a visitor who has no Fountain account yet. `principal_id` is the tenant every resource it builds belongs to, and it never changes — claiming attaches an owner rather than moving anything.
@@ -3518,6 +3787,8 @@ export interface components {
3518
3787
  * @description Set by `POST /api/conversations/:id/read`. Null if never read.
3519
3788
  */
3520
3789
  last_read_at?: string | null;
3790
+ /** @description This conversation's model override (ADR 0061), set at launch or by reapply; null means it runs the agent's model. Each turn's model_selection records the model that turn actually asked for. */
3791
+ model?: string | null;
3521
3792
  /** Format: uuid */
3522
3793
  parent_conversation_id?: string | null;
3523
3794
  /** @description Permission requests that outlived a turn and are still waiting for an answer (#1635). Only GET /api/conversations/{id} can report one; every other response carrying this schema, including the list and the create response, sends an empty array rather than querying for it. */
@@ -3535,6 +3806,10 @@ export interface components {
3535
3806
  sandbox_api_access?: "owner" | "none";
3536
3807
  /** Format: uuid */
3537
3808
  sandbox_id?: string | null;
3809
+ /** @description This conversation's ACP session config options (ADR 0062), over its agent's: a key here replaces the agent's value for that key. Set at launch or by reapply. {} follows the agent. */
3810
+ session_config?: components["schemas"]["SessionConfig"];
3811
+ /** @description The config options the adapter advertised before the latest prompt, after the model and the requested options were applied: what the current model offers and what is in force. Null until a turn reports them. */
3812
+ session_config_options?: components["schemas"]["SessionConfigOption"][] | null;
3538
3813
  /** @enum {string} */
3539
3814
  source?: "ui" | "api" | "agent";
3540
3815
  /** @enum {string} */
@@ -3556,7 +3831,7 @@ export interface components {
3556
3831
  agent_id: string;
3557
3832
  /** @description Opaque key for the external channel this conversation is bound to (for example a Buzz channel id). When set, the latest live conversation for the same agent, vault and channel is resumed (200) instead of a new one being opened (201). */
3558
3833
  channel_id?: string | null;
3559
- /** @description Your own name for the first prompt. Ignored when the request carries no `prompt`, and when `channel_id` resumes a conversation: a resume does not deliver the prompt, so send the value with it on the prompts route. Fountain stores it on the turn the prompt opens and sends it on that turn's `started` stage event, beside the `turn_id`, so a client can bind its work item to the exact turn without inferring it from turn order. Use the event to find a candidate turn and the turn itself to confirm it: the event's copy has been through event redaction, and the turn's is what you sent. It is a correlation and not an idempotency key: a second prompt with the same value opens a second turn that carries it too. Make it unique within the conversation. */
3834
+ /** @description Your own name for the first prompt. Ignored when the request carries no `prompt`. An immediate `channel_id` resume does not deliver the prompt; send the value with it on the prompts route. If a queued start resumes a channel bound while it waited, the queue delivers the prompt and value. Fountain stores it on the turn the prompt opens and sends it on that turn's `started` stage event, beside the `turn_id`, so a client can bind its work item to the exact turn without inferring it from turn order. Use the event to find a candidate turn and the turn itself to confirm it: the event's copy has been through event redaction, and the turn's is what you sent. It is a correlation and not an idempotency key: a second prompt with the same value opens a second turn that carries it too. Make it unique within the conversation. */
3560
3835
  client_request_id?: string | null;
3561
3836
  /**
3562
3837
  * Format: uuid
@@ -3569,14 +3844,16 @@ export interface components {
3569
3844
  images?: components["schemas"]["ImageInput"][] | null;
3570
3845
  /**
3571
3846
  * Format: uuid
3572
- * @description Optional credential set to run on instead of the agent's; the conversation stays pinned to it across wakes. Must be owned by the caller (404 inference_credential_not_found otherwise) and satisfy the agent's allowed_inference_credential_ids when that allowlist is set (422 inference_credential_not_allowed). An unusable selected set is 422 inference_credential_unusable. The resolved source and revision stay bound across wakes; replacing or deleting the source returns 409 inference_source_changed. Not part of sandbox identity, but a shared Codex sandbox requires the same resolved source and revision (409 codex_inference_conflict otherwise).
3847
+ * @description Optional credential set to run on instead of the agent's; the conversation stays pinned to it across wakes. Must be owned by the caller (404 inference_credential_not_found otherwise) and satisfy the agent's allowed_inference_credential_ids when that allowlist is set (422 inference_credential_not_allowed). An unusable selected set is 422 inference_credential_unusable. The resolved source and revision stay bound across wakes; replacing or deleting the source returns 409 inference_source_changed. Not part of sandbox identity, but a shared Codex sandbox requires the same resolved source and revision (409 codex_inference_conflict otherwise). The exception is a set that names a ChatGPT subscription: Codex keeps that sign-in in a home of its own, so it shares a sandbox with any other source, unless the sandbox was first bound before Fountain prepared such homes.
3573
3848
  */
3574
3849
  inference_credential_id?: string | null;
3575
3850
  /** @description Key/value strings to stamp on the conversation. At most 32 entries; a key is at most 64 bytes and a value at most 256 bytes, and a 422 names the offending key under `errors.labels`. With channel_id, a resume merges these into the conversation it hands back rather than dropping them. */
3576
3851
  labels?: {
3577
3852
  [key: string]: string;
3578
3853
  } | null;
3579
- /** @description Per-launch permission override (#939). Keys are matched against the tool card's title first and then ACP's kind (execute, edit, read, fetch, …); "default" covers the rest. Prefer a kind: claude titles a tool call with the command it is about to run, so a title matches one invocation only. Merged with the agent's own policy, taking the stricter of the two. It may only narrow: a policy that would loosen any tool is refused with 422 permission_policy_widens rather than silently clamped, and one the runtime never consults is refused with 422 permission_policy_unenforceable. */
3854
+ /** @description Optional model to run instead of the agent's (ADR 0061), in canonical provider/model_id form, for this conversation only. Checked as the agent's own model is: a provider the runtime does not drive, or any model on the acp runtime, is 422 model_invalid. The model id itself is not checked against a catalog. Change it later with POST /api/conversations/{id}/reapply. Not part of the channel_id resume key: a request that resumes a conversation running a different model is 409 conversation_model_differs, before any prompt is sent; reapply the model, or set fresh: true. */
3855
+ model?: string | null;
3856
+ /** @description Per-launch permission override (#939). Keys are matched against the tool card's title first and then ACP's kind (execute, edit, read, fetch, …); "default" covers the rest. Prefer a kind: claude titles a tool call with the command it is about to run, so a title matches one invocation only. Merged with the agent's own policy, taking the stricter of the two. It may only narrow: a policy that would loosen any tool is refused with 422 permission_policy_widens rather than silently clamped, and one the runtime never consults is refused with 422 permission_policy_unenforceable. If a queued request with a prompt and a nonempty policy resumes an existing channel, it fails with permission_policy_requires_fresh_conversation before sending the prompt. Set fresh: true to create a conversation for that policy. */
3580
3857
  permission_policy?: components["schemas"]["PermissionPolicy"] | null;
3581
3858
  /** @description Optional first turn prompt. A launch may open with no prompt at all, but a prompt that is present must carry words: blank and whitespace-only text is refused with 422 invalid_prompt, before the launch reserves a sandbox. */
3582
3859
  prompt?: string;
@@ -3589,7 +3866,7 @@ export interface components {
3589
3866
  sandbox_api_access?: "owner" | "none";
3590
3867
  /**
3591
3868
  * Format: uuid
3592
- * @description Attach the conversation to a sandbox you already have instead of provisioning one (ADR 0023). The sandbox must be yours (404 sandbox_not_found), ready or suspended (409 sandbox_not_attachable), and built for the same agent, environment and vault as this launch (422 sandbox_identity_mismatch; 422 sandbox_runtime_mismatch if the agent's runtime changed since). The conversation opens idle on that machine; a prompt here wakes it. Several conversations then run on one disk at once, except on opencode and gemini, where a second turn of the same runtime is refused with 409 sandbox_at_capacity while one runs.
3869
+ * @description Attach the conversation to a sandbox you already have instead of provisioning one (ADR 0023). The sandbox must be yours (404 sandbox_not_found), ready or suspended (409 sandbox_not_attachable), and built from the same environment and vault as this launch (422 sandbox_identity_mismatch). It is normally the same agent's (422 sandbox_runtime_mismatch if the agent's runtime changed since). An agent other than the one the sandbox was built for may attach to that agent's persistent sandbox as a guest only to make a claude and codex pair: a codex agent on a claude agent's home, or a claude agent on a codex agent's, where no other agent of either runtime has run. Any other guest is 422 sandbox_identity_mismatch. Attaching a guest needs a full-scope API key; a sandbox's own token, or any key below full scope, is refused with 403 guest_attach_requires_full_scope (reason insufficient_scope), a channel rotation (fresh) of a guest included. The sandbox stays its own agent's, and a guest's reapply is refused with 409 rebuild_required: field shared_sandbox while another conversation is on the sandbox, field guest when the guest is alone there. A claude home created before guests were admitted refuses a codex guest with 409 codex_inference_conflict until it is reset. The conversation opens idle on that machine; a prompt here wakes it. Several conversations then run on one disk at once, except on opencode and gemini, where a second turn of the same runtime is refused with 409 sandbox_at_capacity while one runs.
3593
3870
  */
3594
3871
  sandbox_id?: string | null;
3595
3872
  /**
@@ -3597,6 +3874,8 @@ export interface components {
3597
3874
  * @enum {string|null}
3598
3875
  */
3599
3876
  sandbox_mode?: "ephemeral" | "persistent" | null;
3877
+ /** @description ACP session config options for this conversation (ADR 0062), over the agent's, such as {"reasoning_effort": "high"}. Applied after the model on every turn. The ids and values are the adapter's own; one it does not advertise is skipped, and a value it refuses fails the turn. */
3878
+ session_config?: components["schemas"]["SessionConfig"];
3600
3879
  /** @description Name the conversation's machine instead of taking a generated name. The value is the suffix of an account-scoped name: the server keeps the fountain-<account>- prefix every generated name carries, so a name you choose lands in your own namespace rather than another account's. 1 to 40 characters of letters, digits, - and _, starting with a letter or digit; a name that already carries this account's prefix is taken as it stands, so a name from an earlier launch resolves to the same machine. 422 invalid_sprite_name otherwise. Refused with 422 sprite_name_not_supported on an agent that runs on a self-hosted runner, where the name carries the runner instead. Refused with sandbox_api_access none, which requires a machine no other conversation can reach. */
3601
3880
  sprite_name?: string;
3602
3881
  /** @description Optional display title. The team page names a teammate with it. */
@@ -3623,7 +3902,7 @@ export interface components {
3623
3902
  };
3624
3903
  /**
3625
3904
  * ConversationReapplyRequest
3626
- * @description A selection of Agent, Environment and Vault to apply to the machine an existing conversation already runs on. An omitted field keeps its current selection. An explicit null clears the Environment override or the Vault. An empty object reapplies the current selection.
3905
+ * @description A selection of Agent, Environment, Vault, model and session config to apply to the machine an existing conversation already runs on. An omitted field keeps its current selection. An explicit null clears the Environment override, the Vault, the model override or the session config. An empty object reapplies the current selection.
3627
3906
  */
3628
3907
  ConversationReapplyRequest: {
3629
3908
  /**
@@ -3636,6 +3915,10 @@ export interface components {
3636
3915
  * @description Environment override to use; null returns to the selected Agent's Environment.
3637
3916
  */
3638
3917
  environment_id?: string | null;
3918
+ /** @description Model to run from the next turn (ADR 0061), in canonical provider/model_id form; null returns to the selected Agent's model. Checked against the selected Agent's runtime (422 model_invalid). The conversation keeps its credential: a model that credential does not serve is 409 inference_source_changed and nothing changes. The runtime session is kept, so the next turn continues it on the new model. */
3919
+ model?: string | null;
3920
+ /** @description ACP session config options to request from the next turn (ADR 0062), replacing the conversation's current ones; null or {} returns to the Agent's. Only the shape is checked here. The adapter decides which ids and values exist. */
3921
+ session_config?: components["schemas"]["SessionConfig"];
3639
3922
  /**
3640
3923
  * Format: uuid
3641
3924
  * @description Vault to use; null detaches the current Vault.
@@ -3645,6 +3928,11 @@ export interface components {
3645
3928
  /** ConversationResponse */
3646
3929
  ConversationResponse: {
3647
3930
  data: components["schemas"]["Conversation"];
3931
+ /** @description Present when creating or resuming a conversation. */
3932
+ meta?: {
3933
+ /** @description Whether the channel resumed an existing conversation. */
3934
+ resumed: boolean;
3935
+ };
3648
3936
  };
3649
3937
  /**
3650
3938
  * ConversationTreeNode
@@ -3858,6 +4146,13 @@ export interface components {
3858
4146
  Error: {
3859
4147
  /** @description Sandboxes the account has in use, on `sandbox_quota_exceeded` (429). */
3860
4148
  active_sandboxes?: number;
4149
+ /**
4150
+ * Format: uuid
4151
+ * @description The sign-in already open on that subscription, on `chatgpt_link_attempt_pending` (409): read or cancel that one.
4152
+ */
4153
+ attempt_id?: string;
4154
+ /** @description How many the account has against `limit`, on `chatgpt_grant_limit_reached` and `chatgpt_link_attempts_exceeded` (409). */
4155
+ count?: number;
3861
4156
  /**
3862
4157
  * @description The machine-readable code: `validation_failed`, `not_found`, `insufficient_credits`, `sandbox_quota_exceeded`, `expired`, `invalid_token` and the rest. On the key-authentication and scope refusals it is a sentence and `reason` carries the code.
3863
4158
  * @example validation_failed
@@ -3867,12 +4162,30 @@ export interface components {
3867
4162
  errors?: {
3868
4163
  [key: string]: string[];
3869
4164
  };
3870
- /** @description The account's concurrent-sandbox cap, on `sandbox_quota_exceeded` (429). */
4165
+ /** @description That subscription's name, on `chatgpt_grant_unusable` (409). */
4166
+ grant?: string | null;
4167
+ /**
4168
+ * Format: uuid
4169
+ * @description The ChatGPT subscription the refusal is about, on `chatgpt_grant_unusable` (409).
4170
+ */
4171
+ grant_id?: string;
4172
+ /** @description The account's concurrent-sandbox cap, on `sandbox_quota_exceeded` (429); how many ChatGPT subscriptions it may hold, on `chatgpt_grant_limit_reached` (409); how many sign-ins it may have open, on `chatgpt_link_attempts_exceeded` (409); how many it may start in an hour, on `chatgpt_link_attempts_rate_limited` (429). */
3871
4173
  limit?: number;
3872
4174
  /** @description A sentence for a human, when there is one. */
3873
4175
  message?: string;
3874
- /** @description A second stable word. On the 401 and 403 refusals from key authentication and scope checks, `error` is prose and this is the code (`api_key_invalid`, `api_key_expired`, `insufficient_scope`). On `broker_unavailable`, `sandbox_not_resettable` and `credential_set_is_default`, `error` is the code and this narrows it (`econnrefused`, `timeout`, `is_default`, ...). */
4176
+ /** @description A second stable word. On the 401 and 403 refusals from key authentication and scope checks, `error` is prose and this is the code (`api_key_invalid`, `api_key_expired`, `insufficient_scope`). On `broker_unavailable`, `sandbox_not_resettable` and `credential_set_is_default`, `error` is the code and this narrows it (`econnrefused`, `timeout`, `is_default`, ...). On `chatgpt_grant_unusable` it says why the named subscription cannot serve: `disconnected`, `revoked`, `expired`, `reconnect_required`, `exhausted`, `not_found`, `broker_required` or `owner_ineligible`. */
3875
4177
  reason?: string;
4178
+ /** @description Seconds until another sign-in may be started, on `chatgpt_link_attempts_rate_limited` (429); the `Retry-After` header says the same. */
4179
+ retry_after_seconds?: number;
4180
+ /** @description The credential sets that still name the subscription, by name, on `chatgpt_grant_named_by_sets` (409): point them elsewhere first. */
4181
+ sets?: string[];
4182
+ /** @description What the attempt had already become, on `chatgpt_link_attempt_not_pending` (409). */
4183
+ state?: string;
4184
+ /**
4185
+ * Format: date-time
4186
+ * @description When the subscription's Codex usage resets, on `chatgpt_grant_unusable` with `reason: "exhausted"`; null otherwise.
4187
+ */
4188
+ until?: string | null;
3876
4189
  /** @description Where to buy credit, on `insufficient_credits` (402). */
3877
4190
  upgrade_url?: string;
3878
4191
  };
@@ -3946,6 +4259,19 @@ export interface components {
3946
4259
  * @description One named set of a tenant's inference credentials. An account holds one or more and exactly one is the default; an agent or a launch may name another. Values are never returned — `providers` reports only which of them this set holds.
3947
4260
  */
3948
4261
  InferenceCredentialSet: {
4262
+ /** @description The named subscription's name and status, so a set that will fail says so here. Read-only; the whole subscription is at `/api/account/chatgpt-subscriptions`. */
4263
+ chatgpt_grant: {
4264
+ /** Format: uuid */
4265
+ id: string;
4266
+ name: string;
4267
+ /** @enum {string} */
4268
+ status: "active" | "revoked" | "expired" | "disconnected";
4269
+ } | null;
4270
+ /**
4271
+ * Format: uuid
4272
+ * @description The ChatGPT subscription this set's codex runs use, or null. A named subscription is used or the run fails with 409 `chatgpt_grant_unusable`: nothing falls back to the set's `openai_api_key`, to another subscription or to the platform. Every other OpenAI consumer still needs the key.
4273
+ */
4274
+ chatgpt_grant_id: string | null;
3949
4275
  /** Format: uuid */
3950
4276
  id: string;
3951
4277
  /** Format: date-time */
@@ -3973,9 +4299,14 @@ export interface components {
3973
4299
  };
3974
4300
  /**
3975
4301
  * InferenceCredentialSetUpdateRequest
3976
- * @description Rename a set, make it the default, or both. Omitting a field leaves it alone. `is_default: false` is refused: a set stops being the default when another becomes it, never on its own.
4302
+ * @description Rename a set, make it the default, name a ChatGPT subscription, or any of them. Omitting a field leaves it alone. `is_default: false` is refused: a set stops being the default when another becomes it, never on its own.
3977
4303
  */
3978
4304
  InferenceCredentialSetUpdateRequest: {
4305
+ /**
4306
+ * Format: uuid
4307
+ * @description One of the account's ChatGPT subscriptions, or null to stop naming one. Naming one ends the set's running codex conversations.
4308
+ */
4309
+ chatgpt_grant_id?: string | null;
3979
4310
  is_default?: boolean;
3980
4311
  name?: string;
3981
4312
  };
@@ -4020,11 +4351,26 @@ export interface components {
4020
4351
  LogEventListResponse: {
4021
4352
  data: components["schemas"]["LogEvent"][];
4022
4353
  meta: {
4354
+ /** @description More matching events exist past this page: newer ones for `asc`, older ones for `desc`. */
4023
4355
  has_more: boolean;
4024
4356
  limit: number;
4025
- /** @description Pass as `after` to fetch the next page. null when the page is empty. */
4357
+ /** @description The page's last event id: pass as `after` (`asc`) or `before` (`desc`) to fetch the next page. null when the page is empty. */
4026
4358
  next_cursor?: number | null;
4027
4359
  };
4360
+ /** @description The window this page covers (#2531). */
4361
+ page?: {
4362
+ /** @description The largest event id on the page; on the first `order=desc` page, the `Last-Event-ID` an SSE follow resumes from. null when the page is empty. */
4363
+ newest_cursor: number | null;
4364
+ /** @description The smallest event id on the page. null when the page is empty. */
4365
+ oldest_cursor: number | null;
4366
+ /**
4367
+ * @description The order of `data`, as requested.
4368
+ * @enum {string}
4369
+ */
4370
+ order: "asc" | "desc";
4371
+ /** @description `whole_turns=true` reached its ceiling inside a turn: the page's oldest turn continues on the next page. Always false otherwise. */
4372
+ turn_split: boolean;
4373
+ };
4028
4374
  };
4029
4375
  /**
4030
4376
  * ManifestResource
@@ -4197,6 +4543,8 @@ export interface components {
4197
4543
  /** @description Optional images to attach to this prompt. */
4198
4544
  images?: components["schemas"]["ImageInput"][] | null;
4199
4545
  prompt: string;
4546
+ /** @description ACP session config options for this turn only (ADR 0062), over the conversation's and the agent's, such as {"effort": "high", "fast": true}. The next turn goes back to the conversation's. The turn's config_selection records what was requested, applied and skipped. */
4547
+ session_config?: components["schemas"]["SessionConfig"];
4200
4548
  };
4201
4549
  /** PromptResponse */
4202
4550
  PromptResponse: {
@@ -4225,6 +4573,8 @@ export interface components {
4225
4573
  };
4226
4574
  /** RegisterRequest */
4227
4575
  RegisterRequest: {
4576
+ /** @description The instance's signup access code. Required only when the operator set one; otherwise ignored. */
4577
+ access_code?: string;
4228
4578
  /** Format: email */
4229
4579
  email: string;
4230
4580
  /** Format: password */
@@ -4281,7 +4631,7 @@ export interface components {
4281
4631
  Sandbox: {
4282
4632
  /**
4283
4633
  * Format: uuid
4284
- * @description The agent the machine was built for. With environment_id and vault_id it is the identity a conversation must match to attach (sandbox_id on create).
4634
+ * @description The agent the machine was built for. With environment_id and vault_id it is the identity a conversation must match to attach (sandbox_id on create); an agent of another runtime may attach to a persistent machine as a guest, which leaves this field unchanged.
4285
4635
  */
4286
4636
  agent_id?: string | null;
4287
4637
  /** @description The checkpoint Fountain took of this home the last time it parked (ADR 0023). It is scoped to this machine: it can roll the machine back, not rebuild a machine that is gone. Null for an ephemeral sandbox, a provider without checkpoints, or a home that has not parked yet. */
@@ -4367,7 +4717,7 @@ export interface components {
4367
4717
  SandboxDetail: {
4368
4718
  /**
4369
4719
  * Format: uuid
4370
- * @description The agent the machine was built for. With environment_id and vault_id it is the identity a conversation must match to attach (sandbox_id on create).
4720
+ * @description The agent the machine was built for. With environment_id and vault_id it is the identity a conversation must match to attach (sandbox_id on create); an agent of another runtime may attach to a persistent machine as a guest, which leaves this field unchanged.
4371
4721
  */
4372
4722
  agent_id?: string | null;
4373
4723
  /** @description The checkpoint Fountain took of this home the last time it parked (ADR 0023). It is scoped to this machine: it can roll the machine back, not rebuild a machine that is gone. Null for an ephemeral sandbox, a provider without checkpoints, or a home that has not parked yet. */
@@ -4498,7 +4848,7 @@ export interface components {
4498
4848
  agent_id: string;
4499
4849
  /**
4500
4850
  * Format: uuid
4501
- * @description The conversation the request became, once it started.
4851
+ * @description The conversation the request started, or the target when a failed request reports prompt_delivery_unknown. Inspect it before resubmitting: after a timeout or connection loss, the prompt may have run or may still execute.
4502
4852
  */
4503
4853
  conversation_id?: string | null;
4504
4854
  error?: string | null;
@@ -4690,6 +5040,35 @@ export interface components {
4690
5040
  SecretResponse: {
4691
5041
  data: components["schemas"]["Secret"];
4692
5042
  };
5043
+ /**
5044
+ * SessionConfig
5045
+ * @description ACP session config options to request (ADR 0062): a map of the adapter's option id to a value, a string or a boolean. The ids and values are the adapter's own and are not checked against a list: claude-agent-acp offers `effort` and `fast`, codex-acp `reasoning_effort` and `fast-mode`, and which exist depends on the model. They are applied after the model and before each prompt. An id the adapter does not advertise is skipped, and a `config` stage event reports it (`done`, outcome `skipped`). A value it refuses fails the turn. `model` is refused here; use the model field. `session_config_options` on the conversation lists what the adapter offers.
5046
+ * @example {
5047
+ * "effort": "high",
5048
+ * "fast": true
5049
+ * }
5050
+ */
5051
+ SessionConfig: {
5052
+ [key: string]: string | boolean;
5053
+ } | null;
5054
+ /**
5055
+ * SessionConfigOption
5056
+ * @description One config option as the adapter advertised it (ACP `SessionConfigOption`), passed through unchanged. `category` is `thought_level` for reasoning effort and `model_config` for fast mode on the pinned adapters. `options` lists a select's values, possibly in groups. `currentValue` is the value in force.
5057
+ */
5058
+ SessionConfigOption: {
5059
+ category?: string | null;
5060
+ currentValue?: string | boolean;
5061
+ description?: string | null;
5062
+ id: string;
5063
+ name?: string;
5064
+ options?: {
5065
+ [key: string]: unknown;
5066
+ }[];
5067
+ /** @description `select` or `boolean`. */
5068
+ type?: string;
5069
+ } & {
5070
+ [key: string]: unknown;
5071
+ };
4693
5072
  /**
4694
5073
  * StreamLogEvent
4695
5074
  * @description One frame of the conversation, events or team SSE log stream (#2297). Same fields as `LogEvent` minus `id` — the frame's id travels in the SSE `id:` line, never the JSON body — plus `conversation_id` and `agent_id`, which the REST log feed never sends because its URL or list item already names the conversation.
@@ -4975,6 +5354,10 @@ export interface components {
4975
5354
  Turn: {
4976
5355
  /** @description The `client_request_id` of the prompt that opened this turn (#1406), or null: the caller sent none, or the turn is `autonomous`. Not unique. This is the value the caller sent, byte for byte, and it is the one to compare against: the copy on the turn's `started` stage event has been through event redaction, which rewrites any registered environment value it contains. */
4977
5356
  client_request_id?: string | null;
5357
+ /** @description The ACP session config options of this turn (ADR 0062). `requested` is what the turn asked for (agent, then conversation, then prompt). `applied` maps each id the adapter took to the value it confirmed. `skipped` lists ids the adapter did not advertise. On a refusal, `status` is `failed` with `error`. Null on a turn that requested none. */
5358
+ config_selection?: {
5359
+ [key: string]: unknown;
5360
+ } | null;
4978
5361
  /** Format: date-time */
4979
5362
  ended_at?: string | null;
4980
5363
  exit_code?: number | null;
@@ -4982,6 +5365,24 @@ export interface components {
4982
5365
  id: string;
4983
5366
  /** @description Number of images attached to this turn. */
4984
5367
  image_count?: number;
5368
+ /** @description Which inference source served this turn, recorded once when the turn started and never rewritten: repointing the credential set, reconnecting the subscription or restarting the conversation changes later turns only. Null on a turn that started before the source was recorded. */
5369
+ readonly inference?: {
5370
+ /**
5371
+ * Format: uuid
5372
+ * @description The ChatGPT subscription that served the turn when `scope` is `grant`, as listed by `GET /api/account/chatgpt-subscriptions`; null otherwise. It keeps naming that subscription after the subscription is removed.
5373
+ */
5374
+ chatgpt_grant_id: string | null;
5375
+ /**
5376
+ * @description `own` for a credential of the account's, `platform` for the deployment's.
5377
+ * @enum {string}
5378
+ */
5379
+ origin: "own" | "platform";
5380
+ /**
5381
+ * @description Where the credential came from: the account's credential set (`credential`), an environment or vault value (`tenant_secret`), a ChatGPT subscription the set names (`grant`), the deployment (`platform`), or nowhere because the provider needs none (`none`) or none was found (`missing`).
5382
+ * @enum {string}
5383
+ */
5384
+ scope: "credential" | "tenant_secret" | "grant" | "platform" | "none" | "missing";
5385
+ } | null;
4985
5386
  /** Format: date-time */
4986
5387
  inserted_at?: string;
4987
5388
  /** @description The service-enforced limit that ended this turn, or null. Set independently of exit_code: a runtime that exits zero after its deadline is still an incomplete turn, so a client must read this before treating a turn as successful. */
@@ -5256,35 +5657,549 @@ export interface components {
5256
5657
  queued: boolean;
5257
5658
  };
5258
5659
  };
5259
- responses: never;
5260
- parameters: never;
5261
- requestBodies: never;
5262
- headers: never;
5263
- pathItems: never;
5264
- }
5265
- export type $defs = Record<string, never>;
5266
- export interface operations {
5267
- "FountainWeb.AccountDataController.delete_account": {
5660
+ responses: never;
5661
+ parameters: never;
5662
+ requestBodies: never;
5663
+ headers: never;
5664
+ pathItems: never;
5665
+ }
5666
+ export type $defs = Record<string, never>;
5667
+ export interface operations {
5668
+ "FountainWeb.AccountDataController.delete_account": {
5669
+ parameters: {
5670
+ query?: never;
5671
+ header?: never;
5672
+ path?: never;
5673
+ cookie?: never;
5674
+ };
5675
+ /** @description Confirmation */
5676
+ requestBody?: {
5677
+ content: {
5678
+ "application/json": components["schemas"]["AccountDeleteRequest"];
5679
+ };
5680
+ };
5681
+ responses: {
5682
+ /** @description Deleted */
5683
+ 200: {
5684
+ headers: {
5685
+ [name: string]: unknown;
5686
+ };
5687
+ content: {
5688
+ "application/json": components["schemas"]["AccountDeletedResponse"];
5689
+ };
5690
+ };
5691
+ /** @description Unauthorized */
5692
+ 401: {
5693
+ headers: {
5694
+ [name: string]: unknown;
5695
+ };
5696
+ content: {
5697
+ "application/json": components["schemas"]["Error"];
5698
+ };
5699
+ };
5700
+ /** @description Insufficient scope */
5701
+ 403: {
5702
+ headers: {
5703
+ [name: string]: unknown;
5704
+ };
5705
+ content: {
5706
+ "application/json": components["schemas"]["Error"];
5707
+ };
5708
+ };
5709
+ /** @description No acceptable representation */
5710
+ 406: {
5711
+ headers: {
5712
+ [name: string]: unknown;
5713
+ };
5714
+ content: {
5715
+ "application/json": components["schemas"]["NegotiationError"];
5716
+ };
5717
+ };
5718
+ /** @description Confirmation mismatch */
5719
+ 422: {
5720
+ headers: {
5721
+ [name: string]: unknown;
5722
+ };
5723
+ content: {
5724
+ "application/json": components["schemas"]["Error"];
5725
+ };
5726
+ };
5727
+ /** @description Too Many Requests */
5728
+ 429: {
5729
+ headers: {
5730
+ [name: string]: unknown;
5731
+ };
5732
+ content: {
5733
+ "application/json": components["schemas"]["Error"];
5734
+ };
5735
+ };
5736
+ /** @description Billing cancellation failed */
5737
+ 502: {
5738
+ headers: {
5739
+ [name: string]: unknown;
5740
+ };
5741
+ content: {
5742
+ "application/json": components["schemas"]["Error"];
5743
+ };
5744
+ };
5745
+ };
5746
+ };
5747
+ "FountainWeb.BillingApiController.show": {
5748
+ parameters: {
5749
+ query?: never;
5750
+ header?: never;
5751
+ path?: never;
5752
+ cookie?: never;
5753
+ };
5754
+ requestBody?: never;
5755
+ responses: {
5756
+ /** @description Billing */
5757
+ 200: {
5758
+ headers: {
5759
+ [name: string]: unknown;
5760
+ };
5761
+ content: {
5762
+ "application/json": components["schemas"]["BillingResponse"];
5763
+ };
5764
+ };
5765
+ /** @description Unauthorized */
5766
+ 401: {
5767
+ headers: {
5768
+ [name: string]: unknown;
5769
+ };
5770
+ content: {
5771
+ "application/json": components["schemas"]["Error"];
5772
+ };
5773
+ };
5774
+ /** @description Insufficient scope */
5775
+ 403: {
5776
+ headers: {
5777
+ [name: string]: unknown;
5778
+ };
5779
+ content: {
5780
+ "application/json": components["schemas"]["Error"];
5781
+ };
5782
+ };
5783
+ /** @description Billing disabled */
5784
+ 404: {
5785
+ headers: {
5786
+ [name: string]: unknown;
5787
+ };
5788
+ content: {
5789
+ "application/json": components["schemas"]["Error"];
5790
+ };
5791
+ };
5792
+ /** @description No acceptable representation */
5793
+ 406: {
5794
+ headers: {
5795
+ [name: string]: unknown;
5796
+ };
5797
+ content: {
5798
+ "application/json": components["schemas"]["NegotiationError"];
5799
+ };
5800
+ };
5801
+ /** @description Too Many Requests */
5802
+ 429: {
5803
+ headers: {
5804
+ [name: string]: unknown;
5805
+ };
5806
+ content: {
5807
+ "application/json": components["schemas"]["Error"];
5808
+ };
5809
+ };
5810
+ };
5811
+ };
5812
+ "FountainWeb.BillingApiController.credits_checkout": {
5813
+ parameters: {
5814
+ query?: never;
5815
+ header?: never;
5816
+ path?: never;
5817
+ cookie?: never;
5818
+ };
5819
+ /** @description Pack */
5820
+ requestBody: {
5821
+ content: {
5822
+ "application/json": components["schemas"]["CreditsCheckoutRequest"];
5823
+ };
5824
+ };
5825
+ responses: {
5826
+ /** @description Stripe URL */
5827
+ 200: {
5828
+ headers: {
5829
+ [name: string]: unknown;
5830
+ };
5831
+ content: {
5832
+ "application/json": components["schemas"]["StripeUrlResponse"];
5833
+ };
5834
+ };
5835
+ /** @description Unauthorized */
5836
+ 401: {
5837
+ headers: {
5838
+ [name: string]: unknown;
5839
+ };
5840
+ content: {
5841
+ "application/json": components["schemas"]["Error"];
5842
+ };
5843
+ };
5844
+ /** @description Insufficient scope */
5845
+ 403: {
5846
+ headers: {
5847
+ [name: string]: unknown;
5848
+ };
5849
+ content: {
5850
+ "application/json": components["schemas"]["Error"];
5851
+ };
5852
+ };
5853
+ /** @description Billing disabled */
5854
+ 404: {
5855
+ headers: {
5856
+ [name: string]: unknown;
5857
+ };
5858
+ content: {
5859
+ "application/json": components["schemas"]["Error"];
5860
+ };
5861
+ };
5862
+ /** @description No acceptable representation */
5863
+ 406: {
5864
+ headers: {
5865
+ [name: string]: unknown;
5866
+ };
5867
+ content: {
5868
+ "application/json": components["schemas"]["NegotiationError"];
5869
+ };
5870
+ };
5871
+ /** @description Refused */
5872
+ 422: {
5873
+ headers: {
5874
+ [name: string]: unknown;
5875
+ };
5876
+ content: {
5877
+ "application/json": components["schemas"]["Error"];
5878
+ };
5879
+ };
5880
+ /** @description Too Many Requests */
5881
+ 429: {
5882
+ headers: {
5883
+ [name: string]: unknown;
5884
+ };
5885
+ content: {
5886
+ "application/json": components["schemas"]["Error"];
5887
+ };
5888
+ };
5889
+ /** @description Stripe unreachable */
5890
+ 502: {
5891
+ headers: {
5892
+ [name: string]: unknown;
5893
+ };
5894
+ content: {
5895
+ "application/json": components["schemas"]["Error"];
5896
+ };
5897
+ };
5898
+ };
5899
+ };
5900
+ "FountainWeb.ChatGPTSubscriptionController.index": {
5901
+ parameters: {
5902
+ query?: never;
5903
+ header?: never;
5904
+ path?: never;
5905
+ cookie?: never;
5906
+ };
5907
+ requestBody?: never;
5908
+ responses: {
5909
+ /** @description Subscriptions */
5910
+ 200: {
5911
+ headers: {
5912
+ [name: string]: unknown;
5913
+ };
5914
+ content: {
5915
+ "application/json": components["schemas"]["ChatGPTSubscriptionListResponse"];
5916
+ };
5917
+ };
5918
+ /** @description Unauthorized */
5919
+ 401: {
5920
+ headers: {
5921
+ [name: string]: unknown;
5922
+ };
5923
+ content: {
5924
+ "application/json": components["schemas"]["Error"];
5925
+ };
5926
+ };
5927
+ /** @description Insufficient scope */
5928
+ 403: {
5929
+ headers: {
5930
+ [name: string]: unknown;
5931
+ };
5932
+ content: {
5933
+ "application/json": components["schemas"]["Error"];
5934
+ };
5935
+ };
5936
+ /** @description No acceptable representation */
5937
+ 406: {
5938
+ headers: {
5939
+ [name: string]: unknown;
5940
+ };
5941
+ content: {
5942
+ "application/json": components["schemas"]["NegotiationError"];
5943
+ };
5944
+ };
5945
+ /** @description Too Many Requests */
5946
+ 429: {
5947
+ headers: {
5948
+ [name: string]: unknown;
5949
+ };
5950
+ content: {
5951
+ "application/json": components["schemas"]["Error"];
5952
+ };
5953
+ };
5954
+ };
5955
+ };
5956
+ "FountainWeb.ChatGPTSubscriptionController.index_attempts": {
5957
+ parameters: {
5958
+ query?: never;
5959
+ header?: never;
5960
+ path?: never;
5961
+ cookie?: never;
5962
+ };
5963
+ requestBody?: never;
5964
+ responses: {
5965
+ /** @description Attempts */
5966
+ 200: {
5967
+ headers: {
5968
+ [name: string]: unknown;
5969
+ };
5970
+ content: {
5971
+ "application/json": components["schemas"]["ChatGPTLinkAttemptListResponse"];
5972
+ };
5973
+ };
5974
+ /** @description Unauthorized */
5975
+ 401: {
5976
+ headers: {
5977
+ [name: string]: unknown;
5978
+ };
5979
+ content: {
5980
+ "application/json": components["schemas"]["Error"];
5981
+ };
5982
+ };
5983
+ /** @description Insufficient scope */
5984
+ 403: {
5985
+ headers: {
5986
+ [name: string]: unknown;
5987
+ };
5988
+ content: {
5989
+ "application/json": components["schemas"]["Error"];
5990
+ };
5991
+ };
5992
+ /** @description No acceptable representation */
5993
+ 406: {
5994
+ headers: {
5995
+ [name: string]: unknown;
5996
+ };
5997
+ content: {
5998
+ "application/json": components["schemas"]["NegotiationError"];
5999
+ };
6000
+ };
6001
+ /** @description Too Many Requests */
6002
+ 429: {
6003
+ headers: {
6004
+ [name: string]: unknown;
6005
+ };
6006
+ content: {
6007
+ "application/json": components["schemas"]["Error"];
6008
+ };
6009
+ };
6010
+ };
6011
+ };
6012
+ "FountainWeb.ChatGPTSubscriptionController.create_attempt": {
6013
+ parameters: {
6014
+ query?: never;
6015
+ header?: never;
6016
+ path?: never;
6017
+ cookie?: never;
6018
+ };
6019
+ /** @description What to sign in for */
6020
+ requestBody?: {
6021
+ content: {
6022
+ "application/json": components["schemas"]["ChatGPTLinkAttemptCreateRequest"];
6023
+ };
6024
+ };
6025
+ responses: {
6026
+ /** @description Attempt */
6027
+ 201: {
6028
+ headers: {
6029
+ [name: string]: unknown;
6030
+ };
6031
+ content: {
6032
+ "application/json": components["schemas"]["ChatGPTLinkAttemptResponse"];
6033
+ };
6034
+ };
6035
+ /** @description Unauthorized */
6036
+ 401: {
6037
+ headers: {
6038
+ [name: string]: unknown;
6039
+ };
6040
+ content: {
6041
+ "application/json": components["schemas"]["Error"];
6042
+ };
6043
+ };
6044
+ /** @description Insufficient scope, or `chatgpt_owner_ineligible` */
6045
+ 403: {
6046
+ headers: {
6047
+ [name: string]: unknown;
6048
+ };
6049
+ content: {
6050
+ "application/json": components["schemas"]["Error"];
6051
+ };
6052
+ };
6053
+ /** @description `chatgpt_subscriptions_not_enabled`, or no such subscription to reconnect */
6054
+ 404: {
6055
+ headers: {
6056
+ [name: string]: unknown;
6057
+ };
6058
+ content: {
6059
+ "application/json": components["schemas"]["Error"];
6060
+ };
6061
+ };
6062
+ /** @description No acceptable representation */
6063
+ 406: {
6064
+ headers: {
6065
+ [name: string]: unknown;
6066
+ };
6067
+ content: {
6068
+ "application/json": components["schemas"]["NegotiationError"];
6069
+ };
6070
+ };
6071
+ /** @description `chatgpt_grant_limit_reached`, `chatgpt_link_attempts_exceeded` or `chatgpt_link_attempt_pending` */
6072
+ 409: {
6073
+ headers: {
6074
+ [name: string]: unknown;
6075
+ };
6076
+ content: {
6077
+ "application/json": components["schemas"]["Error"];
6078
+ };
6079
+ };
6080
+ /** @description Invalid or duplicate name */
6081
+ 422: {
6082
+ headers: {
6083
+ [name: string]: unknown;
6084
+ };
6085
+ content: {
6086
+ "application/json": components["schemas"]["Error"];
6087
+ };
6088
+ };
6089
+ /** @description `chatgpt_link_attempts_rate_limited`, with `Retry-After` */
6090
+ 429: {
6091
+ headers: {
6092
+ [name: string]: unknown;
6093
+ };
6094
+ content: {
6095
+ "application/json": components["schemas"]["Error"];
6096
+ };
6097
+ };
6098
+ /** @description `chatgpt_auth_unreachable` */
6099
+ 502: {
6100
+ headers: {
6101
+ [name: string]: unknown;
6102
+ };
6103
+ content: {
6104
+ "application/json": components["schemas"]["Error"];
6105
+ };
6106
+ };
6107
+ /** @description `chatgpt_tenant_key_unavailable` */
6108
+ 503: {
6109
+ headers: {
6110
+ [name: string]: unknown;
6111
+ };
6112
+ content: {
6113
+ "application/json": components["schemas"]["Error"];
6114
+ };
6115
+ };
6116
+ };
6117
+ };
6118
+ "FountainWeb.ChatGPTSubscriptionController.show_attempt": {
6119
+ parameters: {
6120
+ query?: never;
6121
+ header?: never;
6122
+ path: {
6123
+ id: string;
6124
+ };
6125
+ cookie?: never;
6126
+ };
6127
+ requestBody?: never;
6128
+ responses: {
6129
+ /** @description Attempt */
6130
+ 200: {
6131
+ headers: {
6132
+ [name: string]: unknown;
6133
+ };
6134
+ content: {
6135
+ "application/json": components["schemas"]["ChatGPTLinkAttemptResponse"];
6136
+ };
6137
+ };
6138
+ /** @description Unauthorized */
6139
+ 401: {
6140
+ headers: {
6141
+ [name: string]: unknown;
6142
+ };
6143
+ content: {
6144
+ "application/json": components["schemas"]["Error"];
6145
+ };
6146
+ };
6147
+ /** @description Insufficient scope */
6148
+ 403: {
6149
+ headers: {
6150
+ [name: string]: unknown;
6151
+ };
6152
+ content: {
6153
+ "application/json": components["schemas"]["Error"];
6154
+ };
6155
+ };
6156
+ /** @description No such attempt */
6157
+ 404: {
6158
+ headers: {
6159
+ [name: string]: unknown;
6160
+ };
6161
+ content: {
6162
+ "application/json": components["schemas"]["Error"];
6163
+ };
6164
+ };
6165
+ /** @description No acceptable representation */
6166
+ 406: {
6167
+ headers: {
6168
+ [name: string]: unknown;
6169
+ };
6170
+ content: {
6171
+ "application/json": components["schemas"]["NegotiationError"];
6172
+ };
6173
+ };
6174
+ /** @description Too Many Requests */
6175
+ 429: {
6176
+ headers: {
6177
+ [name: string]: unknown;
6178
+ };
6179
+ content: {
6180
+ "application/json": components["schemas"]["Error"];
6181
+ };
6182
+ };
6183
+ };
6184
+ };
6185
+ "FountainWeb.ChatGPTSubscriptionController.cancel_attempt": {
5268
6186
  parameters: {
5269
6187
  query?: never;
5270
6188
  header?: never;
5271
- path?: never;
5272
- cookie?: never;
5273
- };
5274
- /** @description Confirmation */
5275
- requestBody?: {
5276
- content: {
5277
- "application/json": components["schemas"]["AccountDeleteRequest"];
6189
+ path: {
6190
+ id: string;
5278
6191
  };
6192
+ cookie?: never;
5279
6193
  };
6194
+ requestBody?: never;
5280
6195
  responses: {
5281
- /** @description Deleted */
6196
+ /** @description Attempt */
5282
6197
  200: {
5283
6198
  headers: {
5284
6199
  [name: string]: unknown;
5285
6200
  };
5286
6201
  content: {
5287
- "application/json": components["schemas"]["AccountDeletedResponse"];
6202
+ "application/json": components["schemas"]["ChatGPTLinkAttemptResponse"];
5288
6203
  };
5289
6204
  };
5290
6205
  /** @description Unauthorized */
@@ -5305,26 +6220,26 @@ export interface operations {
5305
6220
  "application/json": components["schemas"]["Error"];
5306
6221
  };
5307
6222
  };
5308
- /** @description No acceptable representation */
5309
- 406: {
6223
+ /** @description No such attempt */
6224
+ 404: {
5310
6225
  headers: {
5311
6226
  [name: string]: unknown;
5312
6227
  };
5313
6228
  content: {
5314
- "application/json": components["schemas"]["NegotiationError"];
6229
+ "application/json": components["schemas"]["Error"];
5315
6230
  };
5316
6231
  };
5317
- /** @description Confirmation mismatch */
5318
- 422: {
6232
+ /** @description No acceptable representation */
6233
+ 406: {
5319
6234
  headers: {
5320
6235
  [name: string]: unknown;
5321
6236
  };
5322
6237
  content: {
5323
- "application/json": components["schemas"]["Error"];
6238
+ "application/json": components["schemas"]["NegotiationError"];
5324
6239
  };
5325
6240
  };
5326
- /** @description Too Many Requests */
5327
- 429: {
6241
+ /** @description `chatgpt_link_attempt_not_pending` */
6242
+ 409: {
5328
6243
  headers: {
5329
6244
  [name: string]: unknown;
5330
6245
  };
@@ -5332,8 +6247,8 @@ export interface operations {
5332
6247
  "application/json": components["schemas"]["Error"];
5333
6248
  };
5334
6249
  };
5335
- /** @description Billing cancellation failed */
5336
- 502: {
6250
+ /** @description Too Many Requests */
6251
+ 429: {
5337
6252
  headers: {
5338
6253
  [name: string]: unknown;
5339
6254
  };
@@ -5343,23 +6258,23 @@ export interface operations {
5343
6258
  };
5344
6259
  };
5345
6260
  };
5346
- "FountainWeb.BillingApiController.show": {
6261
+ "FountainWeb.ChatGPTSubscriptionController.delete": {
5347
6262
  parameters: {
5348
6263
  query?: never;
5349
6264
  header?: never;
5350
- path?: never;
6265
+ path: {
6266
+ id: string;
6267
+ };
5351
6268
  cookie?: never;
5352
6269
  };
5353
6270
  requestBody?: never;
5354
6271
  responses: {
5355
- /** @description Billing */
5356
- 200: {
6272
+ /** @description Removed */
6273
+ 204: {
5357
6274
  headers: {
5358
6275
  [name: string]: unknown;
5359
6276
  };
5360
- content: {
5361
- "application/json": components["schemas"]["BillingResponse"];
5362
- };
6277
+ content?: never;
5363
6278
  };
5364
6279
  /** @description Unauthorized */
5365
6280
  401: {
@@ -5379,7 +6294,7 @@ export interface operations {
5379
6294
  "application/json": components["schemas"]["Error"];
5380
6295
  };
5381
6296
  };
5382
- /** @description Billing disabled */
6297
+ /** @description No such subscription */
5383
6298
  404: {
5384
6299
  headers: {
5385
6300
  [name: string]: unknown;
@@ -5397,6 +6312,15 @@ export interface operations {
5397
6312
  "application/json": components["schemas"]["NegotiationError"];
5398
6313
  };
5399
6314
  };
6315
+ /** @description Still connected, or named by sets */
6316
+ 409: {
6317
+ headers: {
6318
+ [name: string]: unknown;
6319
+ };
6320
+ content: {
6321
+ "application/json": components["schemas"]["Error"];
6322
+ };
6323
+ };
5400
6324
  /** @description Too Many Requests */
5401
6325
  429: {
5402
6326
  headers: {
@@ -5408,27 +6332,29 @@ export interface operations {
5408
6332
  };
5409
6333
  };
5410
6334
  };
5411
- "FountainWeb.BillingApiController.credits_checkout": {
6335
+ "FountainWeb.ChatGPTSubscriptionController.update": {
5412
6336
  parameters: {
5413
6337
  query?: never;
5414
6338
  header?: never;
5415
- path?: never;
6339
+ path: {
6340
+ id: string;
6341
+ };
5416
6342
  cookie?: never;
5417
6343
  };
5418
- /** @description Pack */
5419
- requestBody: {
6344
+ /** @description New name */
6345
+ requestBody?: {
5420
6346
  content: {
5421
- "application/json": components["schemas"]["CreditsCheckoutRequest"];
6347
+ "application/json": components["schemas"]["ChatGPTSubscriptionUpdateRequest"];
5422
6348
  };
5423
6349
  };
5424
6350
  responses: {
5425
- /** @description Stripe URL */
6351
+ /** @description Subscription */
5426
6352
  200: {
5427
6353
  headers: {
5428
6354
  [name: string]: unknown;
5429
6355
  };
5430
6356
  content: {
5431
- "application/json": components["schemas"]["StripeUrlResponse"];
6357
+ "application/json": components["schemas"]["ChatGPTSubscriptionResponse"];
5432
6358
  };
5433
6359
  };
5434
6360
  /** @description Unauthorized */
@@ -5440,7 +6366,7 @@ export interface operations {
5440
6366
  "application/json": components["schemas"]["Error"];
5441
6367
  };
5442
6368
  };
5443
- /** @description Insufficient scope */
6369
+ /** @description Insufficient scope, or `chatgpt_owner_ineligible` */
5444
6370
  403: {
5445
6371
  headers: {
5446
6372
  [name: string]: unknown;
@@ -5449,7 +6375,7 @@ export interface operations {
5449
6375
  "application/json": components["schemas"]["Error"];
5450
6376
  };
5451
6377
  };
5452
- /** @description Billing disabled */
6378
+ /** @description No such subscription */
5453
6379
  404: {
5454
6380
  headers: {
5455
6381
  [name: string]: unknown;
@@ -5467,7 +6393,7 @@ export interface operations {
5467
6393
  "application/json": components["schemas"]["NegotiationError"];
5468
6394
  };
5469
6395
  };
5470
- /** @description Refused */
6396
+ /** @description Invalid or duplicate name */
5471
6397
  422: {
5472
6398
  headers: {
5473
6399
  [name: string]: unknown;
@@ -5485,8 +6411,66 @@ export interface operations {
5485
6411
  "application/json": components["schemas"]["Error"];
5486
6412
  };
5487
6413
  };
5488
- /** @description Stripe unreachable */
5489
- 502: {
6414
+ };
6415
+ };
6416
+ "FountainWeb.ChatGPTSubscriptionController.disconnect": {
6417
+ parameters: {
6418
+ query?: never;
6419
+ header?: never;
6420
+ path: {
6421
+ id: string;
6422
+ };
6423
+ cookie?: never;
6424
+ };
6425
+ requestBody?: never;
6426
+ responses: {
6427
+ /** @description Subscription */
6428
+ 200: {
6429
+ headers: {
6430
+ [name: string]: unknown;
6431
+ };
6432
+ content: {
6433
+ "application/json": components["schemas"]["ChatGPTSubscriptionResponse"];
6434
+ };
6435
+ };
6436
+ /** @description Unauthorized */
6437
+ 401: {
6438
+ headers: {
6439
+ [name: string]: unknown;
6440
+ };
6441
+ content: {
6442
+ "application/json": components["schemas"]["Error"];
6443
+ };
6444
+ };
6445
+ /** @description Insufficient scope */
6446
+ 403: {
6447
+ headers: {
6448
+ [name: string]: unknown;
6449
+ };
6450
+ content: {
6451
+ "application/json": components["schemas"]["Error"];
6452
+ };
6453
+ };
6454
+ /** @description No such subscription */
6455
+ 404: {
6456
+ headers: {
6457
+ [name: string]: unknown;
6458
+ };
6459
+ content: {
6460
+ "application/json": components["schemas"]["Error"];
6461
+ };
6462
+ };
6463
+ /** @description No acceptable representation */
6464
+ 406: {
6465
+ headers: {
6466
+ [name: string]: unknown;
6467
+ };
6468
+ content: {
6469
+ "application/json": components["schemas"]["NegotiationError"];
6470
+ };
6471
+ };
6472
+ /** @description Too Many Requests */
6473
+ 429: {
5490
6474
  headers: {
5491
6475
  [name: string]: unknown;
5492
6476
  };
@@ -10906,7 +11890,7 @@ export interface operations {
10906
11890
  "application/json": components["schemas"]["Error"];
10907
11891
  };
10908
11892
  };
10909
- /** @description A sandbox token labelling the conversation a resume landed on */
11893
+ /** @description A sandbox token labelling the conversation a resume landed on, or a key below full scope attaching another agent's conversation to a sandbox (guest_attach_requires_full_scope) */
10910
11894
  403: {
10911
11895
  headers: {
10912
11896
  [name: string]: unknown;
@@ -11059,10 +12043,18 @@ export interface operations {
11059
12043
  streams?: string;
11060
12044
  /** @description Return events with an id greater than this. Defaults to 0. */
11061
12045
  after?: number;
11062
- /** @description Page size, 1..1000. Defaults to 100. */
12046
+ /** @description Return events with an id less than this: the previous `order=desc` page's `meta.next_cursor`. Applies in either order; omitted means no upper bound. */
12047
+ before?: number;
12048
+ /** @description `asc` (the default) pages forward from `after`, oldest first. `desc` pages backward from `before` (or from the newest event), and `data` is newest first. */
12049
+ order?: "asc" | "desc";
12050
+ /** @description With `order=desc`, never end a page inside a turn: when the `limit`th event belongs to a turn that began earlier, the page extends past `limit` to that turn's first event, keeping any events interleaved with it, so a client renders complete turns and `before=<meta.next_cursor>` returns only earlier ones. At most 5000 events: a turn larger than that is cut there, with `page.turn_split: true`, and continues on the next page. Turn-less events (the setup before turn 1) page by `limit` alone. Refused with 422 without `order=desc`. Defaults to false. */
12051
+ whole_turns?: boolean;
12052
+ /** @description Page size, 1..1000. Defaults to 100. `whole_turns=true` can return more. */
11063
12053
  limit?: number;
11064
12054
  /** @description Add `blocks` to each event: its `data` parsed server-side into the structured blocks a transcript renders (text, thinking, tool_use, tool_result, init, result, error, raw) — the same parse the web UI uses, so no client re-implements a runtime's dialect. Defaults to false. */
11065
12055
  blocks?: boolean;
12056
+ /** @description With `blocks=true`, fill each turn's `turn`/`started` stage event — whose `blocks` is otherwise always `[]` — with one `prompt` block carrying the prompt that opened that turn. Without it the feed holds only what the runtime wrote, so a client replaying a conversation renders it as a monologue in the agent's voice. No event is added, removed or reordered, so `meta.next_cursor`, `has_more` and the page size are unchanged. A turn whose `origin` is `autonomous` gets no block: nobody typed it. Note that `streams=acp` excludes stage events, and so excludes these prompts with them. Ignored without `blocks=true`. Defaults to false. */
12057
+ prompts?: boolean;
11066
12058
  };
11067
12059
  header?: never;
11068
12060
  path: {
@@ -11380,7 +12372,7 @@ export interface operations {
11380
12372
  "application/json": components["schemas"]["NegotiationError"];
11381
12373
  };
11382
12374
  };
11383
- /** @description Sandbox is being reset */
12375
+ /** @description Sandbox is being reset or deleted */
11384
12376
  409: {
11385
12377
  headers: {
11386
12378
  [name: string]: unknown;
@@ -14044,7 +15036,7 @@ export interface operations {
14044
15036
  "application/json": components["schemas"]["Error"];
14045
15037
  };
14046
15038
  };
14047
- /** @description Sandbox provider unreachable */
15039
+ /** @description Sandbox provider unreachable, or the sandbox is being parked or destroyed (`sandbox_unavailable`, with `Retry-After`) */
14048
15040
  503: {
14049
15041
  headers: {
14050
15042
  [name: string]: unknown;
@@ -14143,7 +15135,7 @@ export interface operations {
14143
15135
  "application/json": components["schemas"]["Error"];
14144
15136
  };
14145
15137
  };
14146
- /** @description Sandbox provider unreachable */
15138
+ /** @description Sandbox provider unreachable, or the sandbox is being parked or destroyed (`sandbox_unavailable`, with `Retry-After`) */
14147
15139
  503: {
14148
15140
  headers: {
14149
15141
  [name: string]: unknown;
@@ -14240,7 +15232,7 @@ export interface operations {
14240
15232
  "application/json": components["schemas"]["Error"];
14241
15233
  };
14242
15234
  };
14243
- /** @description Sandbox provider unreachable */
15235
+ /** @description Sandbox provider unreachable, or the sandbox is being parked or destroyed (`sandbox_unavailable`, with `Retry-After`) */
14244
15236
  503: {
14245
15237
  headers: {
14246
15238
  [name: string]: unknown;
@@ -14339,7 +15331,7 @@ export interface operations {
14339
15331
  "application/json": components["schemas"]["Error"];
14340
15332
  };
14341
15333
  };
14342
- /** @description Sandbox provider unreachable */
15334
+ /** @description Sandbox provider unreachable, or the sandbox is being parked or destroyed (`sandbox_unavailable`, with `Retry-After`) */
14343
15335
  503: {
14344
15336
  headers: {
14345
15337
  [name: string]: unknown;
@@ -16590,6 +17582,88 @@ export interface operations {
16590
17582
  };
16591
17583
  };
16592
17584
  };
17585
+ "FountainWeb.VaultController.copy": {
17586
+ parameters: {
17587
+ query?: never;
17588
+ header?: never;
17589
+ path: {
17590
+ /** @description Source vault. */
17591
+ id: string;
17592
+ };
17593
+ cookie?: never;
17594
+ };
17595
+ /** @description New vault attributes */
17596
+ requestBody?: {
17597
+ content: {
17598
+ "application/json": components["schemas"]["VaultRequest"];
17599
+ };
17600
+ };
17601
+ responses: {
17602
+ /** @description Vault */
17603
+ 201: {
17604
+ headers: {
17605
+ [name: string]: unknown;
17606
+ };
17607
+ content: {
17608
+ "application/json": components["schemas"]["VaultResponse"];
17609
+ };
17610
+ };
17611
+ /** @description Unauthorized */
17612
+ 401: {
17613
+ headers: {
17614
+ [name: string]: unknown;
17615
+ };
17616
+ content: {
17617
+ "application/json": components["schemas"]["Error"];
17618
+ };
17619
+ };
17620
+ /** @description Forbidden */
17621
+ 403: {
17622
+ headers: {
17623
+ [name: string]: unknown;
17624
+ };
17625
+ content: {
17626
+ "application/json": components["schemas"]["Error"];
17627
+ };
17628
+ };
17629
+ /** @description Not found */
17630
+ 404: {
17631
+ headers: {
17632
+ [name: string]: unknown;
17633
+ };
17634
+ content: {
17635
+ "application/json": components["schemas"]["Error"];
17636
+ };
17637
+ };
17638
+ /** @description No acceptable representation */
17639
+ 406: {
17640
+ headers: {
17641
+ [name: string]: unknown;
17642
+ };
17643
+ content: {
17644
+ "application/json": components["schemas"]["NegotiationError"];
17645
+ };
17646
+ };
17647
+ /** @description Validation error */
17648
+ 422: {
17649
+ headers: {
17650
+ [name: string]: unknown;
17651
+ };
17652
+ content: {
17653
+ "application/json": components["schemas"]["Error"];
17654
+ };
17655
+ };
17656
+ /** @description Too Many Requests */
17657
+ 429: {
17658
+ headers: {
17659
+ [name: string]: unknown;
17660
+ };
17661
+ content: {
17662
+ "application/json": components["schemas"]["Error"];
17663
+ };
17664
+ };
17665
+ };
17666
+ };
16593
17667
  "FountainWeb.VaultSecretController.index": {
16594
17668
  parameters: {
16595
17669
  query?: never;