@ingram-cloud/sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +74 -0
  2. package/dist/client.js +460 -0
  3. package/dist/events.js +108 -0
  4. package/dist/index.js +19 -0
  5. package/dist/responses.js +12 -0
  6. package/dist/schemas.js +4 -0
  7. package/dist/zod/_page.js +17 -0
  8. package/dist/zod/agents.js +176 -0
  9. package/dist/zod/approvals.js +38 -0
  10. package/dist/zod/budgets.js +62 -0
  11. package/dist/zod/catalog.js +49 -0
  12. package/dist/zod/connections.js +75 -0
  13. package/dist/zod/conversations.js +91 -0
  14. package/dist/zod/customers.js +53 -0
  15. package/dist/zod/deployments.js +81 -0
  16. package/dist/zod/discord.js +32 -0
  17. package/dist/zod/email.js +45 -0
  18. package/dist/zod/files.js +55 -0
  19. package/dist/zod/index.js +35 -0
  20. package/dist/zod/mcp.js +107 -0
  21. package/dist/zod/memories.js +43 -0
  22. package/dist/zod/observability.js +133 -0
  23. package/dist/zod/projects.js +58 -0
  24. package/dist/zod/runs.js +119 -0
  25. package/dist/zod/schedules.js +71 -0
  26. package/dist/zod/slack.js +69 -0
  27. package/dist/zod/smith-revisions.js +42 -0
  28. package/dist/zod/smiths.js +108 -0
  29. package/dist/zod/telegram.js +36 -0
  30. package/dist/zod/tenant.js +219 -0
  31. package/dist/zod/vector-stores.js +251 -0
  32. package/dist/zod/whatsapp.js +47 -0
  33. package/package.json +56 -0
  34. package/ts/client.ts +1187 -0
  35. package/ts/events.ts +119 -0
  36. package/ts/index.ts +20 -0
  37. package/ts/responses.ts +83 -0
  38. package/ts/schemas.ts +4 -0
  39. package/ts/zod/_page.ts +18 -0
  40. package/ts/zod/agents.ts +202 -0
  41. package/ts/zod/approvals.ts +44 -0
  42. package/ts/zod/budgets.ts +75 -0
  43. package/ts/zod/catalog.ts +57 -0
  44. package/ts/zod/connections.ts +87 -0
  45. package/ts/zod/conversations.ts +103 -0
  46. package/ts/zod/customers.ts +62 -0
  47. package/ts/zod/deployments.ts +93 -0
  48. package/ts/zod/discord.ts +39 -0
  49. package/ts/zod/email.ts +52 -0
  50. package/ts/zod/files.ts +62 -0
  51. package/ts/zod/index.ts +35 -0
  52. package/ts/zod/mcp.ts +123 -0
  53. package/ts/zod/memories.ts +53 -0
  54. package/ts/zod/observability.ts +155 -0
  55. package/ts/zod/projects.ts +68 -0
  56. package/ts/zod/runs.ts +135 -0
  57. package/ts/zod/schedules.ts +82 -0
  58. package/ts/zod/slack.ts +79 -0
  59. package/ts/zod/smith-revisions.ts +50 -0
  60. package/ts/zod/smiths.ts +118 -0
  61. package/ts/zod/telegram.ts +43 -0
  62. package/ts/zod/tenant.ts +267 -0
  63. package/ts/zod/vector-stores.ts +296 -0
  64. package/ts/zod/whatsapp.ts +54 -0
