@ingram-cloud/sdk 1.2.0 → 1.4.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.
package/dist/client.js CHANGED
@@ -143,6 +143,13 @@ export class IngramCloud {
143
143
  body,
144
144
  }),
145
145
  },
146
+ /** End-user BYOK (#170): a smith's own provider keys, resolved ahead of the
147
+ * tenant's so the end-user's provider account is billed. Never read back. */
148
+ modelKeys: {
149
+ list: (pid, opts) => this.data("GET", `/smiths/${enc(pid)}/model_keys`, opts),
150
+ put: (pid, provider, body, opts) => this.json("PUT", `/smiths/${enc(pid)}/model_keys/${enc(provider)}`, { ...opts, body }),
151
+ delete: (pid, provider, opts) => this.empty("DELETE", `/smiths/${enc(pid)}/model_keys/${enc(provider)}`, opts),
152
+ },
146
153
  schedules: {
147
154
  list: (pid, opts) => this.data("GET", `/smiths/${enc(pid)}/schedules`, opts),
148
155
  create: (pid, body, opts) => this.json("POST", `/smiths/${enc(pid)}/schedules`, {
@@ -246,6 +253,13 @@ export class IngramCloud {
246
253
  rawBody: form,
247
254
  });
248
255
  },
256
+ /** The template's HTML bundle — the same bytes the agent's MCP endpoint
257
+ * serves, so a host can render a panel without vendoring a copy.
258
+ * Tenant-authed: call it server-side and proxy to your chat UI. */
259
+ content: (aid, name, opts) => this.request("GET", `/agents/${enc(aid)}/ui/${enc(name)}/content`, {
260
+ ...opts,
261
+ headers: { accept: "text/html", ...opts?.headers },
262
+ }).then((r) => r.text()),
249
263
  delete: (aid, name, opts) => this.json("DELETE", `/agents/${enc(aid)}/ui/${enc(name)}`, opts),
250
264
  },
251
265
  };
@@ -384,6 +398,9 @@ export class IngramCloud {
384
398
  body,
385
399
  }),
386
400
  delete: (wid, opts) => this.empty("DELETE", `/tenant/webhooks/${enc(wid)}`, opts),
401
+ /** Rotate the signing secret, returning the new one exactly once. Pass
402
+ * `grace_seconds` to keep the old secret accepted during an overlap window. */
403
+ rotateSecret: (wid, body, opts) => this.json("POST", `/tenant/webhooks/${enc(wid)}/rotate_secret`, { ...opts, body: body ?? {} }),
387
404
  test: (wid, opts) => this.json("POST", `/tenant/webhooks/${enc(wid)}/test`, opts),
388
405
  /** The persisted delivery attempts for a webhook (durable retry audit trail). */
389
406
  deliveries: (wid, query, opts) => this.page(`/tenant/webhooks/${enc(wid)}/deliveries`, query, opts),
@@ -456,7 +473,8 @@ export class IngramCloud {
456
473
  decline: (requestId, opts) => this.json("POST", `/oauth/authorize-requests/${enc(requestId)}/decline`, opts),
457
474
  },
458
475
  };
459
- // ── Organization (org token: projects + billing) ────────────────────────
476
+ // ── Organization (org token: projects + tokens) ─────────────────────────
477
+ // Note: the `/v1/organization/billing/*` surface is not yet wrapped here.
460
478
  organization = {
461
479
  projects: {
462
480
  list: (opts) => this.data("GET", "/organization/projects", opts),
@@ -67,6 +67,8 @@ export const AgentDraft = z
67
67
  model: z.string().nullable(),
68
68
  enabled_hosted_tools: z.array(z.string()),
69
69
  vector_store_ids: z.array(z.string()),
70
+ /** Registered MCP servers this agent's smiths load, by name. Null = all. */
71
+ mcp_servers: z.array(z.string()).nullable(),
70
72
  auto_memory: z.boolean().nullable(),
71
73
  memory_consolidation: z.boolean().nullable(),
72
74
  variables: z.array(AgentVariable),
@@ -87,6 +89,8 @@ export const AgentOut = z
87
89
  rollout_version: z.number().int().nullable(),
88
90
  rollout_percent: z.number().int(),
89
91
  smith_count: z.number().int().optional(),
92
+ /** Newest run across every smith of this agent. Null until one runs. */
93
+ last_activity_at: z.string().nullable().optional(),
90
94
  created_at: z.string().nullable(),
91
95
  updated_at: z.string().nullable(),
92
96
  })
