@idapt/browser-app-sdk 0.1.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.
@@ -0,0 +1,1714 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * Typed fetch wrapper used by every API-calling module.
5
+ *
6
+ * Responsibilities:
7
+ * - Build the URL (base + path + query) safely
8
+ * - Serialise JSON bodies or pass through `BodyInit` (multipart)
9
+ * - Attach the bearer token
10
+ * - Honour AbortSignal
11
+ * - Parse JSON responses (respecting Content-Type)
12
+ * - Map non-2xx responses to the typed error hierarchy
13
+ *
14
+ * Everything else in the SDK calls through this single surface so behaviours
15
+ * (retries, 401 handling, etc.) can be evolved in one place.
16
+ */
17
+ /**
18
+ * Query params.
19
+ *
20
+ * Typed as `object` rather than `Record<string, unknown>` because named
21
+ * interfaces (e.g. `ListAgentsQuery`) don't satisfy `Record`'s implicit
22
+ * index signature — a known TS papercut. Any typed object satisfies
23
+ * `object`, so call sites don't need casts. `buildQuery` reads the value
24
+ * via `Object.entries` and skips non-primitives.
25
+ */
26
+ type QueryInput = object;
27
+ interface HttpRequest {
28
+ method: "GET" | "POST" | "PATCH" | "DELETE" | "PUT";
29
+ path: string;
30
+ query?: QueryInput;
31
+ headers?: Record<string, string>;
32
+ body?: unknown;
33
+ bodyRaw?: BodyInit;
34
+ signal?: AbortSignal;
35
+ /**
36
+ * Response decoding mode. Exactly one of these is honoured:
37
+ * - `expectBlob: true` → return `res.blob()` (binary)
38
+ * - `expectJson: false` → return `res.text()` (raw string)
39
+ * - otherwise → parse JSON when Content-Type says so,
40
+ * fall back to text
41
+ */
42
+ expectJson?: boolean;
43
+ expectBlob?: boolean;
44
+ }
45
+ /**
46
+ * How the SDK proves identity on every request:
47
+ *
48
+ * - `"bearer"` (default) — send `Authorization: Bearer <key>`. Used by
49
+ * library mode (explicit `uk_`/`pk_`/`ap_` key) and any caller holding a
50
+ * raw key.
51
+ * - `"cookie"` — send `credentials: "include"` and NO `Authorization`
52
+ * header. Used by the hosted cookie-bootstrap flow: the raw `ap_` key
53
+ * lives only in the httpOnly `__Secure-idapt_app_key` cookie planted on the
54
+ * app subdomain, so the SDK never sees it — the browser attaches it
55
+ * automatically. `key` is unused (and typically empty) in this mode.
56
+ *
57
+ * A third, derived strategy exists when {@link HttpContext.getToken} is set
58
+ * (cookie-mode v1 surfaces): a **minted bearer**. The provider lazily mints an
59
+ * `idapt-api`-audience JWT from the app cookie (via `/api/browser-app/token`),
60
+ * the request sends it as `Authorization: Bearer <jwt>` with NO ambient cookie,
61
+ * and a 401 triggers a single re-mint-and-retry (via {@link HttpContext.onUnauthorized}).
62
+ */
63
+ type AuthMode$1 = "bearer" | "cookie";
64
+ interface HttpContext {
65
+ apiUrl: string;
66
+ key: string;
67
+ /**
68
+ * Auth transport. Defaults to `"bearer"` when omitted (back-compat). In
69
+ * `"cookie"` mode the httpOnly app-key cookie carries auth instead — the
70
+ * request is sent with `credentials: "include"` and no bearer header.
71
+ *
72
+ * Ignored when {@link getToken} is set: a minted-bearer context always
73
+ * attaches the provider's JWT and never sends ambient cookies.
74
+ */
75
+ auth?: AuthMode$1;
76
+ /**
77
+ * Dynamic bearer provider (cookie-mode v1 surfaces). When present it
78
+ * supersedes both `key` and `auth`: every request awaits it for the
79
+ * `Authorization` bearer and omits `credentials: "include"`. Implementations
80
+ * cache the minted token and re-mint on expiry; {@link onUnauthorized} lets
81
+ * the request layer force a re-mint when the server still rejects (401).
82
+ */
83
+ getToken?: () => Promise<string>;
84
+ /**
85
+ * Called once on a 401 from a {@link getToken}-backed request so the provider
86
+ * can invalidate its cached token; the request is then retried a single time
87
+ * with a freshly-minted bearer. No-op / absent ⇒ no retry.
88
+ */
89
+ onUnauthorized?: () => void;
90
+ /**
91
+ * Default headers applied to every request through this context (e.g. a
92
+ * `User-Agent` advertising the caller). Per-request `req.headers` win on key
93
+ * collision; the `Authorization` header is still owned by the auth strategy
94
+ * above (don't set it here). Lets a transport thread one static header set
95
+ * through the context instead of re-specifying it per call. Optional.
96
+ */
97
+ headers?: Record<string, string>;
98
+ /** Custom fetch — used in tests and for polyfills. */
99
+ fetch?: typeof fetch;
100
+ }
101
+ declare function request<T = unknown>(ctx: HttpContext, req: HttpRequest): Promise<T>;
102
+ declare function requestRaw(ctx: HttpContext, req: HttpRequest): Promise<Response>;
103
+ declare function buildUrl(apiUrl: string, path: string, query?: QueryInput): string;
104
+
105
+ declare const userResponseSchema: z.ZodObject<{
106
+ id: z.ZodString;
107
+ email: z.ZodOptional<z.ZodNullable<z.ZodString>>;
108
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
109
+ slug: z.ZodOptional<z.ZodNullable<z.ZodString>>;
110
+ created_at: z.ZodString;
111
+ }, z.core.$strip>;
112
+ type UserResponse = z.infer<typeof userResponseSchema>;
113
+ declare const settingsResponseSchema: z.ZodObject<{
114
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
115
+ slug: z.ZodOptional<z.ZodNullable<z.ZodString>>;
116
+ is_public: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
117
+ is_auto_compact_enabled: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
118
+ consent_analytics: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
119
+ consent_marketing: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
120
+ consent_decided_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
121
+ locale: z.ZodOptional<z.ZodNullable<z.ZodString>>;
122
+ icon: z.ZodOptional<z.ZodNullable<z.ZodString>>;
123
+ display_image: z.ZodOptional<z.ZodNullable<z.ZodString>>;
124
+ github_username: z.ZodOptional<z.ZodNullable<z.ZodString>>;
125
+ }, z.core.$strip>;
126
+ type SettingsResponse = z.infer<typeof settingsResponseSchema>;
127
+ declare const subscriptionResponseSchema: z.ZodObject<{
128
+ plan: z.ZodString;
129
+ is_paid: z.ZodBoolean;
130
+ balance: z.ZodNumber;
131
+ auto_reload_enabled: z.ZodBoolean;
132
+ auto_reload_amount_cents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
133
+ auto_reload_threshold_cents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
134
+ monthly_limit_usd: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
135
+ }, z.core.$strip>;
136
+ type SubscriptionResponse = z.infer<typeof subscriptionResponseSchema>;
137
+ declare const sharedWithMeItemResponseSchema: z.ZodObject<{
138
+ id: z.ZodString;
139
+ resource_type: z.ZodEnum<{
140
+ file: "file";
141
+ agent: "agent";
142
+ workspace: "workspace";
143
+ chat: "chat";
144
+ }>;
145
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
146
+ owner_slug: z.ZodOptional<z.ZodNullable<z.ZodString>>;
147
+ owner_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
148
+ icon: z.ZodOptional<z.ZodNullable<z.ZodString>>;
149
+ extension: z.ZodOptional<z.ZodNullable<z.ZodString>>;
150
+ mime_type: z.ZodOptional<z.ZodNullable<z.ZodString>>;
151
+ permission: z.ZodEnum<{
152
+ read: "read";
153
+ write: "write";
154
+ admin: "admin";
155
+ }>;
156
+ shared_by_actor_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
157
+ workspace_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
158
+ shared_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
159
+ via_public: z.ZodOptional<z.ZodBoolean>;
160
+ }, z.core.$strip>;
161
+ type SharedWithMeItemResponse = z.infer<typeof sharedWithMeItemResponseSchema>;
162
+
163
+ declare const blobObjectResponseSchema: z.ZodObject<{
164
+ namespace: z.ZodString;
165
+ key: z.ZodString;
166
+ content_type: z.ZodString;
167
+ size: z.ZodNumber;
168
+ etag: z.ZodOptional<z.ZodNullable<z.ZodString>>;
169
+ sha256: z.ZodOptional<z.ZodNullable<z.ZodString>>;
170
+ public: z.ZodBoolean;
171
+ resource_id: z.ZodString;
172
+ updated_at: z.ZodString;
173
+ }, z.core.$strip>;
174
+ type BlobObjectResponse = z.infer<typeof blobObjectResponseSchema>;
175
+
176
+ /** `execution_run` record — `transformExecutionRun` output, snake_case. */
177
+ declare const executionRunResponseSchema: z.ZodObject<{
178
+ id: z.ZodString;
179
+ backend: z.ZodString;
180
+ mode: z.ZodOptional<z.ZodNullable<z.ZodString>>;
181
+ status: z.ZodString;
182
+ workspace_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
183
+ file_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
184
+ file_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
185
+ runtime: z.ZodOptional<z.ZodNullable<z.ZodString>>;
186
+ exit_code: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
187
+ stdout: z.ZodOptional<z.ZodNullable<z.ZodString>>;
188
+ stderr: z.ZodOptional<z.ZodNullable<z.ZodString>>;
189
+ duration_ms: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
190
+ timed_out: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
191
+ timeout_seconds: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
192
+ trigger_type: z.ZodOptional<z.ZodNullable<z.ZodString>>;
193
+ error_message: z.ZodOptional<z.ZodNullable<z.ZodString>>;
194
+ created_at: z.ZodString;
195
+ started_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
196
+ completed_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
197
+ output_files: z.ZodOptional<z.ZodArray<z.ZodObject<{
198
+ file_id: z.ZodString;
199
+ path: z.ZodString;
200
+ }, z.core.$strip>>>;
201
+ }, z.core.$strip>;
202
+ type ExecutionRunResponse = z.infer<typeof executionRunResponseSchema>;
203
+
204
+ declare const computerResponseSchema: z.ZodObject<{
205
+ id: z.ZodString;
206
+ name: z.ZodString;
207
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
208
+ icon: z.ZodOptional<z.ZodNullable<z.ZodString>>;
209
+ type: z.ZodEnum<{
210
+ remote: "remote";
211
+ managed: "managed";
212
+ }>;
213
+ hostname: z.ZodOptional<z.ZodNullable<z.ZodString>>;
214
+ port: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
215
+ logging_level: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
216
+ standard: "standard";
217
+ full: "full";
218
+ minimal: "minimal";
219
+ }>>>;
220
+ workspace_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
221
+ state: z.ZodNullable<z.ZodEnum<{
222
+ unprovisioned: "unprovisioned";
223
+ provisioning: "provisioning";
224
+ running: "running";
225
+ hibernating: "hibernating";
226
+ hibernated: "hibernated";
227
+ waking: "waking";
228
+ stopping: "stopping";
229
+ stopped: "stopped";
230
+ terminating: "terminating";
231
+ terminated: "terminated";
232
+ }>>;
233
+ archived_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
234
+ created_at: z.ZodString;
235
+ updated_at: z.ZodString;
236
+ }, z.core.$strip>;
237
+ type ComputerResponse = z.infer<typeof computerResponseSchema>;
238
+ declare const computerUserResponseSchema: z.ZodObject<{
239
+ username: z.ZodString;
240
+ uid: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
241
+ groups: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
242
+ shell: z.ZodOptional<z.ZodNullable<z.ZodString>>;
243
+ home: z.ZodOptional<z.ZodNullable<z.ZodString>>;
244
+ has_credential: z.ZodOptional<z.ZodBoolean>;
245
+ }, z.core.$strip>;
246
+ type ComputerUserResponse = z.infer<typeof computerUserResponseSchema>;
247
+ declare const computerEnvVarResponseSchema: z.ZodObject<{
248
+ name: z.ZodString;
249
+ username: z.ZodString;
250
+ file_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
251
+ created_at: z.ZodString;
252
+ }, z.core.$strip>;
253
+ type ComputerEnvVarResponse = z.infer<typeof computerEnvVarResponseSchema>;
254
+ declare const computerPortResponseSchema: z.ZodObject<{
255
+ port: z.ZodNumber;
256
+ protocol: z.ZodString;
257
+ process: z.ZodOptional<z.ZodNullable<z.ZodString>>;
258
+ hidden: z.ZodOptional<z.ZodBoolean>;
259
+ display_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
260
+ icon: z.ZodOptional<z.ZodNullable<z.ZodString>>;
261
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
262
+ }, z.core.$strip>;
263
+ type ComputerPortResponse = z.infer<typeof computerPortResponseSchema>;
264
+
265
+ declare const agentResponseSchema: z.ZodObject<{
266
+ id: z.ZodString;
267
+ name: z.ZodString;
268
+ icon: z.ZodOptional<z.ZodNullable<z.ZodString>>;
269
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
270
+ system_prompt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
271
+ workspace_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
272
+ type: z.ZodOptional<z.ZodNullable<z.ZodString>>;
273
+ permissions: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>>;
274
+ compaction_preset: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
275
+ minimal: "minimal";
276
+ normal: "normal";
277
+ detailed: "detailed";
278
+ }>>>;
279
+ compaction_summary_percent: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
280
+ compaction_summary_max_tokens: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
281
+ compaction_preserved_percent: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
282
+ compaction_preserved_max_tokens: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
283
+ compaction_msg_percent: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
284
+ compaction_msg_max_tokens: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
285
+ compaction_trigger_type: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
286
+ percent: "percent";
287
+ tokens: "tokens";
288
+ }>>>;
289
+ compaction_trigger_value: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
290
+ source_template_resource_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
291
+ memory_folder: z.ZodOptional<z.ZodNullable<z.ZodString>>;
292
+ default_model_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
293
+ default_reasoning_effort: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
294
+ default_auto_cost_level: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
295
+ default_cost_budget_limit_usd: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
296
+ is_trashed: z.ZodOptional<z.ZodBoolean>;
297
+ trashed_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
298
+ archived_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
299
+ created_at: z.ZodString;
300
+ updated_at: z.ZodString;
301
+ }, z.core.$strip>;
302
+ type AgentResponse = z.infer<typeof agentResponseSchema>;
303
+ declare const chatResponseSchema: z.ZodObject<{
304
+ id: z.ZodString;
305
+ title: z.ZodString;
306
+ icon: z.ZodOptional<z.ZodNullable<z.ZodString>>;
307
+ agent_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
308
+ workspace_id: z.ZodString;
309
+ default_model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
310
+ is_trashed: z.ZodOptional<z.ZodBoolean>;
311
+ archived_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
312
+ created_at: z.ZodString;
313
+ updated_at: z.ZodString;
314
+ }, z.core.$strip>;
315
+ type ChatResponse = z.infer<typeof chatResponseSchema>;
316
+ declare const messageResponseSchema: z.ZodObject<{
317
+ id: z.ZodString;
318
+ role: z.ZodEnum<{
319
+ user: "user";
320
+ assistant: "assistant";
321
+ tool: "tool";
322
+ }>;
323
+ content: z.ZodString;
324
+ model_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
325
+ created_at: z.ZodString;
326
+ }, z.core.$strip>;
327
+ type MessageResponse = z.infer<typeof messageResponseSchema>;
328
+ declare const workspaceResponseSchema: z.ZodObject<{
329
+ id: z.ZodString;
330
+ name: z.ZodString;
331
+ slug: z.ZodString;
332
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
333
+ icon: z.ZodOptional<z.ZodNullable<z.ZodString>>;
334
+ is_personal: z.ZodBoolean;
335
+ public_access: z.ZodOptional<z.ZodNullable<z.ZodString>>;
336
+ archived_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
337
+ created_at: z.ZodString;
338
+ updated_at: z.ZodString;
339
+ }, z.core.$strip>;
340
+ type WorkspaceResponse = z.infer<typeof workspaceResponseSchema>;
341
+ declare const workspaceMemberResponseSchema: z.ZodObject<{
342
+ id: z.ZodString;
343
+ actor_id: z.ZodString;
344
+ slug: z.ZodOptional<z.ZodNullable<z.ZodString>>;
345
+ display_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
346
+ display_image: z.ZodOptional<z.ZodNullable<z.ZodString>>;
347
+ role: z.ZodEnum<{
348
+ custom: "custom";
349
+ admin: "admin";
350
+ owner: "owner";
351
+ editor: "editor";
352
+ viewer: "viewer";
353
+ }>;
354
+ created_at: z.ZodString;
355
+ }, z.core.$strip>;
356
+ type WorkspaceMemberResponse = z.infer<typeof workspaceMemberResponseSchema>;
357
+ declare const triggerResponseSchema: z.ZodObject<{
358
+ id: z.ZodString;
359
+ name: z.ZodString;
360
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
361
+ enabled: z.ZodBoolean;
362
+ workspace_id: z.ZodString;
363
+ trigger_type: z.ZodString;
364
+ action_type: z.ZodString;
365
+ cron_expression: z.ZodOptional<z.ZodNullable<z.ZodString>>;
366
+ cron_timezone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
367
+ agent_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
368
+ prompt_template: z.ZodOptional<z.ZodNullable<z.ZodString>>;
369
+ initial_context: z.ZodOptional<z.ZodNullable<z.ZodString>>;
370
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
371
+ reasoning_level: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
372
+ auto_cost_level: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
373
+ cost_budget_limit_usd: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
374
+ web_search_enabled: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
375
+ memory_enabled: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
376
+ subagent_enabled: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
377
+ delegate_mode: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
378
+ auto_compact_enabled: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
379
+ compaction_preset: z.ZodOptional<z.ZodNullable<z.ZodString>>;
380
+ pasted_texts: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodUnknown>>>;
381
+ active_skills: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
382
+ file_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
383
+ runtime: z.ZodOptional<z.ZodNullable<z.ZodString>>;
384
+ timeout_seconds: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
385
+ env: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodString>>>;
386
+ working_dir_folder_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
387
+ next_run_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
388
+ last_fired_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
389
+ archived_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
390
+ created_at: z.ZodString;
391
+ updated_at: z.ZodString;
392
+ }, z.core.$strip>;
393
+ type TriggerResponse = z.infer<typeof triggerResponseSchema>;
394
+ /** Trigger + its one-time plaintext webhook secret (create / rotate-secret). */
395
+ declare const triggerWithSecretResponseSchema: z.ZodObject<{
396
+ id: z.ZodString;
397
+ name: z.ZodString;
398
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
399
+ enabled: z.ZodBoolean;
400
+ workspace_id: z.ZodString;
401
+ trigger_type: z.ZodString;
402
+ action_type: z.ZodString;
403
+ cron_expression: z.ZodOptional<z.ZodNullable<z.ZodString>>;
404
+ cron_timezone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
405
+ agent_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
406
+ prompt_template: z.ZodOptional<z.ZodNullable<z.ZodString>>;
407
+ initial_context: z.ZodOptional<z.ZodNullable<z.ZodString>>;
408
+ model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
409
+ reasoning_level: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
410
+ auto_cost_level: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
411
+ cost_budget_limit_usd: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
412
+ web_search_enabled: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
413
+ memory_enabled: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
414
+ subagent_enabled: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
415
+ delegate_mode: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
416
+ auto_compact_enabled: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
417
+ compaction_preset: z.ZodOptional<z.ZodNullable<z.ZodString>>;
418
+ pasted_texts: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodUnknown>>>;
419
+ active_skills: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
420
+ file_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
421
+ runtime: z.ZodOptional<z.ZodNullable<z.ZodString>>;
422
+ timeout_seconds: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
423
+ env: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodString>>>;
424
+ working_dir_folder_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
425
+ next_run_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
426
+ last_fired_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
427
+ archived_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
428
+ created_at: z.ZodString;
429
+ updated_at: z.ZodString;
430
+ secret: z.ZodString;
431
+ }, z.core.$strip>;
432
+ type TriggerWithSecretResponse = z.infer<typeof triggerWithSecretResponseSchema>;
433
+ declare const triggerRunResponseSchema: z.ZodObject<{
434
+ id: z.ZodString;
435
+ trigger_id: z.ZodString;
436
+ success: z.ZodBoolean;
437
+ error: z.ZodOptional<z.ZodNullable<z.ZodString>>;
438
+ chat_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
439
+ execution_run_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
440
+ fired_at: z.ZodString;
441
+ }, z.core.$strip>;
442
+ type TriggerRunResponse = z.infer<typeof triggerRunResponseSchema>;
443
+ declare const triggerCostStatsResponseSchema: z.ZodObject<{
444
+ runs_with_cost: z.ZodNumber;
445
+ total_cost_usd: z.ZodNumber;
446
+ today_cost_usd: z.ZodNumber;
447
+ this_month_cost_usd: z.ZodNumber;
448
+ last24h_cost_usd: z.ZodNumber;
449
+ last7d_cost_usd: z.ZodNumber;
450
+ first_fired_at: z.ZodNullable<z.ZodString>;
451
+ }, z.core.$strip>;
452
+ type TriggerCostStatsResponse = z.infer<typeof triggerCostStatsResponseSchema>;
453
+ declare const notificationResponseSchema: z.ZodObject<{
454
+ id: z.ZodString;
455
+ type: z.ZodString;
456
+ subtype: z.ZodOptional<z.ZodNullable<z.ZodString>>;
457
+ title: z.ZodString;
458
+ message: z.ZodOptional<z.ZodNullable<z.ZodString>>;
459
+ data: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
460
+ group_key: z.ZodOptional<z.ZodNullable<z.ZodString>>;
461
+ workspace_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
462
+ sender_kind: z.ZodOptional<z.ZodNullable<z.ZodString>>;
463
+ sender_actor_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
464
+ sender_agent_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
465
+ audience: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>>;
466
+ is_read: z.ZodBoolean;
467
+ read_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
468
+ archived_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
469
+ created_at: z.ZodString;
470
+ }, z.core.$strip>;
471
+ type NotificationResponse = z.infer<typeof notificationResponseSchema>;
472
+ declare const notificationConfigResponseSchema: z.ZodObject<{
473
+ toasts_enabled: z.ZodOptional<z.ZodBoolean>;
474
+ sound_enabled: z.ZodOptional<z.ZodBoolean>;
475
+ quiet_hours_enabled: z.ZodOptional<z.ZodBoolean>;
476
+ quiet_hours_start: z.ZodOptional<z.ZodNullable<z.ZodString>>;
477
+ quiet_hours_end: z.ZodOptional<z.ZodNullable<z.ZodString>>;
478
+ quiet_hours_timezone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
479
+ digest_frequency: z.ZodOptional<z.ZodNullable<z.ZodString>>;
480
+ nudge_shown_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
481
+ }, z.core.$catchall<z.ZodUnknown>>;
482
+ type NotificationConfigResponse = z.infer<typeof notificationConfigResponseSchema>;
483
+ declare const notificationPreferenceResponseSchema: z.ZodObject<{
484
+ type: z.ZodString;
485
+ subtype: z.ZodOptional<z.ZodNullable<z.ZodString>>;
486
+ channel: z.ZodEnum<{
487
+ email: "email";
488
+ in_app: "in_app";
489
+ web_push: "web_push";
490
+ }>;
491
+ enabled: z.ZodBoolean;
492
+ is_default: z.ZodOptional<z.ZodBoolean>;
493
+ }, z.core.$strip>;
494
+ type NotificationPreferenceResponse = z.infer<typeof notificationPreferenceResponseSchema>;
495
+ declare const shareResponseSchema: z.ZodObject<{
496
+ resource_type: z.ZodEnum<{
497
+ file: "file";
498
+ agent: "agent";
499
+ workspace: "workspace";
500
+ chat: "chat";
501
+ }>;
502
+ resource_id: z.ZodString;
503
+ grantee_actor_id: z.ZodString;
504
+ permission: z.ZodEnum<{
505
+ read: "read";
506
+ write: "write";
507
+ admin: "admin";
508
+ }>;
509
+ shared_by_actor_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
510
+ shared_at: z.ZodString;
511
+ }, z.core.$strip>;
512
+ type ShareResponse = z.infer<typeof shareResponseSchema>;
513
+
514
+ declare const datastoreEntryResponseSchema: z.ZodObject<{
515
+ namespace: z.ZodString;
516
+ key: z.ZodString;
517
+ value: z.ZodNullable<z.ZodUnknown>;
518
+ size: z.ZodNumber;
519
+ expires_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
520
+ updated_at: z.ZodString;
521
+ }, z.core.$strip>;
522
+ type DatastoreEntryResponse = z.infer<typeof datastoreEntryResponseSchema>;
523
+
524
+ /**
525
+ * A file resource (`transformFile` → snake_case). `id` is the resourceId.
526
+ * Nullable-and-optional (`.nullish()`) where the SDK marks the field optional,
527
+ * so `z.infer<typeof fileResponseSchema>` is wire-identical to the SDK `File`
528
+ * type it now sources (a present `null` always validates).
529
+ */
530
+ declare const fileResponseSchema: z.ZodObject<{
531
+ id: z.ZodString;
532
+ name: z.ZodString;
533
+ mime_type: z.ZodOptional<z.ZodNullable<z.ZodString>>;
534
+ file_size: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
535
+ version: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
536
+ content_hash: z.ZodOptional<z.ZodNullable<z.ZodString>>;
537
+ parent_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
538
+ workspace_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
539
+ lock_expires_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
540
+ is_locked: z.ZodOptional<z.ZodBoolean>;
541
+ lock_reason: z.ZodOptional<z.ZodNullable<z.ZodString>>;
542
+ created_at: z.ZodOptional<z.ZodString>;
543
+ updated_at: z.ZodOptional<z.ZodString>;
544
+ }, z.core.$strip>;
545
+ type FileResponse = z.infer<typeof fileResponseSchema>;
546
+ /** Stripped record from a multipart upload (`transformFileUpload`) — no timestamps. */
547
+ declare const fileUploadResponseSchema: z.ZodObject<{
548
+ id: z.ZodString;
549
+ name: z.ZodString;
550
+ mime_type: z.ZodOptional<z.ZodNullable<z.ZodString>>;
551
+ file_size: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
552
+ }, z.core.$strip>;
553
+ type FileUploadResponse = z.infer<typeof fileUploadResponseSchema>;
554
+
555
+ /**
556
+ * A hub/store item from `GET /hub/search` (snake_case wire). `id` is the item's
557
+ * resourceId (non-null). The catalog has heterogeneous payloads per type
558
+ * (skills carry version/license, agents carry icons/prompts, computer templates
559
+ * carry sizing), so the common fields are typed and the rest stays open via
560
+ * `.catchall`. Component id `StoreItem` (the SDK `StoreItem` type infers this).
561
+ */
562
+ declare const storeItemResponseSchema: z.ZodObject<{
563
+ id: z.ZodString;
564
+ type: z.ZodOptional<z.ZodNullable<z.ZodString>>;
565
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
566
+ display_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
567
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
568
+ icon: z.ZodOptional<z.ZodNullable<z.ZodString>>;
569
+ display_image: z.ZodOptional<z.ZodNullable<z.ZodString>>;
570
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
571
+ license: z.ZodOptional<z.ZodNullable<z.ZodString>>;
572
+ author_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
573
+ author_slug: z.ZodOptional<z.ZodNullable<z.ZodString>>;
574
+ source: z.ZodOptional<z.ZodNullable<z.ZodString>>;
575
+ external_url: z.ZodOptional<z.ZodNullable<z.ZodString>>;
576
+ install_count: z.ZodOptional<z.ZodNumber>;
577
+ popularity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
578
+ preview: z.ZodOptional<z.ZodNullable<z.ZodString>>;
579
+ metadata: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
580
+ created_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
581
+ updated_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
582
+ }, z.core.$catchall<z.ZodUnknown>>;
583
+ type StoreItemResponse = z.infer<typeof storeItemResponseSchema>;
584
+
585
+ declare const apiKeyResponseSchema: z.ZodObject<{
586
+ id: z.ZodString;
587
+ name: z.ZodString;
588
+ prefix: z.ZodOptional<z.ZodNullable<z.ZodString>>;
589
+ key_preview: z.ZodOptional<z.ZodNullable<z.ZodString>>;
590
+ permissions: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
591
+ resource: z.ZodString;
592
+ scope: z.ZodOptional<z.ZodNullable<z.ZodString>>;
593
+ access: z.ZodOptional<z.ZodEnum<{
594
+ read: "read";
595
+ write: "write";
596
+ admin: "admin";
597
+ }>>;
598
+ }, z.core.$strip>>>>;
599
+ enabled: z.ZodBoolean;
600
+ expires_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
601
+ last_used_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
602
+ created_at: z.ZodString;
603
+ key: z.ZodOptional<z.ZodString>;
604
+ }, z.core.$strip>;
605
+ type ApiKeyResponse = z.infer<typeof apiKeyResponseSchema>;
606
+
607
+ /** Secret metadata — never carries the plaintext value. */
608
+ declare const secretResponseSchema: z.ZodObject<{
609
+ id: z.ZodString;
610
+ name: z.ZodString;
611
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
612
+ workspace_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
613
+ type: z.ZodOptional<z.ZodNullable<z.ZodString>>;
614
+ value_preview: z.ZodOptional<z.ZodNullable<z.ZodString>>;
615
+ expires_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
616
+ last_used_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
617
+ created_at: z.ZodString;
618
+ updated_at: z.ZodString;
619
+ }, z.core.$strip>;
620
+ type SecretResponse = z.infer<typeof secretResponseSchema>;
621
+ /** Reveal response — the metadata PLUS the decrypted plaintext value. */
622
+ declare const secretWithValueResponseSchema: z.ZodObject<{
623
+ id: z.ZodString;
624
+ name: z.ZodString;
625
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
626
+ workspace_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
627
+ type: z.ZodOptional<z.ZodNullable<z.ZodString>>;
628
+ value_preview: z.ZodOptional<z.ZodNullable<z.ZodString>>;
629
+ expires_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
630
+ last_used_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
631
+ created_at: z.ZodString;
632
+ updated_at: z.ZodString;
633
+ value: z.ZodString;
634
+ }, z.core.$strip>;
635
+ type SecretWithValueResponse = z.infer<typeof secretWithValueResponseSchema>;
636
+
637
+ declare const tableCollectionResponseSchema: z.ZodObject<{
638
+ id: z.ZodString;
639
+ name: z.ZodString;
640
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
641
+ icon: z.ZodOptional<z.ZodNullable<z.ZodString>>;
642
+ schema: z.ZodOptional<z.ZodNullable<z.ZodObject<{
643
+ fields: z.ZodArray<z.ZodObject<{
644
+ key: z.ZodString;
645
+ name: z.ZodString;
646
+ type: z.ZodString;
647
+ options: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
648
+ required: z.ZodOptional<z.ZodBoolean>;
649
+ default: z.ZodOptional<z.ZodUnknown>;
650
+ }, z.core.$strip>>;
651
+ }, z.core.$strip>>>;
652
+ workspace_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
653
+ created_at: z.ZodString;
654
+ updated_at: z.ZodString;
655
+ }, z.core.$strip>;
656
+ type TableCollectionResponse = z.infer<typeof tableCollectionResponseSchema>;
657
+ declare const tableRecordResponseSchema: z.ZodObject<{
658
+ id: z.ZodString;
659
+ collection_id: z.ZodString;
660
+ values: z.ZodRecord<z.ZodString, z.ZodUnknown>;
661
+ created_at: z.ZodString;
662
+ updated_at: z.ZodString;
663
+ }, z.core.$strip>;
664
+ type TableRecordResponse = z.infer<typeof tableRecordResponseSchema>;
665
+
666
+ /**
667
+ * Public type surface for @idapt/sdk.
668
+ *
669
+ * Types are hand-written against the **actual** v1 response shapes. When the
670
+ * v1 API changes, update this file and the unit tests — the tests exercise
671
+ * every wire format through mocked fetch responses.
672
+ *
673
+ * ## Envelope conventions (verified against lib/api/v1/response.ts)
674
+ *
675
+ * Single: { data: T }
676
+ * List: { data: T[], pagination: { has_more, next_cursor } }
677
+ * Deleted: { deleted: true, id }
678
+ * Error: { error: { type, message, code? } }
679
+ *
680
+ * Pagination lives in a nested object so the envelope can grow without a
681
+ * breaking change — do NOT flatten `has_more` up. Paging is cursor-based
682
+ * (`limit` capped at 100, opaque `cursor` token) — there is no offset and
683
+ * no total count (Stripe/OpenAI-style).
684
+ *
685
+ * The error envelope splits the old flat `code` into `type` (the coarse
686
+ * category clients branch on) + an optional finer `code` sub-code — see
687
+ * `errors.ts` for the typed hierarchy that wraps it.
688
+ */
689
+
690
+ /**
691
+ * Pagination metadata on every list envelope. Cursor-based: callers page
692
+ * with `limit` (max 100) + an opaque `cursor`. `has_more` flags whether
693
+ * another page exists; `next_cursor` is the token to pass as the next
694
+ * request's `?cursor=` (it is `null` when `has_more` is false).
695
+ *
696
+ * The cursor is OPAQUE — echo `next_cursor` back as `cursor`, never parse
697
+ * it. Bounded lists (static catalogs, workspace members, …) still carry a
698
+ * `pagination` block, but their `next_cursor` is always `null`. There is
699
+ * no total count (Stripe/OpenAI-style).
700
+ */
701
+ interface Pagination {
702
+ has_more: boolean;
703
+ /** Opaque token for the next page, or `null` when `has_more` is false. */
704
+ next_cursor: string | null;
705
+ }
706
+ interface ListEnvelope<T> {
707
+ data: T[];
708
+ pagination: Pagination;
709
+ }
710
+ interface SingleEnvelope<T> {
711
+ data: T;
712
+ }
713
+ interface DeletedResponse {
714
+ deleted: true;
715
+ id: string;
716
+ }
717
+ /**
718
+ * A file resource as returned by the v1 API (`GET /files/:id`, lists).
719
+ *
720
+ * Field names follow the API's snake_case convention. Many columns are
721
+ * nullable on the server — tolerate that in consumer code. `id` is the
722
+ * file's resourceId — there is no separate `resource_id` field.
723
+ */
724
+ type File = FileResponse;
725
+ type FileList = ListEnvelope<File>;
726
+ /**
727
+ * Stripped-down file record returned by `POST /files` (multipart upload).
728
+ * No timestamps. `id` is the file's resourceId.
729
+ */
730
+ type FileUploadResult = FileUploadResponse;
731
+ /** Current-user payload from `GET /me`. */
732
+ /** Current-user payload from `GET /me`. Sourced from the account v1 contract. */
733
+ type User = UserResponse;
734
+ /** `GET /me/usage?view=summary`. */
735
+ interface UsageSummary {
736
+ storage: {
737
+ used_bytes: number;
738
+ capacity_bytes: number;
739
+ snapshot_bytes: number;
740
+ };
741
+ }
742
+ /**
743
+ * `GET /me/usage?view=history` entry — one metered LLM / image / audio
744
+ * call. There is no `id` on the wire: usage rows are an append-only log,
745
+ * keyed by `(actor, created_at)`, not addressable resources.
746
+ */
747
+ interface UsageRecord {
748
+ call_type: string;
749
+ model_id?: string | null;
750
+ /** Workspace the call was billed against. Null for non-workspace calls. */
751
+ workspace_id?: string | null;
752
+ input_tokens?: number | null;
753
+ output_tokens?: number | null;
754
+ /** Reasoning/thinking tokens, when the model reports them separately. */
755
+ reasoning_tokens?: number | null;
756
+ /** Prompt tokens served from the provider's cache. */
757
+ cached_tokens?: number | null;
758
+ cost_usd?: number | null;
759
+ /** Wall-clock duration of the call. */
760
+ duration_seconds?: number | null;
761
+ /** Provider finish reason (`stop`, `length`, `tool_calls`, …). */
762
+ finish_reason?: string | null;
763
+ /** True when the call was cancelled before completion. */
764
+ cancelled?: boolean | null;
765
+ created_at: string;
766
+ [k: string]: unknown;
767
+ }
768
+ /** Agent resource. Sourced from the crud v1 contract. */
769
+ type Agent = AgentResponse;
770
+ /** Chat resource. Sourced from the crud v1 contract. */
771
+ type Chat = ChatResponse;
772
+ /** Chat message. Sourced from the crud v1 contract. */
773
+ type Message = MessageResponse;
774
+ /**
775
+ * Per-call-type cost + token breakdown inside `ChatCost.by_call_type`.
776
+ * Each key (`chat`, `image`, `web_search`, …) maps to one of these.
777
+ */
778
+ interface ChatCostByCallType {
779
+ cost_usd: number;
780
+ count: number;
781
+ input_tokens: number;
782
+ output_tokens: number;
783
+ cached_tokens: number;
784
+ input_cost_usd: number;
785
+ output_cost_usd: number;
786
+ cached_cost_usd: number;
787
+ }
788
+ interface ChatCost {
789
+ total_cost_usd: number;
790
+ total_input_tokens: number;
791
+ total_output_tokens: number;
792
+ total_cached_tokens: number;
793
+ by_call_type?: Record<string, ChatCostByCallType> | null;
794
+ cost_budget_limit_usd?: number | null;
795
+ cost_budget_mode?: string | null;
796
+ cost_budget_spent_usd?: number | null;
797
+ }
798
+ interface MessageCostEntry {
799
+ cost_usd: number;
800
+ input_tokens: number;
801
+ output_tokens: number;
802
+ cached_tokens: number;
803
+ call_type: string;
804
+ is_estimated: boolean;
805
+ duration_seconds: number;
806
+ }
807
+ interface RunCostMetrics {
808
+ total_cost_usd: number;
809
+ total_input_tokens: number;
810
+ total_output_tokens: number;
811
+ total_cached_tokens: number;
812
+ duration_seconds: number;
813
+ state: string;
814
+ }
815
+ interface MessageCosts {
816
+ by_message: Record<string, MessageCostEntry[]>;
817
+ by_run: Record<string, RunCostMetrics>;
818
+ }
819
+ interface ChatStopResult extends Chat {
820
+ run_active: boolean;
821
+ }
822
+ /** Lifecycle state of an agent run row (`GET /chats/:id/runs`). */
823
+ type AgentRunState = "generating" | "streaming" | "completed" | "failed" | "stopped" | "paused";
824
+ interface AgentRun {
825
+ id: string;
826
+ state: AgentRunState;
827
+ model_id?: string | null;
828
+ total_input_tokens?: number | null;
829
+ total_output_tokens?: number | null;
830
+ total_cost_usd?: number | null;
831
+ duration_seconds?: number | null;
832
+ error?: string | null;
833
+ created_at: string;
834
+ completed_at?: string | null;
835
+ }
836
+ /**
837
+ * Response shape of `POST /chats/:id/messages` (201, a `oneOf`).
838
+ * - completed: `{ status, chat_id, model_id, user_message_id, message }`
839
+ * - pending: `{ status, pending_token, chat_id }`
840
+ *
841
+ * `pending_token` is an opaque workflow handle (NOT a resourceId).
842
+ */
843
+ type SendMessageResult = {
844
+ status: "completed";
845
+ chat_id: string;
846
+ model_id: string | null;
847
+ user_message_id: string;
848
+ message: Message;
849
+ } | {
850
+ status: "pending";
851
+ pending_token: string;
852
+ chat_id: string;
853
+ };
854
+ /**
855
+ * Lifecycle status of an execution run. `interrupted` lands when a run is
856
+ * cancelled via `POST /code-runs/:id/interrupt`.
857
+ */
858
+ type ExecutionRunStatus = "pending" | "running" | "completed" | "failed" | "timed_out" | "interrupted";
859
+ /** Where an execution run executes — sandboxed Lambda or a paired computer. */
860
+ type ExecutionBackend = "computer" | "lambda";
861
+ /**
862
+ * An execution-run row. Returned by `POST /code-runs`, `POST /files/:id/run`,
863
+ * `GET /code-runs` and `GET /code-runs/:id` — code execution always yields
864
+ * this single shape (there is no separate stripped run-summary type).
865
+ */
866
+ type ExecutionRun = ExecutionRunResponse;
867
+ type TriggerType = "webhook" | "schedule" | "manual" | string;
868
+ type TriggerActionType = "run_code" | "run_chat" | string;
869
+ /**
870
+ * A trigger resource. This is a flat object — every scheduling field
871
+ * and every action field lives directly on the row, with no nested
872
+ * `trigger_config` / `action_config` objects.
873
+ *
874
+ * `agent_id`, `file_id` and `working_dir_folder_id` are resourceIds.
875
+ */
876
+ /** A trigger resource (flat). Sourced from the crud v1 contract. */
877
+ type Trigger = TriggerResponse;
878
+ /**
879
+ * A trigger plus its one-time webhook `secret`. Returned by
880
+ * `POST /v1/triggers` (webhook creation) and `POST /v1/triggers/:id/rotate-secret`.
881
+ * The plaintext `secret` is only ever echoed on these two responses.
882
+ */
883
+ /** Trigger + one-time webhook secret. Sourced from the crud v1 contract. */
884
+ type TriggerWithSecret = TriggerWithSecretResponse;
885
+ /** A trigger run record. Sourced from the crud v1 contract. */
886
+ type TriggerRun = TriggerRunResponse;
887
+ /** Trigger cost aggregates. Sourced from the crud v1 contract. */
888
+ type TriggerCostStats = TriggerCostStatsResponse;
889
+ /**
890
+ * Create-trigger request body — flat, mirrors the `Trigger` shape. The
891
+ * required fields depend on `trigger_type` / `action_type` (a schedule
892
+ * trigger needs `cron_expression`; a `run_code` action needs `file_id`;
893
+ * a `run_chat` action needs `prompt_template` or `agent_id`). The server
894
+ * validates the combination.
895
+ */
896
+ interface CreateTriggerInput {
897
+ name: string;
898
+ description?: string;
899
+ enabled?: boolean;
900
+ trigger_type: TriggerType;
901
+ action_type: TriggerActionType;
902
+ cron_expression?: string;
903
+ cron_timezone?: string;
904
+ agent_id?: string;
905
+ prompt_template?: string;
906
+ initial_context?: string;
907
+ model?: string;
908
+ reasoning_level?: number;
909
+ auto_cost_level?: number;
910
+ cost_budget_limit_usd?: number;
911
+ web_search_enabled?: boolean;
912
+ memory_enabled?: boolean;
913
+ subagent_enabled?: boolean;
914
+ delegate_mode?: boolean;
915
+ auto_compact_enabled?: boolean;
916
+ compaction_preset?: string;
917
+ pasted_texts?: unknown[];
918
+ active_skills?: string[];
919
+ file_id?: string;
920
+ runtime?: string;
921
+ timeout_seconds?: number;
922
+ env?: Record<string, string>;
923
+ working_dir_folder_id?: string;
924
+ }
925
+ /** Update-trigger request body — every create field plus `agent_id` is patchable. */
926
+ type UpdateTriggerInput = Partial<CreateTriggerInput>;
927
+ /**
928
+ * Modality bucket a model belongs to. Every model row across `/v1/models`,
929
+ * `/v1/audio/models` and `/v1/images/models` carries this discriminant.
930
+ */
931
+ type ModelModality = "chat" | "audio" | "image";
932
+ /**
933
+ * Fields shared by every model row regardless of modality. Modality-specific
934
+ * shapes (`LLMModel`, `AudioModel`, `ImageModel`) extend this.
935
+ *
936
+ * Every model row carries `pricing` and `capabilities` as nested
937
+ * objects. `pricing` is always the user-facing (post-markup) price.
938
+ */
939
+ interface ModelBase {
940
+ id: string;
941
+ /** Human-readable label. */
942
+ display_name: string;
943
+ provider: string;
944
+ modality: ModelModality;
945
+ }
946
+ /** Chat-model pricing block — null when the model is free / unpriced. */
947
+ interface LLMModelPricing {
948
+ input_per_million: number;
949
+ output_per_million: number;
950
+ }
951
+ /** Chat-model capability block (always an object, never an array). */
952
+ interface LLMModelCapabilities {
953
+ context_length: number;
954
+ max_output_tokens: number;
955
+ image_input: boolean;
956
+ }
957
+ /** A chat/LLM model from `GET /v1/models` (`modality: "chat"`). */
958
+ interface LLMModel extends ModelBase {
959
+ modality: "chat";
960
+ pricing: LLMModelPricing | null;
961
+ capabilities: LLMModelCapabilities;
962
+ }
963
+ type ProviderEndpointKind = "openai" | "anthropic" | "openai_compatible";
964
+ type ProviderEndpointProviderKey = "openai" | "anthropic" | "openrouter" | "gemini" | "xai" | "deepseek" | "replicate" | "minimax" | "custom_openai_compatible" | "ollama";
965
+ type ProviderEndpointConnectionType = "managed" | "custom" | "local";
966
+ type ProviderEndpointModality = "text-completion" | "image-generation" | "speech-synthesis" | "speech-recognition" | "embedding";
967
+ type ProviderEndpointTransport = "public_https" | "daemon";
968
+ type ProviderEndpointRuntime = "ollama";
969
+ type ProviderEndpointProtocol = "openai_compatible";
970
+ type ProviderEndpointVisibility = "private" | "marketplace";
971
+ interface ProviderEndpointModelMapping {
972
+ /** Idapt/OpenRouter-style model id, for example `openai/gpt-5.4`. */
973
+ model_id: string;
974
+ /** Upstream API model id sent to the provider. */
975
+ api_model_id: string;
976
+ }
977
+ /**
978
+ * A saved BYOK or daemon-local provider endpoint. Provider secrets are
979
+ * write-only: reads expose only `api_key_preview`.
980
+ */
981
+ interface ProviderEndpoint {
982
+ id: string;
983
+ kind: ProviderEndpointKind;
984
+ provider_key: ProviderEndpointProviderKey;
985
+ connection_type: ProviderEndpointConnectionType;
986
+ display_name: string;
987
+ transport: ProviderEndpointTransport;
988
+ runtime: ProviderEndpointRuntime | null;
989
+ protocol: ProviderEndpointProtocol | null;
990
+ computer_id: string | null;
991
+ local_base_url: string | null;
992
+ visibility: ProviderEndpointVisibility;
993
+ base_url: string | null;
994
+ api_key_preview: string;
995
+ enabled: boolean;
996
+ default_for_kind: boolean;
997
+ default_modalities: ProviderEndpointModality[];
998
+ supported_modalities: ProviderEndpointModality[];
999
+ model_mappings: ProviderEndpointModelMapping[];
1000
+ last_verified_at: string | null;
1001
+ last_used_at: string | null;
1002
+ last_error_at: string | null;
1003
+ last_error_code: string | null;
1004
+ last_error_message: string | null;
1005
+ created_at: string;
1006
+ updated_at: string;
1007
+ }
1008
+ interface ManagedProviderPreset {
1009
+ provider_key: ProviderEndpointProviderKey;
1010
+ connection_type: ProviderEndpointConnectionType;
1011
+ label: string;
1012
+ description: string;
1013
+ supported_modalities: ProviderEndpointModality[];
1014
+ requires_api_key: boolean;
1015
+ }
1016
+ interface ProviderEndpointTestResult {
1017
+ ok: boolean;
1018
+ message: string;
1019
+ status?: number;
1020
+ }
1021
+ /** One routable serving provider in the catalog. */
1022
+ interface AiGatewayProvider {
1023
+ slug: string;
1024
+ name: string;
1025
+ has_direct_connector: boolean;
1026
+ }
1027
+ /** One usage-breakdown row (model view carries `model_id`; provider view carries `provider_*`). */
1028
+ interface AiGatewayUsageRow {
1029
+ model_id?: string | null;
1030
+ provider_slug?: string | null;
1031
+ provider_name?: string | null;
1032
+ cost_usd: number;
1033
+ input_tokens: number;
1034
+ output_tokens: number;
1035
+ calls: number;
1036
+ }
1037
+ /** Image-model pricing block — flat per-image price (post-markup). */
1038
+ interface ImageModelPricing {
1039
+ per_image: number;
1040
+ }
1041
+ /** An image model from `GET /v1/images/models` (`modality: "image"`). */
1042
+ interface ImageModel extends ModelBase {
1043
+ modality: "image";
1044
+ provider_display_name?: string | null;
1045
+ provider_slug?: string | null;
1046
+ /** Post-markup pricing. */
1047
+ pricing: ImageModelPricing;
1048
+ /** Capability block — always an object. */
1049
+ capabilities: Record<string, unknown>;
1050
+ paid: boolean;
1051
+ /** Minimum tier required to use a paid model. */
1052
+ required_tier?: string | null;
1053
+ /** True when the caller's tier is below `required_tier`. */
1054
+ locked?: boolean;
1055
+ speed?: string | null;
1056
+ is_new?: boolean;
1057
+ }
1058
+ interface ImageGenerationResult {
1059
+ path: string;
1060
+ file_id: string;
1061
+ url: string;
1062
+ raw_url?: string | null;
1063
+ model: string;
1064
+ cost_usd?: number | null;
1065
+ }
1066
+ /** Audio (TTS) model pricing block — price per 1,000 characters (post-markup). */
1067
+ interface AudioModelPricing {
1068
+ per_thousand_chars: number;
1069
+ }
1070
+ /** Audio (TTS) model capability block (always an object). */
1071
+ interface AudioModelCapabilities {
1072
+ max_chars: number;
1073
+ }
1074
+ /**
1075
+ * A text-to-speech model from `GET /v1/audio/models` (`modality: "audio"`).
1076
+ * Pricing and capabilities are nested objects.
1077
+ */
1078
+ interface AudioModel extends ModelBase {
1079
+ modality: "audio";
1080
+ provider_display_name?: string | null;
1081
+ provider_slug?: string | null;
1082
+ pricing: AudioModelPricing;
1083
+ capabilities: AudioModelCapabilities;
1084
+ speed?: string | null;
1085
+ paid: boolean;
1086
+ is_new?: boolean;
1087
+ }
1088
+ /** Perceived gender of a TTS voice. */
1089
+ type TtsVoiceGender = "male" | "female" | "neutral";
1090
+ /**
1091
+ * A selectable TTS voice from `GET /v1/audio/voices`. The wire field is
1092
+ * `display_name` (was `name`); `gender` is a non-null enum.
1093
+ */
1094
+ interface TtsVoice {
1095
+ id: string;
1096
+ display_name: string;
1097
+ gender: TtsVoiceGender;
1098
+ language?: string | null;
1099
+ provider?: string | null;
1100
+ preview_url?: string | null;
1101
+ }
1102
+ interface SpeechResult {
1103
+ path: string;
1104
+ file_id: string;
1105
+ url: string;
1106
+ raw_url?: string | null;
1107
+ model: string;
1108
+ voice_id?: string | null;
1109
+ cost_usd?: number | null;
1110
+ char_count: number;
1111
+ }
1112
+ interface TranscriptionResult {
1113
+ text: string;
1114
+ /**
1115
+ * Present only for the JSON / reference form (`file_id` / `path` / `url`),
1116
+ * which persists the transcript as a `.txt` Drive file. The multipart
1117
+ * `file`-upload form (OpenAI-compatible) returns only `text`.
1118
+ */
1119
+ file_id?: string | null;
1120
+ path?: string | null;
1121
+ }
1122
+ type SpeechStreamEvent = {
1123
+ type: "chunk";
1124
+ audio: string;
1125
+ } | {
1126
+ type: "done";
1127
+ total_bytes?: number;
1128
+ duration_ms?: number;
1129
+ char_count?: number;
1130
+ cached?: boolean;
1131
+ } | {
1132
+ type: "error";
1133
+ status?: number;
1134
+ retry_after?: number;
1135
+ };
1136
+ type TranscriptionStreamEvent = {
1137
+ type: "partial";
1138
+ text: string;
1139
+ } | {
1140
+ type: "final";
1141
+ text: string;
1142
+ } | {
1143
+ type: "error";
1144
+ status?: number;
1145
+ retry_after?: number;
1146
+ };
1147
+ /** Workspace resource. Sourced from the crud v1 contract. */
1148
+ type Workspace = WorkspaceResponse;
1149
+ type WorkspaceMemberRole = "owner" | "admin" | "editor" | "viewer" | "custom";
1150
+ /** A workspace member. Sourced from the crud v1 contract. */
1151
+ type WorkspaceMember = WorkspaceMemberResponse;
1152
+ /** Whether a computer is a self-managed remote box or an idapt-provisioned VM. */
1153
+ type ComputerType = "remote" | "managed";
1154
+ /** Per-computer daemon logging verbosity. */
1155
+ type ComputerLoggingLevel = "minimal" | "standard" | "full";
1156
+ /**
1157
+ * Managed-computer lifecycle state. `state` is `null` for `remote` computers
1158
+ * (their reachability is not modelled as a lifecycle).
1159
+ */
1160
+ type ComputerState = "unprovisioned" | "provisioning" | "running" | "hibernating" | "hibernated" | "waking" | "stopping" | "stopped" | "terminating" | "terminated";
1161
+ /**
1162
+ * Computer record. Self-managed (`type: "remote"`) computers are paired
1163
+ * through the local daemon; idapt-provisioned (`type: "managed"`) computers
1164
+ * expose the full lifecycle `state`.
1165
+ */
1166
+ /** Computer record. Sourced from the computers v1 contract. */
1167
+ type Computer = ComputerResponse;
1168
+ /** One Unix user on a computer, returned by `listUsers`. */
1169
+ /** One Unix user on a computer. Sourced from the computers v1 contract. */
1170
+ type ComputerUser = ComputerUserResponse;
1171
+ /**
1172
+ * Env-var binding row — one credential file mounted as `${name}=$(<...)`
1173
+ * on a user. A binding is addressed by its env-var `name`; there is no
1174
+ * standalone UUID `id`. The bound credential is referenced by `file_id`.
1175
+ */
1176
+ /** Env-var binding row. Sourced from the computers v1 contract. */
1177
+ type ComputerEnvVar = ComputerEnvVarResponse;
1178
+ /** Auto-discovered listening port on a cloud computer. */
1179
+ /** Auto-discovered listening port. Sourced from the computers v1 contract. */
1180
+ type ComputerPort = ComputerPortResponse;
1181
+ /**
1182
+ * `exec` result — single-shot daemon command output. `success` reflects
1183
+ * whether the command exited 0 within its timeout.
1184
+ */
1185
+ interface ComputerExecResult {
1186
+ success: boolean;
1187
+ stdout: string;
1188
+ stderr: string;
1189
+ exitCode: number | null;
1190
+ durationMs: number;
1191
+ timedOut: boolean;
1192
+ }
1193
+ /**
1194
+ * Daemon server info returned inside `test-connection` — a structured
1195
+ * object.
1196
+ */
1197
+ interface ComputerServerInfo {
1198
+ version: string;
1199
+ uptime_seconds: number;
1200
+ }
1201
+ /**
1202
+ * One re-attachable tmux window on the `idapt` session. A tmux window
1203
+ * has no `pid` — it is not a single process.
1204
+ */
1205
+ interface TmuxWindow {
1206
+ name: string;
1207
+ active: boolean;
1208
+ }
1209
+ /** SFTP listing entry as returned by `op: "list"`. */
1210
+ interface SftpEntry {
1211
+ name: string;
1212
+ type: "file" | "dir" | "symlink" | string;
1213
+ size?: number | null;
1214
+ mode?: string | null;
1215
+ mtime?: string | null;
1216
+ }
1217
+ /**
1218
+ * A credential row exposed via `/api/v1/api-keys`. The plaintext `key` is
1219
+ * only present on the create response — there is no way to retrieve it
1220
+ * after that (the server only stores the hash).
1221
+ */
1222
+ /** An API key credential row. Sourced from the keys v1 contract. */
1223
+ type ApiKey = ApiKeyResponse;
1224
+ type NotificationSenderKind = "user" | "agent" | "system" | string;
1225
+ /** A notification row. Sourced from the crud v1 contract. */
1226
+ type Notification = NotificationResponse;
1227
+ /** Per-user toast/sound/quiet-hours/digest config. Sourced from the crud v1 contract. */
1228
+ type NotificationConfig = NotificationConfigResponse;
1229
+ /** One (type, subtype?, channel) preference row. Sourced from the crud v1 contract. */
1230
+ type NotificationPreference = NotificationPreferenceResponse;
1231
+ /**
1232
+ * A workspace secret. Stored server-side as a `.credential` file in the
1233
+ * workspace's `.secrets/` folder; the public API masks that detail. The
1234
+ * plaintext `value` is only echoed on the create response (so the caller
1235
+ * can audit what was stored), never on subsequent reads.
1236
+ */
1237
+ /** A workspace secret (metadata only — never the plaintext value). */
1238
+ type Secret = SecretResponse;
1239
+ /** A secret plus its decrypted value — only returned by `reveal`. */
1240
+ type SecretWithValue = SecretWithValueResponse;
1241
+ /** Datastore (KV) entry. */
1242
+ type DatastoreEntry = DatastoreEntryResponse;
1243
+ /** Blobs (object storage) object metadata. */
1244
+ type BlobObject = BlobObjectResponse;
1245
+ /** Idapt Tables — a collection (schema + metadata). */
1246
+ type TableCollection = TableCollectionResponse;
1247
+ /** Idapt Tables — a record (JSON document). */
1248
+ type TableRecord = TableRecordResponse;
1249
+ /**
1250
+ * A workspace invitation. The v1 contract keys invitations by `invitee_slug`
1251
+ * — there is no standalone `id` field on the wire. `DELETE` takes the slug
1252
+ * as a query param.
1253
+ */
1254
+ interface WorkspaceInvitation {
1255
+ status: "pending" | "accepted" | "declined" | "expired" | string;
1256
+ invitee_slug?: string | null;
1257
+ invitee_display_name?: string | null;
1258
+ inviter_slug?: string | null;
1259
+ inviter_display_name?: string | null;
1260
+ role?: string | null;
1261
+ expires_at?: string | null;
1262
+ created_at: string;
1263
+ responded_at?: string | null;
1264
+ }
1265
+ /**
1266
+ * Account-level preferences exposed on the v1 surface — the exact set
1267
+ * returned by `GET /v1/settings` and `PATCH /v1/settings`.
1268
+ *
1269
+ * `transformSettings` on the server picks ONLY these v1-stable fields and
1270
+ * deep-snake-cases them. UI-only state (sidebar collapsed groups, modal
1271
+ * counters, theme) is deliberately omitted from the public contract.
1272
+ */
1273
+ /** Account preferences from `GET/PATCH /settings`. Sourced from the v1 contract. */
1274
+ type Settings = SettingsResponse;
1275
+ /**
1276
+ * Account tier. Idapt is pay-as-you-go — there are no subscription plans /
1277
+ * tiers. `"paid"` means the caller has funded real credits (a persistent
1278
+ * credit balance); everyone else is `"free"`.
1279
+ */
1280
+ type SubscriptionPlan = "free" | "paid" | string;
1281
+ /**
1282
+ * Current account/credit view from `GET /subscription`. Sourced from the v1
1283
+ * contract. Carries the account tier (`plan` / `is_paid`), the credit `balance`
1284
+ * (USD), and the auto top-up settings. There are no subscription periods,
1285
+ * trial / cancel timestamps, or scheduled-downgrade fields — those concepts no
1286
+ * longer exist. Anonymous / unauthenticated callers get the `free` view.
1287
+ *
1288
+ * Stripe correlation ids are excluded at the route boundary — never visible.
1289
+ */
1290
+ type Subscription = SubscriptionResponse;
1291
+ type ShareResourceType = "chat" | "agent" | "file" | "workspace";
1292
+ type SharePermission = "read" | "write" | "admin";
1293
+ /**
1294
+ * A share row. The v1 contract identifies a share by its
1295
+ * `(resource_type, resource_id, grantee_actor_id)` triple — there is no
1296
+ * standalone `id` field on the wire.
1297
+ *
1298
+ * The provenance fields are `shared_at` / `shared_by_actor_id`.
1299
+ */
1300
+ /** A share grant. Sourced from the crud v1 contract. */
1301
+ type Share = ShareResponse;
1302
+ /**
1303
+ * Payload of `DELETE /v1/shares` — the unshare echoes back the triple it
1304
+ * removed (no envelope `id`).
1305
+ */
1306
+ interface ShareDeletedResult {
1307
+ deleted: true;
1308
+ resource_type: ShareResourceType;
1309
+ resource_id: string;
1310
+ grantee_actor_id: string;
1311
+ }
1312
+ /** One row in `GET /v1/shared-with-me`. The id IS the shared resource's id. */
1313
+ /** One `GET /v1/shared-with-me` row. Sourced from the account v1 contract. */
1314
+ type SharedWithMeItem = SharedWithMeItemResponse;
1315
+ type StoreItemType = "skill" | "agent" | "computer" | "computer-template" | "workspace" | string;
1316
+ /**
1317
+ * A single hub/store item. The catalog has heterogeneous payloads per
1318
+ * type (skills carry `version`/`license`, agents carry icons/prompts,
1319
+ * computer templates carry sizing) so we type the common fields and
1320
+ * leave the rest open.
1321
+ */
1322
+ /** A hub/store item. Sourced from the hub v1 contract. */
1323
+ type StoreItem = StoreItemResponse;
1324
+ /**
1325
+ * Returned by `POST /v1/store/:id/install`. Open shape per template type.
1326
+ * `id` is always present (the installed resource's resourceId).
1327
+ */
1328
+ interface StoreInstallResult {
1329
+ /** The installed resource's resourceId — always present. */
1330
+ id: string;
1331
+ installed: boolean;
1332
+ /** When the install lands as files in a workspace, the parent folder id. */
1333
+ folder_id?: string | null;
1334
+ /** When the install creates an agent, the new agent id. */
1335
+ agent_id?: string | null;
1336
+ /** Echoed back so callers can chain on the installed surface. */
1337
+ resource_type?: StoreItemType;
1338
+ resource_id?: string;
1339
+ [k: string]: unknown;
1340
+ }
1341
+ /**
1342
+ * Response shape of `POST /chats/:id/messages/:message_id/reprompt`.
1343
+ * - `wait=true` (default): returns `{ status: "completed", ..., message? }`
1344
+ * - `wait=false` or timeout: returns `{ status: "pending", ... }`
1345
+ *
1346
+ * The async status is `"pending"`. `reprompted_message_id` echoes the
1347
+ * user message the reprompt targets.
1348
+ */
1349
+ type RepromptResult = {
1350
+ status: "completed";
1351
+ chat_id: string;
1352
+ reprompted_message_id: string;
1353
+ model_id: string | null;
1354
+ /** The new assistant sibling. Null when we couldn't locate it post-run. */
1355
+ message: Message | null;
1356
+ } | {
1357
+ status: "pending";
1358
+ chat_id: string;
1359
+ reprompted_message_id: string;
1360
+ };
1361
+ interface SearchResult {
1362
+ id: string;
1363
+ source?: string | null;
1364
+ source_id?: string | null;
1365
+ resource_id?: string | null;
1366
+ title?: string | null;
1367
+ content?: string | null;
1368
+ score?: number | null;
1369
+ is_folder?: boolean;
1370
+ mime_type?: string | null;
1371
+ extension?: string | null;
1372
+ parent_name?: string | null;
1373
+ icon?: string | null;
1374
+ chat_title?: string | null;
1375
+ message_type?: "user" | "assistant" | null;
1376
+ agent_name?: string | null;
1377
+ workspace_resource_id?: string | null;
1378
+ workspace_name?: string | null;
1379
+ profile_slug?: string | null;
1380
+ display_image?: string | null;
1381
+ updated_at?: string | null;
1382
+ computer_name?: string | null;
1383
+ computer_hostname?: string | null;
1384
+ [k: string]: unknown;
1385
+ }
1386
+ interface WebSearchHit {
1387
+ title: string;
1388
+ url: string;
1389
+ text?: string;
1390
+ published_date?: string | null;
1391
+ author?: string | null;
1392
+ }
1393
+ interface WebSearchResponse {
1394
+ query: string;
1395
+ results: WebSearchHit[];
1396
+ }
1397
+ /** Permission descriptor — server-side `Permission` mirror. */
1398
+ interface Permission {
1399
+ resource: string;
1400
+ scope?: string | null;
1401
+ access?: "read" | "write" | "admin";
1402
+ }
1403
+ /**
1404
+ * Which backing the client is wired against. Always `"remote"` — the client
1405
+ * talks to the Idapt backend, either via the cookie/bootstrap flow (hosted on
1406
+ * an app subdomain) or library mode with an explicit `key`. Browser apps are
1407
+ * **npm-only**: there is no off-Idapt local mode.
1408
+ */
1409
+ type RuntimeMode = "remote";
1410
+ interface ClientMeta {
1411
+ appId: string;
1412
+ apiUrl: string;
1413
+ appFolderId: string;
1414
+ dataFolderId: string;
1415
+ /** Which backing the client is wired against (always `"remote"`). */
1416
+ mode: RuntimeMode;
1417
+ }
1418
+ /**
1419
+ * How the client authenticates each request:
1420
+ *
1421
+ * - `"bearer"` — send the raw `key` as `Authorization: Bearer`. Library mode
1422
+ * (explicit key) and any credential carrying a raw key.
1423
+ * - `"cookie"` — the httpOnly `__Secure-idapt_app_key` cookie carries auth;
1424
+ * there is no raw `key`. Hosted cookie-bootstrap flow. Requests go out
1425
+ * with `credentials: "include"` and no bearer header.
1426
+ */
1427
+ type AuthMode = "bearer" | "cookie";
1428
+ /**
1429
+ * The credential the client was constructed from.
1430
+ *
1431
+ * Two shapes (both `"remote"` — there is no off-Idapt local mode):
1432
+ * - **library bearer** — `{ key, apiUrl, mode: "remote", auth: "bearer" }`.
1433
+ * - **cookie bootstrap** — `{ key: null, apiUrl, mode: "remote",
1434
+ * auth: "cookie", appResourceId }`. The DB-first hosted flow: the raw
1435
+ * `ap_` key lives only in the httpOnly cookie, so `key` is `null` and auth
1436
+ * rides the cookie. `appResourceId` scopes the data KV (`RemoteDataStore`).
1437
+ *
1438
+ * `appFolderId` / `dataFolderId` are legacy Drive-folder ids — kept for the
1439
+ * `ClientMeta` surface. DB-first cookie boots no longer carry them (there is no
1440
+ * Drive folder); they default to `""`.
1441
+ */
1442
+ interface StoredCredential {
1443
+ /** The `ap_` / `uk_` bearer, or `null` in cookie mode (cookie carries auth). */
1444
+ key: string | null;
1445
+ /** API origin. */
1446
+ apiUrl: string;
1447
+ appResourceId?: string;
1448
+ appFolderId: string;
1449
+ dataFolderId: string;
1450
+ /** Always `"remote"`; defaults to `"remote"` when omitted. */
1451
+ mode?: RuntimeMode;
1452
+ /**
1453
+ * Auth transport. Defaults to `"bearer"`. Set to `"cookie"` for the hosted
1454
+ * bootstrap flow (no raw key — the httpOnly cookie carries auth).
1455
+ */
1456
+ auth?: AuthMode;
1457
+ }
1458
+ interface CallOptions {
1459
+ signal?: AbortSignal;
1460
+ }
1461
+ interface WriteOptions extends CallOptions {
1462
+ expectedUpdatedAt?: string;
1463
+ }
1464
+ interface ConnectOptions {
1465
+ apiUrl?: string;
1466
+ browserAppDomain?: string;
1467
+ /**
1468
+ * Explicit bearer (`uk_` / `pk_` / `ap_`) for **library mode**. When set,
1469
+ * the SDK skips the cookie bootstrap and connects directly to `apiUrl` with
1470
+ * this key as the Bearer token. Requires `apiUrl`.
1471
+ */
1472
+ key?: string;
1473
+ debug?: boolean;
1474
+ fetch?: typeof fetch;
1475
+ location?: Pick<Location, "hostname" | "pathname" | "origin" | "href" | "search">;
1476
+ }
1477
+ type EscalateRequest = Permission | Permission[];
1478
+
1479
+ /**
1480
+ * AppFolder — read-only access to the app's own code/bundle.
1481
+ *
1482
+ * Browser apps can list and read files from their own bundle to inspect their
1483
+ * manifest, bundled assets, etc. They cannot write here — that would be the
1484
+ * equivalent of a mobile app self-modifying its IPA bundle at runtime.
1485
+ *
1486
+ * `AppFolder` delegates every read to a {@link BundleReader}. The only
1487
+ * implementation is {@link RemoteBundleReader}, which reads the app's Drive
1488
+ * code folder through the same `/api/v1/drive/files/*` endpoints every other
1489
+ * file surface uses (id-addressed). The `BundleReader` seam is kept so the
1490
+ * accessor stays trivially testable with an injected reader.
1491
+ */
1492
+
1493
+ /**
1494
+ * The minimal read surface `AppFolder` needs. {@link RemoteBundleReader}
1495
+ * implements it; the interface is kept as a seam so tests can inject a fake
1496
+ * reader without an HTTP context. `id` arguments are Drive file ids.
1497
+ */
1498
+ interface BundleReader {
1499
+ /** The bundle/code-folder id. */
1500
+ readonly id?: string;
1501
+ /** List the bundle root. */
1502
+ list(opts?: CallOptions): Promise<File[]>;
1503
+ /** List a specific subfolder. */
1504
+ listFolder(parentId: string, opts?: CallOptions): Promise<File[]>;
1505
+ /** Read text by Drive file id. */
1506
+ read(id: string, opts?: CallOptions): Promise<string>;
1507
+ /** Read + parse JSON. */
1508
+ readJSON<T = unknown>(id: string, opts?: CallOptions): Promise<T>;
1509
+ /** Read raw bytes as a Blob, preserving Content-Type. */
1510
+ readBlob(id: string, opts?: CallOptions): Promise<Blob>;
1511
+ }
1512
+ /**
1513
+ * Remote `BundleReader` — the historical Drive-backed behaviour, talking to
1514
+ * `/api/v1/drive/files/*` scoped to the app's code folder.
1515
+ */
1516
+ declare class RemoteBundleReader implements BundleReader {
1517
+ private readonly ctx;
1518
+ readonly id: string;
1519
+ constructor(ctx: HttpContext, id: string);
1520
+ list(opts?: CallOptions): Promise<File[]>;
1521
+ listFolder(parentId: string, opts?: CallOptions): Promise<File[]>;
1522
+ read(fileId: string, opts?: CallOptions): Promise<string>;
1523
+ readJSON<T = unknown>(fileId: string, opts?: CallOptions): Promise<T>;
1524
+ readBlob(fileId: string, opts?: CallOptions): Promise<Blob>;
1525
+ }
1526
+ declare class AppFolder {
1527
+ private readonly reader;
1528
+ /**
1529
+ * Two construction shapes:
1530
+ *
1531
+ * - `new AppFolder(ctx, folderId)` — builds a {@link RemoteBundleReader}
1532
+ * internally. The normal path.
1533
+ * - `new AppFolder(reader)` — inject any {@link BundleReader} (e.g. a fake
1534
+ * in tests).
1535
+ */
1536
+ constructor(ctxOrReader: HttpContext | BundleReader, folderId?: string);
1537
+ /** The code folder's id. */
1538
+ get id(): string;
1539
+ /** List files in the app folder. */
1540
+ list(opts?: CallOptions): Promise<File[]>;
1541
+ /** List a specific subfolder of the app folder. */
1542
+ listFolder(parentId: string, opts?: CallOptions): Promise<File[]>;
1543
+ /**
1544
+ * Read a file's text content (by Drive file id). UTF-8 decoded; use
1545
+ * `readBlob` for binary.
1546
+ */
1547
+ read(fileId: string, opts?: CallOptions): Promise<string>;
1548
+ /** Read + parse JSON in one call. */
1549
+ readJSON<T = unknown>(fileId: string, opts?: CallOptions): Promise<T>;
1550
+ /** Read a file's raw bytes as a Blob. Preserves the server's MIME type. */
1551
+ readBlob(fileId: string, opts?: CallOptions): Promise<Blob>;
1552
+ }
1553
+
1554
+ /**
1555
+ * DataFolder — read-write access to the app's **per-(user × app) data store**.
1556
+ *
1557
+ * This is where browser apps persist per-user state (preferences, history,
1558
+ * caches). `DataFolder` delegates every operation to a {@link DataStore}; the
1559
+ * only implementation is {@link RemoteDataStore} (`./data-remote.ts`), which
1560
+ * backs onto the dedicated app-data KV at `/api/browser-app/data/{appResId}/{key}`
1561
+ * (DB-first — NOT Drive). Each entry is scoped to the app's principal → blast
1562
+ * radius is exactly this app's own sandbox. The KV is a **flat key/value
1563
+ * namespace**: the key doubles as the file id AND name (there are no folders).
1564
+ * The `DataStore` interface is kept as a testing seam.
1565
+ *
1566
+ * Three layers are exposed:
1567
+ *
1568
+ * **Name-based** (ergonomic, the 95% case):
1569
+ * set/get/has/remove/setJSON/getJSON — keyed by name (== the KV key).
1570
+ *
1571
+ * **key-based** (raw, for apps that want full control):
1572
+ * list/read/write/delete/readJSON/writeJSON + upload (the key is the id).
1573
+ *
1574
+ * **Subfolders** (`createFolder`/`move`/`listFolder`): the flat KV has no
1575
+ * folder analogue and throws a typed `InvalidRequestError`.
1576
+ */
1577
+
1578
+ /** Upload input at the store layer (already resolved against the data folder). */
1579
+ interface DataStoreUploadInput {
1580
+ file: Blob | globalThis.File;
1581
+ name?: string;
1582
+ /** Resolved parent; the store defaults a missing value to its root. */
1583
+ parent_id?: string;
1584
+ skip_if_exists?: boolean;
1585
+ }
1586
+ /** Create-folder input at the store layer. */
1587
+ interface DataStoreCreateFolderInput {
1588
+ name: string;
1589
+ parent_id?: string;
1590
+ icon?: string;
1591
+ }
1592
+ /**
1593
+ * The read-write surface `DataFolder` needs. {@link RemoteDataStore} implements
1594
+ * it; the interface is kept as a seam so tests can inject a fake store. Methods
1595
+ * mirror the v1 Drive operations the name-cache / OCC logic composes.
1596
+ */
1597
+ interface DataStore {
1598
+ /** The data store's id (the app resource id). */
1599
+ readonly id: string;
1600
+ /** API origin. */
1601
+ readonly apiUrl?: string | null;
1602
+ list(opts?: CallOptions): Promise<File[]>;
1603
+ listFolder(parentId: string, opts?: CallOptions): Promise<File[]>;
1604
+ getMetadata(fileId: string, opts?: CallOptions): Promise<File>;
1605
+ read(fileId: string, opts?: CallOptions): Promise<string>;
1606
+ readBlob(fileId: string, opts?: CallOptions): Promise<Blob>;
1607
+ write(fileId: string, content: string, opts?: WriteOptions): Promise<File>;
1608
+ delete(fileId: string, opts?: CallOptions): Promise<DeletedResponse>;
1609
+ upload(input: DataStoreUploadInput, opts?: CallOptions): Promise<FileUploadResult>;
1610
+ createFolder(input: DataStoreCreateFolderInput, opts?: CallOptions): Promise<File>;
1611
+ move(fileId: string, parentId: string | null, opts?: CallOptions): Promise<File>;
1612
+ }
1613
+ interface DataUploadInput {
1614
+ file: Blob | globalThis.File;
1615
+ /** Override the name stored in the database. */
1616
+ name?: string;
1617
+ /** Subfolder within the data folder; defaults to the data folder root. */
1618
+ parent_id?: string;
1619
+ skip_if_exists?: boolean;
1620
+ }
1621
+ interface DataCreateFolderInput {
1622
+ name: string;
1623
+ /** Nest under another folder inside the data folder. Defaults to data root. */
1624
+ parent_id?: string;
1625
+ icon?: string;
1626
+ }
1627
+ declare class DataFolder {
1628
+ /** name (lowercased) → fileId, populated lazily by list() / set(). */
1629
+ private readonly nameCache;
1630
+ private nameCacheLoaded;
1631
+ private readonly store;
1632
+ /**
1633
+ * Two construction shapes:
1634
+ *
1635
+ * - `new DataFolder(ctx, appResourceId)` — builds a {@link RemoteDataStore}
1636
+ * internally, scoped by the app's RESOURCE id (the `{appResId}` segment of
1637
+ * the KV path), NOT a Drive folder id. The normal path.
1638
+ * - `new DataFolder(store)` — inject any {@link DataStore} (e.g. a fake in
1639
+ * tests).
1640
+ */
1641
+ constructor(ctxOrStore: HttpContext | DataStore, appResourceId?: string);
1642
+ /** The data folder's id — useful for passing to other SDK calls. */
1643
+ get id(): string;
1644
+ /** List every file in the data folder (top level only, excluding subfolders' contents). */
1645
+ list(opts?: CallOptions): Promise<File[]>;
1646
+ /** List a specific subfolder within the data folder. */
1647
+ listFolder(parentId: string, opts?: CallOptions): Promise<File[]>;
1648
+ /** Read a file's raw text content by id. UTF-8 decoded. */
1649
+ read(fileId: string, opts?: CallOptions): Promise<string>;
1650
+ /** Read and parse as JSON. */
1651
+ readJSON<T = unknown>(fileId: string, opts?: CallOptions): Promise<T>;
1652
+ /** Read raw bytes as a Blob. Use for binary files stored in data folder. */
1653
+ readBlob(fileId: string, opts?: CallOptions): Promise<Blob>;
1654
+ /** PATCH content on an existing file id (optimistic concurrency via opts). */
1655
+ write(fileId: string, content: string, opts?: WriteOptions): Promise<File>;
1656
+ /** Stringify and PATCH. */
1657
+ writeJSON<T>(fileId: string, data: T, opts?: WriteOptions): Promise<File>;
1658
+ /** Move the file to trash. */
1659
+ delete(fileId: string, opts?: CallOptions): Promise<void>;
1660
+ /**
1661
+ * Multipart upload a Blob or File into the data folder (or a subfolder of
1662
+ * it). Returns the upload record. Use this for binary data; for text/JSON
1663
+ * prefer the name-based `set()` / `setJSON()`.
1664
+ */
1665
+ upload(input: DataUploadInput, opts?: CallOptions): Promise<FileUploadResult>;
1666
+ /**
1667
+ * Create (or get) a subfolder inside the data folder. Returns the folder
1668
+ * record — store the `id` to use as `parent_id` for nested uploads /
1669
+ * `createFolder` calls. Idempotent by name at the given parent.
1670
+ */
1671
+ createFolder(input: DataCreateFolderInput, opts?: CallOptions): Promise<File>;
1672
+ /**
1673
+ * Move a file or subfolder within the data folder. Pass the data folder's
1674
+ * own id (or omit `parentId`) to move it back to the data-folder root.
1675
+ */
1676
+ move(fileId: string, parentId?: string | null, opts?: CallOptions): Promise<File>;
1677
+ /**
1678
+ * Upsert a file by name. Creates it on first call, PATCHes it on
1679
+ * subsequent calls. Returns the resolved file metadata.
1680
+ */
1681
+ set(name: string, content: string, opts?: WriteOptions): Promise<File>;
1682
+ /** Stringify-and-upsert. */
1683
+ setJSON<T>(name: string, data: T, opts?: WriteOptions): Promise<File>;
1684
+ /**
1685
+ * Read a file by name. Returns `null` if the file doesn't exist (rather
1686
+ * than throwing) — this is the common "first-run preferences" case.
1687
+ */
1688
+ get(name: string, opts?: CallOptions): Promise<string | null>;
1689
+ /** Read + parse JSON, or null if the file doesn't exist. */
1690
+ getJSON<T = unknown>(name: string, opts?: CallOptions): Promise<T | null>;
1691
+ /** Does a file with this name exist? */
1692
+ has(name: string, opts?: CallOptions): Promise<boolean>;
1693
+ /**
1694
+ * Delete a file by name. Returns `true` if something was deleted, `false`
1695
+ * if the file didn't exist.
1696
+ */
1697
+ remove(name: string, opts?: CallOptions): Promise<boolean>;
1698
+ /**
1699
+ * Find the file id for a given name, or null. Populates the name→id cache
1700
+ * on first call.
1701
+ */
1702
+ resolve(name: string, opts?: CallOptions): Promise<File | null>;
1703
+ /** Drop the name→id cache. Next call will re-list. */
1704
+ invalidate(): void;
1705
+ /**
1706
+ * Create a new file at the data-folder root via multipart upload. The
1707
+ * `skip_if_exists` flag hedges against concurrent creates; if another tab
1708
+ * wins the race, we re-list and PATCH instead.
1709
+ */
1710
+ private createByName;
1711
+ private rebuildNameCache;
1712
+ }
1713
+
1714
+ export { type LLMModelPricing as $, type AiGatewayProvider as A, type BlobObject as B, type CallOptions as C, type DataStore as D, type ComputerServerInfo as E, type File as F, type ComputerState as G, type HttpContext as H, type ComputerType as I, type ComputerUser as J, type CreateTriggerInput as K, type DataCreateFolderInput as L, DataFolder as M, type DataUploadInput as N, type DatastoreEntry as O, type EscalateRequest as P, type ExecutionBackend as Q, type ExecutionRun as R, type ExecutionRunStatus as S, type FileList as T, type HttpRequest as U, type ImageGenerationResult as V, type WriteOptions as W, type ImageModel as X, type ImageModelPricing as Y, type LLMModel as Z, type LLMModelCapabilities as _, type AiGatewayUsageRow as a, type UsageRecord as a$, type ListEnvelope as a0, type ManagedProviderPreset as a1, type Message as a2, type MessageCostEntry as a3, type MessageCosts as a4, type ModelBase as a5, type ModelModality as a6, type Notification as a7, type NotificationConfig as a8, type NotificationPreference as a9, type ShareDeletedResult as aA, type SharePermission as aB, type ShareResourceType as aC, type SharedWithMeItem as aD, type SingleEnvelope as aE, type SpeechResult as aF, type SpeechStreamEvent as aG, type StoreInstallResult as aH, type StoreItem as aI, type StoreItemType as aJ, type StoredCredential as aK, type Subscription as aL, type SubscriptionPlan as aM, type TableCollection as aN, type TableRecord as aO, type TmuxWindow as aP, type TranscriptionResult as aQ, type TranscriptionStreamEvent as aR, type Trigger as aS, type TriggerActionType as aT, type TriggerCostStats as aU, type TriggerRun as aV, type TriggerType as aW, type TriggerWithSecret as aX, type TtsVoice as aY, type TtsVoiceGender as aZ, type UpdateTriggerInput as a_, type NotificationSenderKind as aa, type Pagination as ab, type Permission as ac, type ProviderEndpoint as ad, type ProviderEndpointConnectionType as ae, type ProviderEndpointKind as af, type ProviderEndpointModality as ag, type ProviderEndpointModelMapping as ah, type ProviderEndpointProtocol as ai, type ProviderEndpointProviderKey as aj, type ProviderEndpointRuntime as ak, type ProviderEndpointTestResult as al, type ProviderEndpointTransport as am, type ProviderEndpointVisibility as an, type QueryInput as ao, RemoteBundleReader as ap, type RepromptResult as aq, type RunCostMetrics as ar, type RuntimeMode as as, type SearchResult as at, type Secret as au, type SecretWithValue as av, type SendMessageResult as aw, type Settings as ax, type SftpEntry as ay, type Share as az, type DeletedResponse as b, type UsageSummary as b0, type User as b1, type WebSearchHit as b2, type WebSearchResponse as b3, type Workspace as b4, type WorkspaceInvitation as b5, type WorkspaceMember as b6, type WorkspaceMemberRole as b7, buildUrl as b8, request as b9, requestRaw as ba, type DataStoreUploadInput as c, type FileUploadResult as d, type DataStoreCreateFolderInput as e, type ConnectOptions as f, type Agent as g, type AgentRun as h, type AgentRunState as i, type ApiKey as j, AppFolder as k, type AudioModel as l, type AudioModelCapabilities as m, type AudioModelPricing as n, type AuthMode as o, type BundleReader as p, type Chat as q, type ChatCost as r, type ChatCostByCallType as s, type ChatStopResult as t, type ClientMeta as u, type Computer as v, type ComputerEnvVar as w, type ComputerExecResult as x, type ComputerLoggingLevel as y, type ComputerPort as z };