package/ts/events.ts ADDED
@@ -0,0 +1,119 @@
1
+ /**
2
+ * The Ingram Cloud event types — HAND-AUTHORED (not generated).
3
+ *
4
+ * Two event surfaces ride the native `{v:1}` envelope and are deliberately NOT in
5
+ * `openapi.json`: OpenAPI can't describe an SSE frame sequence (even OpenAI's own
6
+ * spec doesn't type its stream chunks — SDKs hand-define them). So these live
7
+ * here, hand-authored, and must be kept in step with
8
+ * `web/src/content/docs/events.md` (the canonical catalog).
9
+ *
10
+ * 1. {@link webhookEvent} — the append-only feed / webhook delivery envelope
11
+ * (`GET /v1/events`, signed webhook POSTs).
12
+ * 2. {@link streamFrame} — the live SSE run-stream frames (`POST .../runs` with
13
+ * `stream:true`), i.e. `runs.py::_stream`.
14
+ *
15
+ * `data` is `.passthrough()` on purpose: the catalog documents the *notable*
16
+ * fields per type, not an exhaustive closed shape — same philosophy as the
17
+ * `extra="allow"` response models. Consumers narrow on `type` / `event`.
18
+ */
19
+ import { z } from "zod";
20
+
21
+ // ─── Feed / webhook event types (docs/events.md "Event type catalog") ────────
22
+ // Only these reach the `/v1/events` feed and signed webhooks. Pure run-stream frames
23
+ // — `run.started`, `message.delta`, `message.completed`, `run.cancelled` — ride the
24
+ // live SSE stream and the per-run timeline only; they are NOT feed events (see
25
+ // {@link STREAM_EVENTS}). `tool.executing` / `tool.completed` are both: a live frame
26
+ // AND a feed event.
27
+ export const EVENT_TYPES = [
28
+ "run.paused",
29
+ "run.completed",
30
+ "run.failed",
31
+ "tool.executing",
32
+ "tool.completed",
33
+ "approval.required",
34
+ "approval.resolved",
35
+ "connection.required",
36
+ "unbound_message",
37
+ "budget.threshold",
38
+ "credit.exhausted",
39
+ "deployment.bound",
40
+ "deployment.inbound",
41
+ "slack.app_provisioned",
42
+ "slack.install",
43
+ "slack.uninstalled",
44
+ "email.send_failed",
45
+ "webhook.test",
46
+ ] as const;
47
+
48
+ export const eventType = z.enum(EVENT_TYPES);
49
+ export type EventType = z.infer<typeof eventType>;
50
+
51
+ /**
52
+ * The envelope carried identically by the `/v1/events` feed and signed webhook
53
+ * POSTs. `type` is a plain string (not the enum) so a forward-added type still
54
+ * parses; compare against {@link EVENT_TYPES} / {@link eventType} when narrowing.
55
+ */
56
+ export const webhookEvent = z
57
+ .object({
58
+ v: z.literal(1),
59
+ id: z.string(),
60
+ type: z.string(),
61
+ created_at: z.string(),
62
+ tenant_id: z.string(),
63
+ smith_id: z.string().nullable().optional(),
64
+ data: z.record(z.string(), z.unknown()).default({}),
65
+ })
66
+ .passthrough();
67
+ export type WebhookEvent = z.infer<typeof webhookEvent>;
68
+
69
+ // ─── Native SSE run-stream frames (runs.py::_stream `{v:1, run_id, ...}`) ─────
70
+ // The SSE `event:` line becomes `event`; the frame's data fields sit alongside
71
+ // `v` / `run_id`. `tool.executing` / `tool.completed` ride the live stream as they
72
+ // happen AND are mirrored to the run timeline + feed (see EVENT_TYPES) so a run's
73
+ // tool activity is auditable after the fact. The standard surface expresses the same
74
+ // live status on the OpenAI Responses API (`/v1/responses`) as `mcp_call` items
75
+ // (`response.mcp_call.in_progress` / `.completed`); those are standard OpenAI shapes,
76
+ // so we don't re-type them here — consume them with the OpenAI/AI SDK. These native
77
+ // frames are the place to retire as that lands everywhere (see CLAUDE.md).
78
+ export const STREAM_EVENTS = [
79
+ "run.started",
80
+ "message.delta",
81
+ "tool.executing",
82
+ "tool.completed",
83
+ "run.paused",
84
+ "approval.required",
85
+ "run.completed",
86
+ "run.failed",
87
+ "run.cancelled",
88
+ "run.duplicate",
89
+ "message.completed",
90
+ ] as const;
91
+
92
+ export const streamEventName = z.enum(STREAM_EVENTS);
93
+ export type StreamEventName = z.infer<typeof streamEventName>;
94
+
95
+ export const streamFrame = z
96
+ .object({
97
+ event: z.string(),
98
+ v: z.number().optional(),
99
+ run_id: z.string().optional(),
100
+ })
101
+ .passthrough();
102
+ export type StreamFrame = z.infer<typeof streamFrame>;
103
+
104
+ // ─── A few well-known `data` shapes (convenience; still passthrough) ─────────
105
+ export const messageDeltaData = z.object({ delta: z.string() }).passthrough();
106
+ export const runCompletedData = z
107
+ .object({
108
+ stop_reason: z.string(),
109
+ usage: z.record(z.string(), z.unknown()).optional(),
110
+ })
111
+ .passthrough();
112
+ export const approvalRequiredData = z
113
+ .object({
114
+ approval_id: z.string(),
115
+ tool: z.string().nullable().optional(),
116
+ args: z.record(z.string(), z.unknown()).optional(),
117
+ })
118
+ .passthrough();
119
+ export const toolActivityData = z.object({ tool: z.string().nullable() }).passthrough();
package/ts/index.ts ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * The Ingram Cloud API wire contract, in TypeScript.
3
+ *
4
+ * `schemas` is the named map of hand-authored Zod schemas for the request and
5
+ * response bodies (defined in `./zod`, one module per resource). It's the source
6
+ * of truth for the wire shapes — the API imports the same schemas to validate
7
+ * requests and to emit its OpenAPI document — and you can use it to validate a
8
+ * body against the contract. This package is not an HTTP client.
9
+ *
10
+ * `./responses` is the matching `IC*` TypeScript types (inferred from the same
11
+ * schemas), for typing the JSON you read back without pulling in Zod.
12
+ *
13
+ * `./events` is the hand-authored `{v:1}` webhook/feed envelope and the SSE
14
+ * run-stream frames, which OpenAPI can't express.
15
+ *
16
+ * See `../README.md`.
17
+ */
18
+ export { schemas } from "./schemas.js";
19
+ export * from "./events.js";
20
+ export type * from "./responses.js";
@@ -0,0 +1,83 @@
1
+ /**
2
+ * TypeScript types for the `/v1` JSON response bodies — the consumer-facing
3
+ * companion to the wire schemas, imported by API consumers (e.g. the console) to
4
+ * type the JSON they read back.
5
+ *
6
+ * The `IC*` types are `z.infer`red from the hand-authored Zod in
7
+ * `./zod/<resource>` (the wire's source of truth) and re-exported here as
8
+ * **types** — so this module stays Zod-free for `import type` consumers. Only the
9
+ * list-envelope generics ({@link ICList}/{@link ICPaginatedResponse}) are
10
+ * declared inline, since they're generic over any resource.
11
+ */
12
+
13
+ /** The standard list envelope — a `data` array and nothing else. Most list
14
+ * endpoints return this. */
15
+ export interface ICList<T> {
16
+ data: T[];
17
+ }
18
+
19
+ /** A cursor-paginated list. The endpoints that page (smiths, memories,
20
+ * customers) add `has_more`, and some a `next_cursor`; the rest return the
21
+ * plain {@link ICList}. */
22
+ export interface ICPaginatedResponse<T> {
23
+ data: T[];
24
+ has_more: boolean;
25
+ next_cursor?: string | null;
26
+ }
27
+
28
+ // ── Re-exported from the hand-authored Zod source of truth (./zod/*) ──────────
29
+ export type {
30
+ ICAgent,
31
+ ICAgentVariable,
32
+ ICAgentVersion,
33
+ ICUiResource,
34
+ ICUiResourceTool,
35
+ } from "./zod/agents.js";
36
+ export type { ICApproval } from "./zod/approvals.js";
37
+ export type { ICBudget, ICBudgetStatus } from "./zod/budgets.js";
38
+ export type { ICCatalogEntry } from "./zod/catalog.js";
39
+ export type { ICConnection } from "./zod/connections.js";
40
+ export type { ICConversation, ICConversationItem } from "./zod/conversations.js";
41
+ export type { ICCustomer } from "./zod/customers.js";
42
+ export type { ICDeployment, ICDeploymentCreated } from "./zod/deployments.js";
43
+ export type { ICDiscordApp } from "./zod/discord.js";
44
+ export type { ICEmailConfig } from "./zod/email.js";
45
+ export type { ICFile, ICFileList } from "./zod/files.js";
46
+ export type { ICMcpServer, ICMcpTool, ICApprovalRule } from "./zod/mcp.js";
47
+ export type { ICWorkingMemory, ICRecallHit } from "./zod/memories.js";
48
+ export type {
49
+ ICSpanKind,
50
+ ICSpan,
51
+ ICSpanNode,
52
+ ICTrace,
53
+ ICTraceDetail,
54
+ ICUsageBreakdown,
55
+ } from "./zod/observability.js";
56
+ export type { ICProject } from "./zod/projects.js";
57
+ export type { ICRun, ICRunUsage, ICInputMessage, ICRunEvent } from "./zod/runs.js";
58
+ export type { ICSchedule } from "./zod/schedules.js";
59
+ export type { ICSlackApp } from "./zod/slack.js";
60
+ export type { ICSmith } from "./zod/smiths.js";
61
+ export type { ICSmithRevision } from "./zod/smith-revisions.js";
62
+ export type { ICTelegramBot } from "./zod/telegram.js";
63
+ export type {
64
+ ICEvent,
65
+ ICWebhook,
66
+ ICToken,
67
+ ICMintedToken,
68
+ ICUsage,
69
+ ICModel,
70
+ ICModelProvider,
71
+ ICModelCatalog,
72
+ ICModelKey,
73
+ ICProvider,
74
+ } from "./zod/tenant.js";
75
+ export type { ICWhatsAppConfig } from "./zod/whatsapp.js";
76
+ export type {
77
+ ICVectorStore,
78
+ ICVectorStoreFile,
79
+ ICVectorStoreFileBatch,
80
+ ICVectorStoreSearchPage,
81
+ ICVectorStoreAttributes,
82
+ ICVectorStoreFilter,
83
+ } from "./zod/vector-stores.js";
package/ts/schemas.ts ADDED
@@ -0,0 +1,4 @@
1
+ /** The wire's Zod schema map — the hand-authored schemas in ./zod, keyed by
2
+ * export name. Source of truth; consumed by the api test suite to validate
3
+ * wire shapes. (Replaces the former openapi-zod-client-generated file.) */
4
+ export * as schemas from "./zod/index.js";
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The shared cursor-paginated list envelope. One definition so every paginated
3
+ * `/v1` list reads back the same shape: `data` + the opaque `next_cursor` (null
4
+ * on the last page) + `has_more`. The cursor is an opaque, short-lived token —
5
+ * pass it straight back as `?cursor=`, never parse it.
6
+ */
7
+ import { z } from "zod";
8
+
9
+ /** Wrap an item schema as a cursor-paginated list out, named `id` in the spec. */
10
+ export function pageOut<T extends z.ZodTypeAny>(item: T, id: string) {
11
+ return z
12
+ .object({
13
+ data: z.array(item),
14
+ next_cursor: z.string().nullish(),
15
+ has_more: z.boolean(),
16
+ })
17
+ .meta({ id });
18
+ }
@@ -0,0 +1,202 @@
1
+ /**
2
+ * Hand-authored Zod schemas for the `agents` resource — the wire's source of
3
+ * truth, replacing the loose generated `schemas.ts` shapes for this resource.
4
+ *
5
+ * One source, three outputs: the API imports these into its `createRoute`
6
+ * definitions (validation + emitted OpenAPI), and the consumer-facing `IC*`
7
+ * types are `z.infer`red from them here and re-exported by `../responses`. No
8
+ * Zod is pulled into a type-only consumer — `responses.ts` re-exports these as
9
+ * `export type`.
10
+ *
11
+ * `.meta({ id })` names the component so the emitted OpenAPI references it as
12
+ * `#/components/schemas/<id>` rather than inlining it.
13
+ */
14
+ import { z } from "zod";
15
+ import { pageOut } from "./_page.js";
16
+
17
+ /** A per-smith variable an agent declares; bound at run time. */
18
+ export const AgentVariable = z
19
+ .object({
20
+ name: z.string(),
21
+ default: z.string().nullish(),
22
+ description: z.string().nullish(),
23
+ required: z.boolean().optional(),
24
+ })
25
+ .meta({ id: "AgentVariable" });
26
+
27
+ /** A predeclared UI-backed capability (Rung 2) bound to a UI template — the MCP
28
+ * host's model calls it as a typed tool and the template renders the result. */
29
+ export const UiResourceTool = z
30
+ .object({
31
+ description: z.string(),
32
+ /** JSON Schema for the tool's arguments (host-supplied). */
33
+ input_schema: z.record(z.string(), z.unknown()).optional(),
34
+ /** Scoped instruction the smith runs with when this tool is called. */
35
+ instruction: z.string().nullish(),
36
+ /** Writes gate through approval; reads flow freely (OpenUI Query/Mutation). */
37
+ mutating: z.boolean().optional(),
38
+ })
39
+ .meta({ id: "UiResourceTool" });
40
+
41
+ /** CSP domain allowlists for the sandboxed iframe — the MCP Apps `_meta.ui.csp`
42
+ * shape (each key a list of allowed origins), passed through to the host verbatim. */
43
+ export const UiCsp = z
44
+ .object({
45
+ connectDomains: z.array(z.string()).optional(),
46
+ resourceDomains: z.array(z.string()).optional(),
47
+ frameDomains: z.array(z.string()).optional(),
48
+ baseUriDomains: z.array(z.string()).optional(),
49
+ })
50
+ .meta({ id: "UiCsp" });
51
+
52
+ /** A tenant-authored interactive UI template (MCP Apps, SEP-1865) attached to an
53
+ * agent. The HTML bundle lives in blob storage; this is its wire metadata (the
54
+ * internal blob ref is never exposed). `csp`/`permissions` mirror the standard
55
+ * `_meta.ui` shape and are echoed to the host on `resources/read`. */
56
+ export const UiResource = z
57
+ .object({
58
+ name: z.string(),
59
+ content_hash: z.string(),
60
+ csp: UiCsp.optional(),
61
+ /** Host permissions the template requests, a Permissions-Policy-style map
62
+ * (e.g. `{ "camera": {}, "microphone": {} }`). */
63
+ permissions: z.record(z.string(), z.unknown()).optional(),
64
+ tool: UiResourceTool.nullish(),
65
+ })
66
+ .meta({ id: "UiResource" });
67
+
68
+ /** The mutable draft head — what the next publish snapshots. */
69
+ export const AgentDraft = z
70
+ .object({
71
+ instructions: z.string().nullable(),
72
+ model: z.string().nullable(),
73
+ enabled_hosted_tools: z.array(z.string()),
74
+ vector_store_ids: z.array(z.string()),
75
+ auto_memory: z.boolean().nullable(),
76
+ memory_consolidation: z.boolean().nullable(),
77
+ variables: z.array(AgentVariable),
78
+ ui_resources: z.array(UiResource),
79
+ })
80
+ .meta({ id: "AgentDraft" });
81
+
82
+ export const AgentOut = z
83
+ .object({
84
+ id: z.string(),
85
+ /** Immutable, project-unique IaC reconcile key. Null for the default agent. */
86
+ slug: z.string().nullable(),
87
+ /** Free, mutable display label (not unique). */
88
+ name: z.string(),
89
+ /** True for the lazily-created default agent (can't be deleted). */
90
+ is_default: z.boolean(),
91
+ draft: AgentDraft,
92
+ active_version: z.number().int().nullable(),
93
+ rollout_version: z.number().int().nullable(),
94
+ rollout_percent: z.number().int(),
95
+ smith_count: z.number().int().optional(),
96
+ created_at: z.string().nullable(),
97
+ updated_at: z.string().nullable(),
98
+ })
99
+ .meta({ id: "AgentOut" });
100
+
101
+ export const AgentListOut = pageOut(AgentOut, "AgentListOut");
102
+
103
+ /** A published, immutable version snapshot of an agent. */
104
+ export const AgentVersionOut = z
105
+ .object({
106
+ version: z.number().int(),
107
+ snapshot: z.object({
108
+ instructions: z.string().nullish(),
109
+ model: z.string().nullish(),
110
+ enabled_hosted_tools: z.array(z.string()).optional(),
111
+ vector_store_ids: z.array(z.string()).optional(),
112
+ auto_memory: z.boolean().nullish(),
113
+ memory_consolidation: z.boolean().nullish(),
114
+ variables: z.array(AgentVariable).optional(),
115
+ ui_resources: z.array(UiResource).optional(),
116
+ }),
117
+ created_by: z.string().nullable(),
118
+ note: z.string().nullable(),
119
+ created_at: z.string().nullable(),
120
+ })
121
+ .meta({ id: "AgentVersionOut" });
122
+
123
+ export const AgentVersionListOut = z
124
+ .object({ data: z.array(AgentVersionOut) })
125
+ .meta({ id: "AgentVersionListOut" });
126
+
127
+ // ── Request bodies ──────────────────────────────────────────────────────────
128
+
129
+ export const AgentIn = z
130
+ .object({
131
+ name: z.string(),
132
+ slug: z.string().nullish(),
133
+ instructions: z.string().nullish(),
134
+ model: z.string().nullish(),
135
+ enabled_hosted_tools: z.array(z.string()).nullish(),
136
+ vector_store_ids: z.array(z.string()).nullish(),
137
+ auto_memory: z.boolean().nullish(),
138
+ memory_consolidation: z.boolean().nullish(),
139
+ variables: z.array(AgentVariable).nullish(),
140
+ })
141
+ .meta({ id: "AgentIn" });
142
+
143
+ export const AgentPatch = z
144
+ .object({
145
+ name: z.string().nullish(),
146
+ instructions: z.string().nullish(),
147
+ model: z.string().nullish(),
148
+ enabled_hosted_tools: z.array(z.string()).nullish(),
149
+ vector_store_ids: z.array(z.string()).nullish(),
150
+ auto_memory: z.boolean().nullish(),
151
+ memory_consolidation: z.boolean().nullish(),
152
+ variables: z.array(AgentVariable).nullish(),
153
+ })
154
+ .meta({ id: "AgentPatch" });
155
+
156
+ export const RolloutIn = z
157
+ .object({
158
+ version: z.number().int(),
159
+ percent: z.number().int().min(0).max(100).default(100),
160
+ })
161
+ .meta({ id: "RolloutIn" });
162
+
163
+ export const PublishIn = z
164
+ .object({ note: z.string().nullish() })
165
+ .meta({ id: "PublishIn" });
166
+
167
+ export const ImportIn = z
168
+ .object({ from_smith: z.string(), name: z.string() })
169
+ .meta({ id: "ImportIn" });
170
+
171
+ export const AttachIn = z
172
+ .object({
173
+ all: z.boolean().default(false),
174
+ smith_ids: z.array(z.string()).nullish(),
175
+ })
176
+ .meta({ id: "AttachIn" });
177
+
178
+ /** The JSON `metadata` part of a UI-template multipart upload (the HTML bundle
179
+ * rides the `file` part). */
180
+ export const UiResourceIn = z
181
+ .object({
182
+ name: z
183
+ .string()
184
+ .regex(/^[a-z0-9][a-z0-9_-]*$/, "lowercase letters, digits, - and _")
185
+ .max(63),
186
+ csp: UiCsp.nullish(),
187
+ permissions: z.record(z.string(), z.unknown()).nullish(),
188
+ tool: UiResourceTool.nullish(),
189
+ })
190
+ .meta({ id: "UiResourceIn" });
191
+
192
+ export const UiResourceListOut = z
193
+ .object({ data: z.array(UiResource) })
194
+ .meta({ id: "UiResourceListOut" });
195
+
196
+ // ── Inferred consumer-facing types (re-exported by ../responses) ─────────────
197
+
198
+ export type ICAgentVariable = z.infer<typeof AgentVariable>;
199
+ export type ICAgent = z.infer<typeof AgentOut>;
200
+ export type ICAgentVersion = z.infer<typeof AgentVersionOut>;
201
+ export type ICUiResource = z.infer<typeof UiResource>;
202
+ export type ICUiResourceTool = z.infer<typeof UiResourceTool>;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Hand-authored Zod schemas for the `approvals` resource — the wire's source of
3
+ * truth, replacing the loose generated `schemas.ts` shapes for this resource.
4
+ *
5
+ * One source, three outputs: the API imports these into its `createRoute`
6
+ * definitions (validation + emitted OpenAPI), and the consumer-facing `IC*`
7
+ * types are `z.infer`red from them here and re-exported by `../responses`. No
8
+ * Zod is pulled into a type-only consumer — `responses.ts` re-exports these as
9
+ * `export type`.
10
+ *
11
+ * `.meta({ id })` names the component so the emitted OpenAPI references it as
12
+ * `#/components/schemas/<id>` rather than inlining it.
13
+ *
14
+ * The approvals route is read-only (list + get); there is no decision/submit
15
+ * body here — approvals are resolved on the standard tool-call channel via the
16
+ * run's `/submit`, not a bespoke endpoint.
17
+ */
18
+ import { z } from "zod";
19
+ import { pageOut } from "./_page.js";
20
+
21
+ /** A first-class human-in-the-loop decision raised by a paused run. */
22
+ export const ApprovalOut = z
23
+ .object({
24
+ id: z.string(),
25
+ run_id: z.string().nullable(),
26
+ smith_id: z.string().nullable(),
27
+ tool_call_id: z.string().nullable(),
28
+ tool: z.string().nullable(),
29
+ /** The tool-call arguments awaiting a decision; `{}` when none. */
30
+ args: z.record(z.string(), z.unknown()),
31
+ /** pending | approved | rejected. */
32
+ status: z.string(),
33
+ actor: z.string().nullable(),
34
+ reason: z.string().nullable(),
35
+ created_at: z.string().nullable(),
36
+ resolved_at: z.string().nullable(),
37
+ })
38
+ .meta({ id: "ApprovalOut" });
39
+
40
+ export const ApprovalListOut = pageOut(ApprovalOut, "ApprovalListOut");
41
+
42
+ // ── Inferred consumer-facing types (re-exported by ../responses) ─────────────
43
+
44
+ export type ICApproval = z.infer<typeof ApprovalOut>;
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Hand-authored Zod schemas for the `budgets` resource — the wire's source of
3
+ * truth, replacing the loose generated `schemas.ts` shapes for this resource.
4
+ *
5
+ * One source, three outputs: the API imports these into its `createRoute`
6
+ * definitions (validation + emitted OpenAPI), and the consumer-facing `IC*`
7
+ * types are `z.infer`red from them here and re-exported by `../responses`. No
8
+ * Zod is pulled into a type-only consumer — `responses.ts` re-exports these as
9
+ * `export type`.
10
+ *
11
+ * `.meta({ id })` names the component so the emitted OpenAPI references it as
12
+ * `#/components/schemas/<id>` rather than inlining it.
13
+ */
14
+ import { z } from "zod";
15
+
16
+ /** What a budget caps; `agent`/`smith`/`customer` budgets carry the id in
17
+ * `scope_id` (an agent design, a single smith, or one of your customers). */
18
+ export const BudgetScope = z.enum(["tenant", "agent", "smith", "customer"]);
19
+
20
+ /** Whether crossing the cap warns or blocks new runs. */
21
+ export const BudgetAction = z.enum(["warn", "block"]);
22
+
23
+ /** A monthly spend cap on a scope. `limit` is in `currency` — the platform billing
24
+ * currency (EUR by default), not necessarily USD; the field is currency-agnostic. */
25
+ export const BudgetOut = z
26
+ .object({
27
+ id: z.string(),
28
+ scope: BudgetScope,
29
+ scope_id: z.string().nullish(),
30
+ period: z.string(),
31
+ limit: z.number(),
32
+ // ISO-4217, lower-case. The denomination of `limit` and `/status`'s `spent`.
33
+ currency: z.string(),
34
+ action: BudgetAction,
35
+ created_at: z.string().nullish(),
36
+ })
37
+ .meta({ id: "BudgetOut" });
38
+
39
+ /** A budget plus its month-to-date spend, computed by `/status`. */
40
+ export const BudgetStatusOut = BudgetOut.extend({
41
+ period_start: z.string(),
42
+ period_key: z.string(),
43
+ spent: z.number(),
44
+ pct: z.number(),
45
+ over: z.boolean(),
46
+ }).meta({ id: "BudgetStatusOut" });
47
+
48
+ export const BudgetListOut = z
49
+ .object({ data: z.array(BudgetOut) })
50
+ .meta({ id: "BudgetListOut" });
51
+
52
+ // ── Request bodies ──────────────────────────────────────────────────────────
53
+
54
+ export const BudgetIn = z
55
+ .object({
56
+ scope: z.string(),
57
+ scope_id: z.string().nullish(),
58
+ // The cap, in the platform billing currency (EUR by default).
59
+ limit: z.number(),
60
+ action: z.string().default("warn"),
61
+ period: z.string().default("monthly"),
62
+ })
63
+ .meta({ id: "BudgetIn" });
64
+
65
+ export const BudgetPatch = z
66
+ .object({
67
+ limit: z.number().nullish(),
68
+ action: z.string().nullish(),
69
+ })
70
+ .meta({ id: "BudgetPatch" });
71
+
72
+ // ── Inferred consumer-facing types (re-exported by ../responses) ─────────────
73
+
74
+ export type ICBudget = z.infer<typeof BudgetOut>;
75
+ export type ICBudgetStatus = z.infer<typeof BudgetStatusOut>;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Hand-authored Zod schemas for the `catalog` resource — the Ingram-curated MCP
3
+ * integration presets exposed at `GET /v1/catalog`.
4
+ *
5
+ * One source, three outputs: the API imports these into its `createRoute`
6
+ * definitions (validation + emitted OpenAPI), and the consumer-facing `IC*`
7
+ * type is `z.infer`red from them here and re-exported by `../responses`. No Zod
8
+ * is pulled into a type-only consumer — `responses.ts` re-exports these as
9
+ * `export type`.
10
+ *
11
+ * `.meta({ id })` names the component so the emitted OpenAPI references it as
12
+ * `#/components/schemas/<id>` rather than inlining it.
13
+ */
14
+ import { z } from "zod";
15
+
16
+ /**
17
+ * The approval-rule shape a catalog entry carries as its `default_approval_policy`.
18
+ *
19
+ * Defined inline (not imported from `./mcp`) to keep this module independent of
20
+ * the parallel mcp authoring. It mirrors the canonical mcp `ApprovalRule`:
21
+ * a tool-name `match` glob and an optional `require` mode.
22
+ */
23
+ const ApprovalRule = z.object({
24
+ match: z.string(),
25
+ require: z.string().optional(),
26
+ });
27
+
28
+ /** How a catalog integration authenticates; surfaced flattened on the wire. */
29
+ const CatalogAuth = z.object({
30
+ kind: z.string(),
31
+ provider: z.string().nullable(),
32
+ client_mode: z.string(),
33
+ });
34
+
35
+ export const CatalogEntryOut = z
36
+ .object({
37
+ slug: z.string(),
38
+ display_name: z.string(),
39
+ description: z.string(),
40
+ mcp_url: z.string(),
41
+ auth: CatalogAuth,
42
+ scopes: z.array(z.string()),
43
+ /** null = expose all discovered tools; otherwise the default-deny set. */
44
+ default_allowlist: z.array(z.string()).nullable(),
45
+ default_approval_policy: z.array(ApprovalRule),
46
+ logo_url: z.string().nullable(),
47
+ docs_url: z.string().nullable(),
48
+ })
49
+ .meta({ id: "CatalogEntryOut" });
50
+
51
+ export const CatalogListOut = z
52
+ .object({ data: z.array(CatalogEntryOut) })
53
+ .meta({ id: "CatalogListOut" });
54
+
55
+ // ── Inferred consumer-facing type (re-exported by ../responses) ──────────────
56
+
57
+ export type ICCatalogEntry = z.infer<typeof CatalogEntryOut>;