@@ -101,6 +105,7 @@ export const AgentVersionOut = z
101
105
  model: z.string().nullish(),
102
106
  enabled_hosted_tools: z.array(z.string()).optional(),
103
107
  vector_store_ids: z.array(z.string()).optional(),
108
+ mcp_servers: z.array(z.string()).nullish(),
104
109
  auto_memory: z.boolean().nullish(),
105
110
  memory_consolidation: z.boolean().nullish(),
106
111
  variables: z.array(AgentVariable).optional(),
@@ -123,6 +128,8 @@ export const AgentIn = z
123
128
  model: z.string().nullish(),
124
129
  enabled_hosted_tools: z.array(z.string()).nullish(),
125
130
  vector_store_ids: z.array(z.string()).nullish(),
131
+ /** Scope runs to these registered MCP servers (by name). Null/omitted = all. */
132
+ mcp_servers: z.array(z.string()).nullish(),
126
133
  auto_memory: z.boolean().nullish(),
127
134
  memory_consolidation: z.boolean().nullish(),
128
135
  variables: z.array(AgentVariable).nullish(),
@@ -135,6 +142,9 @@ export const AgentPatch = z
135
142
  model: z.string().nullish(),
136
143
  enabled_hosted_tools: z.array(z.string()).nullish(),
137
144
  vector_store_ids: z.array(z.string()).nullish(),
145
+ /** Scope runs to these registered MCP servers (by name). An explicit null
146
+ * clears the restriction (= all); omitted leaves it unchanged. */
147
+ mcp_servers: z.array(z.string()).nullish(),
138
148
  auto_memory: z.boolean().nullish(),
139
149
  memory_consolidation: z.boolean().nullish(),
140
150
  variables: z.array(AgentVariable).nullish(),
package/dist/zod/mcp.js CHANGED
@@ -67,11 +67,17 @@ export const McpServerOut = z
67
67
  approval_policy: z.array(ApprovalRule).optional(),
68
68
  tools: z.array(McpTool),
69
69
  tools_refreshed_at: z.string().nullable(),
70
- /** `degraded` when the edge failed discovery or its secret can't be decoded
71
- * at run time; otherwise the stored lifecycle status. */
70
+ /** `degraded` when the edge failed discovery, its secret can't be decoded at
71
+ * run time, or its last `tools/call` failed at the transport level;
72
+ * otherwise the stored lifecycle status. */
72
73
  status: z.string(),
73
- /** Last discovery/runtime-load failure, or null when the edge is healthy. */
74
+ /** Last discovery/runtime-load failure, or null when discovery is healthy. */
74
75
  discovery_error: z.string().nullable(),
76
+ /** Last transport-level `tools/call` failure (network / HTTP status), or
77
+ * null. Discovery can succeed while calls fail — this catches that. Cleared
78
+ * by a successful call or a re-PUT. */
79
+ last_call_error: z.string().nullable(),
80
+ last_call_error_at: z.string().nullable(),
75
81
  created_at: z.string().nullable(),
76
82
  })
77
83
  .meta({ id: "McpServerOut" });
@@ -95,7 +101,9 @@ export const McpAuthIn = z
95
101
  })
96
102
  .meta({ id: "McpAuthIn" });
97
103
  /** Register or replace a server: supply a raw `url` + `auth`, or a `catalog`
98
- * slug (catalog defaults are stamped down, body fields override). */
104
+ * slug (catalog defaults are stamped down, body fields override). PUT is a
105
+ * full replace and `auth.kind` is required unless a catalog preset supplies
106
+ * it — there is no implicit `none`. */
99
107
  export const McpServerIn = z
100
108
  .object({
101
109
  url: z.string().nullish(),
@@ -63,6 +63,7 @@ export const TraceOut = z
63
63
  id: z.string(),
64
64
  smith_id: z.string(),
65
65
  app_id: z.string().nullable(),
66
+ run_id: z.string().nullable(),
66
67
  root_kind: ICSpanKindEnum,
67
68
  name: z.string(),
68
69
  status: z.string(),
@@ -25,8 +25,11 @@ export const SmithRevisionOut = z
25
25
  model: z.string().nullish(),
26
26
  enabled_hosted_tools: z.array(z.string()).optional(),
27
27
  vector_store_ids: z.array(z.string()).optional(),
28
- auto_memory: z.boolean().optional(),
29
- memory_consolidation: z.boolean().optional(),
28
+ mcp_servers: z.array(z.string()).nullish(),
29
+ // Nullish: a snapshot taken while the smith inherited a sparse agent
30
+ // version carries null (= the default) for these.
31
+ auto_memory: z.boolean().nullish(),
32
+ memory_consolidation: z.boolean().nullish(),
30
33
  }),
31
34
  created_by: z.string().nullish(),
32
35
  note: z.string().nullish(),
@@ -36,6 +36,8 @@ export const SmithOut = z
36
36
  rendered_instructions: z.string().nullish(),
37
37
  enabled_hosted_tools: z.array(z.string()).optional(),
38
38
  vector_store_ids: z.array(z.string()).optional(),
39
+ /** Registered MCP servers this smith's runs load, by name. Null = all. */
40
+ mcp_servers: z.array(z.string()).nullish(),
39
41
  auto_memory: z.boolean().optional(),
40
42
  memory_consolidation: z.boolean().optional(),
41
43
  /** How the config resolved: by reference, with overrides, or embedded. */
@@ -55,6 +57,7 @@ export const SmithOut = z
55
57
  instructions: z.string().nullable(),
56
58
  enabled_hosted_tools: z.array(z.string()),
57
59
  vector_store_ids: z.array(z.string()),
60
+ mcp_servers: z.array(z.string()).nullable(),
58
61
  auto_memory: z.boolean().nullable(),
59
62
  memory_consolidation: z.boolean().nullable(),
60
63
  })
@@ -85,6 +88,8 @@ export const SmithCreate = z
85
88
  instructions: z.string().nullish(),
86
89
  enabled_hosted_tools: z.array(z.string()).nullish(),
87
90
  vector_store_ids: z.array(z.string()).nullish(),
91
+ /** Scope this smith's runs to these registered MCP servers (by name). */
92
+ mcp_servers: z.array(z.string()).nullish(),
88
93
  auto_memory: z.boolean().nullish(),
89
94
  memory_consolidation: z.boolean().nullish(),
90
95
  })
@@ -102,6 +107,9 @@ export const SmithPatch = z
102
107
  instructions: z.string().nullish(),
103
108
  enabled_hosted_tools: z.array(z.string()).nullish(),
104
109
  vector_store_ids: z.array(z.string()).nullish(),
110
+ /** Scope this smith's runs to these registered MCP servers (by name).
111
+ * Null clears the per-smith override (re-inherit the agent's value). */
112
+ mcp_servers: z.array(z.string()).nullish(),
105
113
  auto_memory: z.boolean().nullish(),
106
114
  memory_consolidation: z.boolean().nullish(),
107
115
  })
@@ -67,6 +67,23 @@ export const WebhookPatch = z
67
67
  active: z.boolean().nullish(),
68
68
  })
69
69
  .meta({ id: "WebhookPatch" });
70
+ /** Rotate a webhook's signing secret. `grace_seconds` keeps the outgoing secret
71
+ * valid for an overlap window (default 24h, 0 = cut over immediately, max 7d);
72
+ * during it every delivery is signed with both the new and old secret. */
73
+ export const WebhookRotateIn = z
74
+ .object({
75
+ grace_seconds: z.number().int().min(0).max(604800).default(86400),
76
+ })
77
+ .meta({ id: "WebhookRotateIn" });
78
+ /** The rotate response — the new signing `secret` is returned EXACTLY ONCE, here.
79
+ * `previous_secret_expires_at` is when the old secret stops being accepted. */
80
+ export const WebhookRotateOut = z
81
+ .object({
82
+ id: z.string(),
83
+ secret: z.string(),
84
+ previous_secret_expires_at: z.string().nullable(),
85
+ })
86
+ .meta({ id: "WebhookRotateOut" });
70
87
  /** One persisted delivery attempt record for a webhook — the audit trail behind
71
88
  * durable, retried delivery. `status` is `pending` | `succeeded` | `dead`. */
72
89
  export const WebhookDeliveryOut = z
@@ -7,9 +7,11 @@
7
7
  * filter grammar, and the `search_results.page` envelope are OpenAI's, wart for
8
8
  * wart (modify is `POST`, the batch object is `vector_store.files_batch`, the
9
9
  * search page uses a `next_page` token while CRUD lists use `first_id`/
10
- * `last_id`). `smith_id` is the one documented IC extension: it scopes a store
11
- * to a single smith ("" = tenant-wide), the same isolation boundary every other
12
- * smith-owned resource has. Expiration policies (`expires_after`), query
10
+ * `last_id`). Two documented IC extensions: `smith_id` scopes a store to a
11
+ * single smith ("" = tenant-wide), the same isolation boundary every other
12
+ * smith-owned resource has; `embedding_model` names the store's embedder,
13
+ * frozen at create (OpenAI pins one platform-wide, Gemini's File Search exposes
14
+ * it the same way). Expiration policies (`expires_after`), query
13
15
  * rewriting, and rankers are not implemented — the fields don't exist here
14
16
  * rather than being accepted and ignored.
15
17
  */
@@ -78,6 +80,11 @@ export const VectorStoreIn = z
78
80
  metadata: z.record(z.string(), z.unknown()).optional(),
79
81
  /** IC extension: own the store to one smith ("" / omitted = tenant-wide). */
80
82
  smith_id: z.string().optional(),
83
+ /** IC extension: the embedder to index and query this store with, frozen at
84
+ * create (omitted = the platform default). Any model your OpenAI-provider
85
+ * key can reach — including an EU-hosted OpenAI-compatible endpoint set as
86
+ * that key's `base_url` — of at most 1536 dimensions. */
87
+ embedding_model: z.string().optional(),
81
88
  })
82
89
  .meta({ id: "VectorStoreIn" });
83
90
  export const VectorStoreFileCounts = z.object({
@@ -105,6 +112,9 @@ export const VectorStoreOut = z
105
112
  metadata: z.record(z.string(), z.unknown()),
106
113
  /** IC extension: the owning smith ("" = tenant-wide). */
107
114
  smith_id: z.string(),
115
+ /** IC extension: the embedder this store is indexed and queried with,
116
+ * frozen at create. */
117
+ embedding_model: z.string(),
108
118
  })
109
119
  .meta({ id: "VectorStoreOut" });
110
120
  /** Vector stores, in OpenAI's `list` envelope. */
@@ -151,7 +161,12 @@ export const VectorStoreFileOut = z
151
161
  status: z.enum(["in_progress", "completed", "failed", "cancelled"]),
152
162
  last_error: z
153
163
  .object({
154
- code: z.enum(["server_error", "unsupported_file", "invalid_file"]),
164
+ code: z.enum([
165
+ "server_error",
166
+ "unsupported_file",
167
+ "no_text_layer",
168
+ "invalid_file",
169
+ ]),
155
170
  message: z.string(),
156
171
  })
157
172
  .nullable(),
@@ -174,6 +189,17 @@ export const VectorStoreFileUpdate = z
174
189
  attributes: VectorStoreAttributes.nullable(),
175
190
  })
176
191
  .meta({ id: "VectorStoreFileUpdate" });
192
+ /** The parsed text a file was indexed as, chunk by chunk, in OpenAI's
193
+ * `vector_store.file_content.page` envelope. The whole file is one page — the
194
+ * paging fields are the envelope's shape, not a promise of more. */
195
+ export const VectorStoreFileContentOut = z
196
+ .object({
197
+ object: z.literal("vector_store.file_content.page"),
198
+ data: z.array(z.object({ type: z.literal("text"), text: z.string() })),
199
+ has_more: z.literal(false),
200
+ next_page: z.null(),
201
+ })
202
+ .meta({ id: "VectorStoreFileContentOut" });
177
203
  export const VectorStoreFileDeleted = z
178
204
  .object({
179
205
  id: z.string(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ingram-cloud/sdk",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "Typed wire contract + management-plane client for the Ingram Cloud API: Zod schemas to validate request/response bodies, TypeScript types for the JSON you read back, SSE/webhook event types, and a typed REST client.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/ts/client.ts CHANGED
@@ -125,6 +125,8 @@ import type {
125
125
  WebhookIn,
126
126
  WebhookPatch,
127
127
  WebhookRedeliverOut,
128
+ WebhookRotateIn,
129
+ WebhookRotateOut,
128
130
  } from "./zod/tenant.js";
129
131
  import type { WhatsAppConfigIn } from "./zod/whatsapp.js";
130
132
 
@@ -451,6 +453,30 @@ export class IngramCloud {
451
453
  ),
452
454
  },
453
455
 
456
+ /** End-user BYOK (#170): a smith's own provider keys, resolved ahead of the
457
+ * tenant's so the end-user's provider account is billed. Never read back. */
458
+ modelKeys: {
459
+ list: (pid: string, opts?: RequestOptions) =>
460
+ this.data<ICModelKey>("GET", `/smiths/${enc(pid)}/model_keys`, opts),
461
+ put: (
462
+ pid: string,
463
+ provider: string,
464
+ body: z.input<typeof ModelKeyIn>,
465
+ opts?: RequestOptions,
466
+ ) =>
467
+ this.json<z.infer<typeof ModelKeyConfiguredOut>>(
468
+ "PUT",
469
+ `/smiths/${enc(pid)}/model_keys/${enc(provider)}`,
470
+ { ...opts, body },
471
+ ),
472
+ delete: (pid: string, provider: string, opts?: RequestOptions) =>
473
+ this.empty(
474
+ "DELETE",
475
+ `/smiths/${enc(pid)}/model_keys/${enc(provider)}`,
476
+ opts,
477
+ ),
478
+ },
479
+
454
480
  schedules: {
455
481
  list: (pid: string, opts?: RequestOptions) =>
456
482
  this.data<ICSchedule>("GET", `/smiths/${enc(pid)}/schedules`, opts),
@@ -659,6 +685,14 @@ export class IngramCloud {
659
685
  rawBody: form,
660
686
  });
661
687
  },
688
+ /** The template's HTML bundle — the same bytes the agent's MCP endpoint
689
+ * serves, so a host can render a panel without vendoring a copy.
690
+ * Tenant-authed: call it server-side and proxy to your chat UI. */
691
+ content: (aid: string, name: string, opts?: RequestOptions) =>
692
+ this.request("GET", `/agents/${enc(aid)}/ui/${enc(name)}/content`, {
693
+ ...opts,
694
+ headers: { accept: "text/html", ...opts?.headers },
695
+ }).then((r) => r.text()),
662
696
  delete: (aid: string, name: string, opts?: RequestOptions) =>
663
697
  this.json<{ name: string; deleted: boolean }>(
664
698
  "DELETE",
@@ -1034,6 +1068,18 @@ export class IngramCloud {
1034
1068
  }),
1035
1069
  delete: (wid: string, opts?: RequestOptions) =>
1036
1070
  this.empty("DELETE", `/tenant/webhooks/${enc(wid)}`, opts),
1071
+ /** Rotate the signing secret, returning the new one exactly once. Pass
1072
+ * `grace_seconds` to keep the old secret accepted during an overlap window. */
1073
+ rotateSecret: (
1074
+ wid: string,
1075
+ body?: z.input<typeof WebhookRotateIn>,
1076
+ opts?: RequestOptions,
1077
+ ) =>
1078
+ this.json<z.infer<typeof WebhookRotateOut>>(
1079
+ "POST",
1080
+ `/tenant/webhooks/${enc(wid)}/rotate_secret`,
1081
+ { ...opts, body: body ?? {} },
1082
+ ),
1037
1083
  test: (wid: string, opts?: RequestOptions) =>
1038
1084
  this.json<{ delivered: boolean }>(
1039
1085
  "POST",
@@ -1210,7 +1256,8 @@ export class IngramCloud {
1210
1256
  },
1211
1257
  };
1212
1258
 
1213
- // ── Organization (org token: projects + billing) ────────────────────────
1259
+ // ── Organization (org token: projects + tokens) ─────────────────────────
1260
+ // Note: the `/v1/organization/billing/*` surface is not yet wrapped here.
1214
1261
 
1215
1262
  readonly organization = {
1216
1263
  projects: {
package/ts/zod/agents.ts CHANGED
@@ -72,6 +72,8 @@ export const AgentDraft = z
72
72
  model: z.string().nullable(),
73
73
  enabled_hosted_tools: z.array(z.string()),
74
74
  vector_store_ids: z.array(z.string()),
75
+ /** Registered MCP servers this agent's smiths load, by name. Null = all. */
76
+ mcp_servers: z.array(z.string()).nullable(),
75
77
  auto_memory: z.boolean().nullable(),
76
78
  memory_consolidation: z.boolean().nullable(),
77
79
  variables: z.array(AgentVariable),
@@ -93,6 +95,8 @@ export const AgentOut = z
93
95
  rollout_version: z.number().int().nullable(),
94
96
  rollout_percent: z.number().int(),
95
97
  smith_count: z.number().int().optional(),
98
+ /** Newest run across every smith of this agent. Null until one runs. */
99
+ last_activity_at: z.string().nullable().optional(),
96
100
  created_at: z.string().nullable(),
97
101
  updated_at: z.string().nullable(),
98
102
  })
@@ -109,6 +113,7 @@ export const AgentVersionOut = z
109
113
  model: z.string().nullish(),
110
114
  enabled_hosted_tools: z.array(z.string()).optional(),
111
115
  vector_store_ids: z.array(z.string()).optional(),
116
+ mcp_servers: z.array(z.string()).nullish(),
112
117
  auto_memory: z.boolean().nullish(),
113
118
  memory_consolidation: z.boolean().nullish(),
114
119
  variables: z.array(AgentVariable).optional(),
@@ -134,6 +139,8 @@ export const AgentIn = z
134
139
  model: z.string().nullish(),
135
140
  enabled_hosted_tools: z.array(z.string()).nullish(),
136
141
  vector_store_ids: z.array(z.string()).nullish(),
142
+ /** Scope runs to these registered MCP servers (by name). Null/omitted = all. */
143
+ mcp_servers: z.array(z.string()).nullish(),
137
144
  auto_memory: z.boolean().nullish(),
138
145
  memory_consolidation: z.boolean().nullish(),
139
146
  variables: z.array(AgentVariable).nullish(),
@@ -147,6 +154,9 @@ export const AgentPatch = z
147
154
  model: z.string().nullish(),
148
155
  enabled_hosted_tools: z.array(z.string()).nullish(),
149
156
  vector_store_ids: z.array(z.string()).nullish(),
157
+ /** Scope runs to these registered MCP servers (by name). An explicit null
158
+ * clears the restriction (= all); omitted leaves it unchanged. */
159
+ mcp_servers: z.array(z.string()).nullish(),
150
160
  auto_memory: z.boolean().nullish(),
151
161
  memory_consolidation: z.boolean().nullish(),
152
162
  variables: z.array(AgentVariable).nullish(),
package/ts/zod/mcp.ts CHANGED
@@ -72,11 +72,17 @@ export const McpServerOut = z
72
72
  approval_policy: z.array(ApprovalRule).optional(),
73
73
  tools: z.array(McpTool),
74
74
  tools_refreshed_at: z.string().nullable(),
75
- /** `degraded` when the edge failed discovery or its secret can't be decoded
76
- * at run time; otherwise the stored lifecycle status. */
75
+ /** `degraded` when the edge failed discovery, its secret can't be decoded at
76
+ * run time, or its last `tools/call` failed at the transport level;
77
+ * otherwise the stored lifecycle status. */
77
78
  status: z.string(),
78
- /** Last discovery/runtime-load failure, or null when the edge is healthy. */
79
+ /** Last discovery/runtime-load failure, or null when discovery is healthy. */
79
80
  discovery_error: z.string().nullable(),
81
+ /** Last transport-level `tools/call` failure (network / HTTP status), or
82
+ * null. Discovery can succeed while calls fail — this catches that. Cleared
83
+ * by a successful call or a re-PUT. */
84
+ last_call_error: z.string().nullable(),
85
+ last_call_error_at: z.string().nullable(),
80
86
  created_at: z.string().nullable(),
81
87
  })
82
88
  .meta({ id: "McpServerOut" });
@@ -105,7 +111,9 @@ export const McpAuthIn = z
105
111
  .meta({ id: "McpAuthIn" });
106
112
 
107
113
  /** Register or replace a server: supply a raw `url` + `auth`, or a `catalog`
108
- * slug (catalog defaults are stamped down, body fields override). */
114
+ * slug (catalog defaults are stamped down, body fields override). PUT is a
115
+ * full replace and `auth.kind` is required unless a catalog preset supplies
116
+ * it — there is no implicit `none`. */
109
117
  export const McpServerIn = z
110
118
  .object({
111
119
  url: z.string().nullish(),
@@ -67,6 +67,7 @@ export const TraceOut = z
67
67
  id: z.string(),
68
68
  smith_id: z.string(),
69
69
  app_id: z.string().nullable(),
70
+ run_id: z.string().nullable(),
70
71
  root_kind: ICSpanKindEnum,
71
72
  name: z.string(),
72
73
  status: z.string(),
@@ -26,8 +26,11 @@ export const SmithRevisionOut = z
26
26
  model: z.string().nullish(),
27
27
  enabled_hosted_tools: z.array(z.string()).optional(),
28
28
  vector_store_ids: z.array(z.string()).optional(),
29
- auto_memory: z.boolean().optional(),
30
- memory_consolidation: z.boolean().optional(),
29
+ mcp_servers: z.array(z.string()).nullish(),
30
+ // Nullish: a snapshot taken while the smith inherited a sparse agent
31
+ // version carries null (= the default) for these.
32
+ auto_memory: z.boolean().nullish(),
33
+ memory_consolidation: z.boolean().nullish(),
31
34
  }),
32
35
  created_by: z.string().nullish(),
33
36
  note: z.string().nullish(),
package/ts/zod/smiths.ts CHANGED
@@ -38,6 +38,8 @@ export const SmithOut = z
38
38
  rendered_instructions: z.string().nullish(),
39
39
  enabled_hosted_tools: z.array(z.string()).optional(),
40
40
  vector_store_ids: z.array(z.string()).optional(),
41
+ /** Registered MCP servers this smith's runs load, by name. Null = all. */
42
+ mcp_servers: z.array(z.string()).nullish(),
41
43
  auto_memory: z.boolean().optional(),
42
44
  memory_consolidation: z.boolean().optional(),
43
45
  /** How the config resolved: by reference, with overrides, or embedded. */
@@ -57,6 +59,7 @@ export const SmithOut = z
57
59
  instructions: z.string().nullable(),
58
60
  enabled_hosted_tools: z.array(z.string()),
59
61
  vector_store_ids: z.array(z.string()),
62
+ mcp_servers: z.array(z.string()).nullable(),
60
63
  auto_memory: z.boolean().nullable(),
61
64
  memory_consolidation: z.boolean().nullable(),
62
65
  })
@@ -90,6 +93,8 @@ export const SmithCreate = z
90
93
  instructions: z.string().nullish(),
91
94
  enabled_hosted_tools: z.array(z.string()).nullish(),
92
95
  vector_store_ids: z.array(z.string()).nullish(),
96
+ /** Scope this smith's runs to these registered MCP servers (by name). */
97
+ mcp_servers: z.array(z.string()).nullish(),
93
98
  auto_memory: z.boolean().nullish(),
94
99
  memory_consolidation: z.boolean().nullish(),
95
100
  })
@@ -108,6 +113,9 @@ export const SmithPatch = z
108
113
  instructions: z.string().nullish(),
109
114
  enabled_hosted_tools: z.array(z.string()).nullish(),
110
115
  vector_store_ids: z.array(z.string()).nullish(),
116
+ /** Scope this smith's runs to these registered MCP servers (by name).
117
+ * Null clears the per-smith override (re-inherit the agent's value). */
118
+ mcp_servers: z.array(z.string()).nullish(),
111
119
  auto_memory: z.boolean().nullish(),
112
120
  memory_consolidation: z.boolean().nullish(),
113
121
  })
package/ts/zod/tenant.ts CHANGED
@@ -78,6 +78,25 @@ export const WebhookPatch = z
78
78
  })
79
79
  .meta({ id: "WebhookPatch" });
80
80
 
81
+ /** Rotate a webhook's signing secret. `grace_seconds` keeps the outgoing secret
82
+ * valid for an overlap window (default 24h, 0 = cut over immediately, max 7d);
83
+ * during it every delivery is signed with both the new and old secret. */
84
+ export const WebhookRotateIn = z
85
+ .object({
86
+ grace_seconds: z.number().int().min(0).max(604800).default(86400),
87
+ })
88
+ .meta({ id: "WebhookRotateIn" });
89
+
90
+ /** The rotate response — the new signing `secret` is returned EXACTLY ONCE, here.
91
+ * `previous_secret_expires_at` is when the old secret stops being accepted. */
92
+ export const WebhookRotateOut = z
93
+ .object({
94
+ id: z.string(),
95
+ secret: z.string(),
96
+ previous_secret_expires_at: z.string().nullable(),
97
+ })
98
+ .meta({ id: "WebhookRotateOut" });
99
+
81
100
  /** One persisted delivery attempt record for a webhook — the audit trail behind
82
101
  * durable, retried delivery. `status` is `pending` | `succeeded` | `dead`. */
83
102
  export const WebhookDeliveryOut = z
@@ -7,9 +7,11 @@
7
7
  * filter grammar, and the `search_results.page` envelope are OpenAI's, wart for
8
8
  * wart (modify is `POST`, the batch object is `vector_store.files_batch`, the
9
9
  * search page uses a `next_page` token while CRUD lists use `first_id`/
10
- * `last_id`). `smith_id` is the one documented IC extension: it scopes a store
11
- * to a single smith ("" = tenant-wide), the same isolation boundary every other
12
- * smith-owned resource has. Expiration policies (`expires_after`), query
10
+ * `last_id`). Two documented IC extensions: `smith_id` scopes a store to a
11
+ * single smith ("" = tenant-wide), the same isolation boundary every other
12
+ * smith-owned resource has; `embedding_model` names the store's embedder,
13
+ * frozen at create (OpenAI pins one platform-wide, Gemini's File Search exposes
14
+ * it the same way). Expiration policies (`expires_after`), query
13
15
  * rewriting, and rankers are not implemented — the fields don't exist here
14
16
  * rather than being accepted and ignored.
15
17
  */
@@ -95,6 +97,11 @@ export const VectorStoreIn = z
95
97
  metadata: z.record(z.string(), z.unknown()).optional(),
96
98
  /** IC extension: own the store to one smith ("" / omitted = tenant-wide). */
97
99
  smith_id: z.string().optional(),
100
+ /** IC extension: the embedder to index and query this store with, frozen at
101
+ * create (omitted = the platform default). Any model your OpenAI-provider
102
+ * key can reach — including an EU-hosted OpenAI-compatible endpoint set as
103
+ * that key's `base_url` — of at most 1536 dimensions. */
104
+ embedding_model: z.string().optional(),
98
105
  })
99
106
  .meta({ id: "VectorStoreIn" });
100
107
 
@@ -124,6 +131,9 @@ export const VectorStoreOut = z
124
131
  metadata: z.record(z.string(), z.unknown()),
125
132
  /** IC extension: the owning smith ("" = tenant-wide). */
126
133
  smith_id: z.string(),
134
+ /** IC extension: the embedder this store is indexed and queried with,
135
+ * frozen at create. */
136
+ embedding_model: z.string(),
127
137
  })
128
138
  .meta({ id: "VectorStoreOut" });
129
139
 
@@ -176,7 +186,12 @@ export const VectorStoreFileOut = z
176
186
  status: z.enum(["in_progress", "completed", "failed", "cancelled"]),
177
187
  last_error: z
178
188
  .object({
179
- code: z.enum(["server_error", "unsupported_file", "invalid_file"]),
189
+ code: z.enum([
190
+ "server_error",
191
+ "unsupported_file",
192
+ "no_text_layer",
193
+ "invalid_file",
194
+ ]),
180
195
  message: z.string(),
181
196
  })
182
197
  .nullable(),
@@ -202,6 +217,18 @@ export const VectorStoreFileUpdate = z
202
217
  })
203
218
  .meta({ id: "VectorStoreFileUpdate" });
204
219
 
220
+ /** The parsed text a file was indexed as, chunk by chunk, in OpenAI's
221
+ * `vector_store.file_content.page` envelope. The whole file is one page — the
222
+ * paging fields are the envelope's shape, not a promise of more. */
223
+ export const VectorStoreFileContentOut = z
224
+ .object({
225
+ object: z.literal("vector_store.file_content.page"),
226
+ data: z.array(z.object({ type: z.literal("text"), text: z.string() })),
227
+ has_more: z.literal(false),
228
+ next_page: z.null(),
229
+ })
230
+ .meta({ id: "VectorStoreFileContentOut" });
231
+
205
232
  export const VectorStoreFileDeleted = z
206
233
  .object({
207
234
  id: z.string(),
@@ -291,6 +318,7 @@ export const VectorStoreSearchOut = z
291
318
 
292
319
  export type ICVectorStore = z.infer<typeof VectorStoreOut>;
293
320
  export type ICVectorStoreFile = z.infer<typeof VectorStoreFileOut>;
321
+ export type ICVectorStoreFileContentPage = z.infer<typeof VectorStoreFileContentOut>;
294
322
  export type ICVectorStoreFileBatch = z.infer<typeof VectorStoreFileBatchOut>;
295
323
  export type ICVectorStoreSearchPage = z.infer<typeof VectorStoreSearchOut>;
296
324
  export type ICVectorStoreAttributes = z.infer<typeof VectorStoreAttributes>;