@ingram-cloud/sdk 1.2.0 → 1.5.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 (49) hide show
  1. package/dist/client.js +185 -14
  2. package/dist/index.js +4 -0
  3. package/dist/scopes.js +52 -0
  4. package/dist/zod/_actor.js +33 -0
  5. package/dist/zod/_page.js +18 -4
  6. package/dist/zod/agents.js +17 -3
  7. package/dist/zod/billing.js +136 -0
  8. package/dist/zod/budgets.js +2 -3
  9. package/dist/zod/connections.js +2 -3
  10. package/dist/zod/conversations.js +4 -11
  11. package/dist/zod/deployments.js +32 -0
  12. package/dist/zod/files.js +2 -9
  13. package/dist/zod/index.js +3 -0
  14. package/dist/zod/mcp.js +20 -14
  15. package/dist/zod/observability.js +39 -19
  16. package/dist/zod/projects.js +4 -4
  17. package/dist/zod/runs.js +16 -4
  18. package/dist/zod/schedules.js +2 -7
  19. package/dist/zod/skills.js +73 -0
  20. package/dist/zod/smith-revisions.js +7 -5
  21. package/dist/zod/smiths.js +14 -0
  22. package/dist/zod/tenant.js +41 -4
  23. package/dist/zod/vector-stores.js +36 -23
  24. package/package.json +6 -8
  25. package/ts/client.ts +431 -50
  26. package/ts/index.ts +4 -0
  27. package/ts/responses.ts +40 -2
  28. package/ts/scopes.ts +57 -0
  29. package/ts/zod/.impeccable/hook.cache.json +1 -0
  30. package/ts/zod/_actor.ts +36 -0
  31. package/ts/zod/_page.ts +19 -4
  32. package/ts/zod/agents.ts +17 -3
  33. package/ts/zod/billing.ts +168 -0
  34. package/ts/zod/budgets.ts +2 -3
  35. package/ts/zod/connections.ts +2 -3
  36. package/ts/zod/conversations.ts +7 -11
  37. package/ts/zod/deployments.ts +36 -0
  38. package/ts/zod/files.ts +2 -9
  39. package/ts/zod/index.ts +3 -0
  40. package/ts/zod/mcp.ts +20 -15
  41. package/ts/zod/observability.ts +75 -24
  42. package/ts/zod/projects.ts +4 -4
  43. package/ts/zod/runs.ts +18 -4
  44. package/ts/zod/schedules.ts +2 -7
  45. package/ts/zod/skills.ts +85 -0
  46. package/ts/zod/smith-revisions.ts +7 -5
  47. package/ts/zod/smiths.ts +14 -0
  48. package/ts/zod/tenant.ts +52 -5
  49. package/ts/zod/vector-stores.ts +41 -23
package/ts/index.ts CHANGED
@@ -13,8 +13,12 @@
13
13
  * `./events` is the hand-authored `{v:1}` webhook/feed envelope and the SSE
14
14
  * run-stream frames, which OpenAPI can't express.
15
15
  *
16
+ * `./scopes` is the closed permission vocabulary a smith token may carry — you
17
+ * must name the scopes you want when minting one.
18
+ *
16
19
  * See `../README.md`.
17
20
  */
18
21
  export { schemas } from "./schemas.js";
19
22
  export * from "./events.js";
23
+ export * from "./scopes.js";
20
24
  export type * from "./responses.js";
package/ts/responses.ts CHANGED
@@ -25,6 +25,23 @@ export interface ICPaginatedResponse<T> {
25
25
  next_cursor?: string | null;
26
26
  }
27
27
 
28
+ /** One embedded input from `POST /v1/embeddings`, on the OpenAI wire. */
29
+ export interface ICEmbedding {
30
+ object: "embedding";
31
+ index: number;
32
+ embedding: number[];
33
+ }
34
+
35
+ /** The `POST /v1/embeddings` response — the OpenAI `list`-of-`embedding` shape.
36
+ * Declared inline (not `z.infer`red) because that route is a hand-shaped
37
+ * OpenAI-compatible front door with no Zod on the API side to share. */
38
+ export interface ICEmbeddingList {
39
+ object: "list";
40
+ data: ICEmbedding[];
41
+ model: string;
42
+ usage: { prompt_tokens: number; total_tokens: number };
43
+ }
44
+
28
45
  // ── Re-exported from the hand-authored Zod source of truth (./zod/*) ──────────
29
46
  export type {
30
47
  ICAgent,
@@ -34,12 +51,24 @@ export type {
34
51
  ICUiResourceTool,
35
52
  } from "./zod/agents.js";
36
53
  export type { ICApproval } from "./zod/approvals.js";
54
+ export type {
55
+ ICAutoreload,
56
+ ICBalance,
57
+ ICLedgerEntry,
58
+ ICOrgUsage,
59
+ ICOrgUsageProject,
60
+ ICOrgUsageSeries,
61
+ } from "./zod/billing.js";
37
62
  export type { ICBudget, ICBudgetStatus } from "./zod/budgets.js";
38
63
  export type { ICCatalogEntry } from "./zod/catalog.js";
39
64
  export type { ICConnection } from "./zod/connections.js";
40
65
  export type { ICConversation, ICConversationItem } from "./zod/conversations.js";
41
66
  export type { ICCustomer } from "./zod/customers.js";
42
- export type { ICDeployment, ICDeploymentCreated } from "./zod/deployments.js";
67
+ export type {
68
+ ICDeployment,
69
+ ICDeploymentCreated,
70
+ ICInboundEvent,
71
+ } from "./zod/deployments.js";
43
72
  export type { ICDiscordApp } from "./zod/discord.js";
44
73
  export type { ICEmailConfig } from "./zod/email.js";
45
74
  export type { ICFile, ICFileList } from "./zod/files.js";
@@ -48,6 +77,7 @@ export type { ICWorkingMemory, ICRecallHit } from "./zod/memories.js";
48
77
  export type {
49
78
  ICSpanKind,
50
79
  ICSpan,
80
+ ICSpanIn,
51
81
  ICSpanNode,
52
82
  ICTrace,
53
83
  ICTraceDetail,
@@ -55,8 +85,16 @@ export type {
55
85
  ICUsageEvent,
56
86
  } from "./zod/observability.js";
57
87
  export type { ICProject } from "./zod/projects.js";
58
- export type { ICRun, ICRunUsage, ICInputMessage, ICRunEvent } from "./zod/runs.js";
88
+ export type { ICActor } from "./zod/_actor.js";
89
+ export type {
90
+ ICRun,
91
+ ICRunUsage,
92
+ ICRunWarning,
93
+ ICInputMessage,
94
+ ICRunEvent,
95
+ } from "./zod/runs.js";
59
96
  export type { ICSchedule } from "./zod/schedules.js";
97
+ export type { ICSkill, ICSkillVersion, ICSkillReference } from "./zod/skills.js";
60
98
  export type { ICSlackApp } from "./zod/slack.js";
61
99
  export type { ICSmith } from "./zod/smiths.js";
62
100
  export type { ICSmithRevision } from "./zod/smith-revisions.js";
package/ts/scopes.ts ADDED
@@ -0,0 +1,57 @@
1
+ /**
2
+ * The closed permission vocabulary a smith token may carry, in mint order.
3
+ *
4
+ * It lives here rather than in the API because it is wire contract: a caller
5
+ * minting a token has to name the scopes it wants (`permissions` is required —
6
+ * there is no "grant everything" default), and the console's token form needs
7
+ * the same list to offer full access. One definition, so a new scope reaches
8
+ * every minting surface at once instead of drifting into a stale copy.
9
+ *
10
+ * Not in here: the admin markers (`tenant:*`, `operator:*`) and the account key
11
+ * (`organization:*`). Those are postures, not permissions — they are never a
12
+ * legal `permissions` entry, and the API refuses them as unknown scopes.
13
+ */
14
+ export const V1_SCOPES = [
15
+ "runs:read",
16
+ "runs:write",
17
+ "conversations:read",
18
+ "conversations:write",
19
+ "memories:read",
20
+ "memories:write",
21
+ "connections:read",
22
+ "connections:write",
23
+ "deployments:read",
24
+ "deployments:write",
25
+ "schedules:read",
26
+ "schedules:write",
27
+ "approvals:read",
28
+ "approvals:write",
29
+ "traces:read",
30
+ "traces:write",
31
+ "usage:read",
32
+ "usage:write",
33
+ "customers:read",
34
+ "customers:write",
35
+ "files:read",
36
+ "files:write",
37
+ "vector_stores:read",
38
+ "vector_stores:write",
39
+ // Smith-level provider keys (#170, end-user BYOK): an end-user sets their own
40
+ // key; a tenant token manages any of its smiths' keys.
41
+ "model_keys:read",
42
+ "model_keys:write",
43
+ // Agent Skills (#175): a tenant's skill bundles and their immutable versions.
44
+ "skills:read",
45
+ "skills:write",
46
+ // Embeddings: the stateless text→vector compute endpoint (POST /v1/embeddings).
47
+ // Write-only — it produces a result, it reads no stored state.
48
+ "embeddings:write",
49
+ ] as const;
50
+
51
+ export type V1Scope = (typeof V1_SCOPES)[number];
52
+
53
+ /** The read half of the vocabulary — the scope set for a token that must not
54
+ * change anything. Derived, so it cannot fall behind {@link V1_SCOPES}. */
55
+ export const V1_READ_SCOPES: readonly V1Scope[] = V1_SCOPES.filter(
56
+ (s): s is Extract<V1Scope, `${string}:read`> => s.endsWith(":read"),
57
+ );
@@ -0,0 +1 @@
1
+ {"version":1,"sessions":{"409c438b-72a6-412d-9a44-013a81c0f846":{"updatedAt":1784658629665,"files":{"/home/adys/src/cloud.ingram.tech/sdk/ts/client.ts":{"editCount":2,"findings":[]}}}}}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * The acting principal — who a run or an event is attributable to.
3
+ *
4
+ * Resolved from the authenticated caller at the point of action and stamped on
5
+ * the record it produced; never inferred afterwards. Every event a run produces
6
+ * inherits the run's actor, so a whole turn is attributable to one identity.
7
+ */
8
+ import { z } from "zod";
9
+
10
+ export const Actor = z
11
+ .object({
12
+ /** `smith` — a smith acted (a smith-bound token, or the smith itself on an
13
+ * autonomous turn); `tenant` — a tenant-admin token acted on a smith's
14
+ * behalf; `operator` — Ingram staff acted through the operator console. */
15
+ kind: z.enum(["smith", "tenant", "operator"]),
16
+ /** The smith id, tenant id, or operator email, per `kind`. */
17
+ id: z.string(),
18
+ /** `jti` of the token that authorized the action. Empty when no token
19
+ * acted — a scheduled or channel-driven turn the platform ran itself, or a
20
+ * console session, which signs a short-lived per-request token that is never
21
+ * registered. Read it with `email`: both empty means the platform acted. */
22
+ token_id: z.string(),
23
+ /** The human behind the action, when one is named — the signed-in console user
24
+ * or the Ingram operator. Empty for a machine caller (an API token, a smith
25
+ * acting for itself) and for autonomous work.
26
+ *
27
+ * This is what makes a config change attributable to a *person* rather than to
28
+ * the tenant they share: console mutations all carry `kind: "tenant"`, so
29
+ * without this every colleague's action looked identical. Defaulted rather than
30
+ * optional so records written before it existed read as "no human named"
31
+ * instead of failing to parse. */
32
+ email: z.string().default(""),
33
+ })
34
+ .meta({ id: "Actor" });
35
+
36
+ export type ICActor = z.infer<typeof Actor>;
package/ts/zod/_page.ts CHANGED
@@ -1,8 +1,10 @@
1
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.
2
+ * The two `/v1` list envelopes, one definition each. Native resources page by
3
+ * keyset: `data` + the opaque `next_cursor` (null on the last page) + `has_more`
4
+ * the cursor is an opaque, short-lived token; pass it straight back as
5
+ * `?cursor=`, never parse it. OpenAI-mirrored resources use the OpenAI `list`
6
+ * envelope instead: `object:"list"` + `first_id`/`last_id` + `has_more`, paged
7
+ * by passing `last_id` back as `?after=`.
6
8
  */
7
9
  import { z } from "zod";
8
10
 
@@ -16,3 +18,16 @@ export function pageOut<T extends z.ZodTypeAny>(item: T, id: string) {
16
18
  })
17
19
  .meta({ id });
18
20
  }
21
+
22
+ /** Wrap an item schema in the OpenAI `list` envelope, named `id` in the spec. */
23
+ export function oaiListOut<T extends z.ZodTypeAny>(item: T, id: string) {
24
+ return z
25
+ .object({
26
+ object: z.literal("list"),
27
+ data: z.array(item),
28
+ first_id: z.string().nullable(),
29
+ last_id: z.string().nullable(),
30
+ has_more: z.boolean(),
31
+ })
32
+ .meta({ id });
33
+ }
package/ts/zod/agents.ts CHANGED
@@ -13,6 +13,7 @@
13
13
  */
14
14
  import { z } from "zod";
15
15
  import { pageOut } from "./_page.js";
16
+ import { SkillRef } from "./skills.js";
16
17
 
17
18
  /** A per-smith variable an agent declares; bound at run time. */
18
19
  export const AgentVariable = z
@@ -72,6 +73,10 @@ export const AgentDraft = z
72
73
  model: z.string().nullable(),
73
74
  enabled_hosted_tools: z.array(z.string()),
74
75
  vector_store_ids: z.array(z.string()),
76
+ /** Registered MCP servers this agent's smiths load, by name. Null = all. */
77
+ mcp_servers: z.array(z.string()).nullable(),
78
+ /** Skills this agent's smiths carry. Frozen into the snapshot at publish. */
79
+ skills: z.array(SkillRef),
75
80
  auto_memory: z.boolean().nullable(),
76
81
  memory_consolidation: z.boolean().nullable(),
77
82
  variables: z.array(AgentVariable),
@@ -93,6 +98,8 @@ export const AgentOut = z
93
98
  rollout_version: z.number().int().nullable(),
94
99
  rollout_percent: z.number().int(),
95
100
  smith_count: z.number().int().optional(),
101
+ /** Newest run across every smith of this agent. Null until one runs. */
102
+ last_activity_at: z.string().nullable().optional(),
96
103
  created_at: z.string().nullable(),
97
104
  updated_at: z.string().nullable(),
98
105
  })
@@ -109,6 +116,8 @@ export const AgentVersionOut = z
109
116
  model: z.string().nullish(),
110
117
  enabled_hosted_tools: z.array(z.string()).optional(),
111
118
  vector_store_ids: z.array(z.string()).optional(),
119
+ mcp_servers: z.array(z.string()).nullish(),
120
+ skills: z.array(SkillRef).optional(),
112
121
  auto_memory: z.boolean().nullish(),
113
122
  memory_consolidation: z.boolean().nullish(),
114
123
  variables: z.array(AgentVariable).optional(),
@@ -120,9 +129,7 @@ export const AgentVersionOut = z
120
129
  })
121
130
  .meta({ id: "AgentVersionOut" });
122
131
 
123
- export const AgentVersionListOut = z
124
- .object({ data: z.array(AgentVersionOut) })
125
- .meta({ id: "AgentVersionListOut" });
132
+ export const AgentVersionListOut = pageOut(AgentVersionOut, "AgentVersionListOut");
126
133
 
127
134
  // ── Request bodies ──────────────────────────────────────────────────────────
128
135
 
@@ -134,6 +141,9 @@ export const AgentIn = z
134
141
  model: z.string().nullish(),
135
142
  enabled_hosted_tools: z.array(z.string()).nullish(),
136
143
  vector_store_ids: z.array(z.string()).nullish(),
144
+ /** Scope runs to these registered MCP servers (by name). Null/omitted = all. */
145
+ mcp_servers: z.array(z.string()).nullish(),
146
+ skills: z.array(SkillRef).nullish(),
137
147
  auto_memory: z.boolean().nullish(),
138
148
  memory_consolidation: z.boolean().nullish(),
139
149
  variables: z.array(AgentVariable).nullish(),
@@ -147,6 +157,10 @@ export const AgentPatch = z
147
157
  model: z.string().nullish(),
148
158
  enabled_hosted_tools: z.array(z.string()).nullish(),
149
159
  vector_store_ids: z.array(z.string()).nullish(),
160
+ /** Scope runs to these registered MCP servers (by name). An explicit null
161
+ * clears the restriction (= all); omitted leaves it unchanged. */
162
+ mcp_servers: z.array(z.string()).nullish(),
163
+ skills: z.array(SkillRef).nullish(),
150
164
  auto_memory: z.boolean().nullish(),
151
165
  memory_consolidation: z.boolean().nullish(),
152
166
  variables: z.array(AgentVariable).nullish(),
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Hand-authored Zod schemas for platform credits — the org wallet the tenant
3
+ * funds to pay *Ingram* (`/v1/organization/billing/*`). One wallet pools across
4
+ * all of the org's projects; every endpoint needs an organization-scoped token.
5
+ *
6
+ * Source of truth is the handler (`api/src/routes/billing.ts`), which imports
7
+ * these for request validation and response typing. Amounts are always integer
8
+ * **minor units** (cents) of `currency` (ISO-4217, lower-case) — never floats.
9
+ *
10
+ * The per-endpoint query schemas stay in the handler: they carry OpenAPI
11
+ * `param` metadata, and the client types query args as plain TS.
12
+ *
13
+ * `.meta({ id })` names the component so the emitted OpenAPI references it as
14
+ * `#/components/schemas/<id>` rather than inlining it.
15
+ */
16
+ import { z } from "zod";
17
+
18
+ // ── Balance + ledger ────────────────────────────────────────────────────────
19
+
20
+ export const BalanceOut = z
21
+ .object({
22
+ /** ISO-4217, lower-case. Clients format `balance_cents` in this currency. */
23
+ currency: z.string(),
24
+ balance_cents: z.number().int(),
25
+ /** Whether the org has a Stripe Customer yet (materialized on first payment). */
26
+ stripe_customer: z.boolean(),
27
+ })
28
+ .meta({ id: "BalanceOut" });
29
+
30
+ /** One credit-ledger row. `amount_cents` is positive for money in (top-ups,
31
+ * grants, redeemed codes) and negative for usage debits. */
32
+ export const LedgerEntryOut = z
33
+ .object({
34
+ id: z.string(),
35
+ amount_cents: z.number().int(),
36
+ currency: z.string(),
37
+ kind: z.string(),
38
+ description: z.string(),
39
+ created_at: z.string().nullable(),
40
+ })
41
+ .meta({ id: "LedgerEntryOut" });
42
+
43
+ /** A page of ledger rows (keyset pagination). */
44
+ export const LedgerListOut = z
45
+ .object({
46
+ data: z.array(LedgerEntryOut),
47
+ next_cursor: z.string().nullable(),
48
+ has_more: z.boolean(),
49
+ })
50
+ .meta({ id: "LedgerListOut" });
51
+
52
+ // ── Per-project draw from the wallet ────────────────────────────────────────
53
+
54
+ /** One project's draw for a calendar month — which project is spending the
55
+ * shared funds, and against what cap. */
56
+ export const OrgUsageProject = z
57
+ .object({
58
+ project_id: z.string(),
59
+ name: z.string(),
60
+ /** Credits drawn this period (sum of the project's debit rows). */
61
+ drawn_cents: z.number().int(),
62
+ /** Tokens the project's runs consumed this period (priced daily rollup). */
63
+ tokens: z.number().int(),
64
+ /** The project's tenant-scope budget limit (billing currency, major units),
65
+ * or null when it draws freely from the org wallet. */
66
+ budget_limit: z.number().nullable(),
67
+ budget_action: z.string().nullable(),
68
+ })
69
+ .meta({ id: "OrgUsageProject" });
70
+
71
+ export const OrgUsageOut = z
72
+ .object({
73
+ period: z.string(),
74
+ currency: z.string(),
75
+ total_drawn_cents: z.number().int(),
76
+ total_tokens: z.number().int(),
77
+ projects: z.array(OrgUsageProject),
78
+ })
79
+ .meta({ id: "OrgUsageOut" });
80
+
81
+ /** One day/project draw. Points are sparse — a day with no draw is absent, and
82
+ * the client fills the gaps with zero. */
83
+ export const OrgUsageSeriesPoint = z
84
+ .object({
85
+ day: z.string(),
86
+ project_id: z.string(),
87
+ drawn_cents: z.number().int(),
88
+ })
89
+ .meta({ id: "OrgUsageSeriesPoint" });
90
+
91
+ export const OrgUsageSeriesOut = z
92
+ .object({
93
+ currency: z.string(),
94
+ from: z.string(),
95
+ to: z.string(),
96
+ /** Projects with any draw in the window, ranked by total draw. */
97
+ projects: z.array(z.object({ project_id: z.string(), name: z.string() })),
98
+ points: z.array(OrgUsageSeriesPoint),
99
+ })
100
+ .meta({ id: "OrgUsageSeriesOut" });
101
+
102
+ // ── Money movement ──────────────────────────────────────────────────────────
103
+
104
+ export const CheckoutIn = z
105
+ .object({
106
+ amount_cents: z.number().int(),
107
+ /** The console's own origin URL to return to; must carry the Stripe session
108
+ * template so the page can reflect the result. */
109
+ return_url: z.string(),
110
+ })
111
+ .meta({ id: "CheckoutIn" });
112
+
113
+ export const CheckoutOut = z.object({ url: z.string() }).meta({ id: "CheckoutOut" });
114
+
115
+ export const ConfirmIn = z.object({ session_id: z.string() }).meta({ id: "ConfirmIn" });
116
+
117
+ export const ConfirmOut = z
118
+ .object({ credited: z.boolean(), payment_status: z.string() })
119
+ .meta({ id: "ConfirmOut" });
120
+
121
+ /** Add a card with no charge (Stripe setup-mode Checkout); on success it unlocks
122
+ * the one-time welcome credit. Same return-url contract as checkout. */
123
+ export const SetupIn = z.object({ return_url: z.string() }).meta({ id: "SetupIn" });
124
+
125
+ export const SetupOut = z.object({ url: z.string() }).meta({ id: "SetupOut" });
126
+
127
+ /** Redeem a one-time credit code, matched case-insensitively. */
128
+ export const RedeemIn = z.object({ code: z.string() }).meta({ id: "RedeemIn" });
129
+
130
+ export const RedeemOut = z
131
+ .object({
132
+ amount_cents: z.number().int(),
133
+ currency: z.string(),
134
+ })
135
+ .meta({ id: "RedeemOut" });
136
+
137
+ export const AutoreloadOut = z
138
+ .object({
139
+ enabled: z.boolean(),
140
+ /** When the balance drops below `threshold_cents`, the saved card is charged
141
+ * for `amount_cents`. Both are integer minor units of the billing currency. */
142
+ threshold_cents: z.number().int(),
143
+ amount_cents: z.number().int(),
144
+ })
145
+ .meta({ id: "AutoreloadOut" });
146
+
147
+ /** Set the same shape you read back. */
148
+ export const AutoreloadIn = AutoreloadOut;
149
+
150
+ /** `amount_cents` is optional — it defaults to the configured auto-reload amount. */
151
+ export const ReloadIn = z
152
+ .object({ amount_cents: z.number().int().optional() })
153
+ .meta({ id: "ReloadIn" });
154
+
155
+ export const ReloadOut = z
156
+ .object({ credited: z.boolean(), payment_status: z.string() })
157
+ .meta({ id: "ReloadOut" });
158
+
159
+ export const PortalOut = z.object({ url: z.string() }).meta({ id: "PortalOut" });
160
+
161
+ // ── Inferred consumer-facing types (re-exported by ../responses) ─────────────
162
+
163
+ export type ICBalance = z.infer<typeof BalanceOut>;
164
+ export type ICLedgerEntry = z.infer<typeof LedgerEntryOut>;
165
+ export type ICOrgUsage = z.infer<typeof OrgUsageOut>;
166
+ export type ICOrgUsageProject = z.infer<typeof OrgUsageProject>;
167
+ export type ICOrgUsageSeries = z.infer<typeof OrgUsageSeriesOut>;
168
+ export type ICAutoreload = z.infer<typeof AutoreloadOut>;
package/ts/zod/budgets.ts CHANGED
@@ -12,6 +12,7 @@
12
12
  * `#/components/schemas/<id>` rather than inlining it.
13
13
  */
14
14
  import { z } from "zod";
15
+ import { pageOut } from "./_page.js";
15
16
 
16
17
  /** What a budget caps; `agent`/`smith`/`customer` budgets carry the id in
17
18
  * `scope_id` (an agent design, a single smith, or one of your customers). */
@@ -45,9 +46,7 @@ export const BudgetStatusOut = BudgetOut.extend({
45
46
  over: z.boolean(),
46
47
  }).meta({ id: "BudgetStatusOut" });
47
48
 
48
- export const BudgetListOut = z
49
- .object({ data: z.array(BudgetOut) })
50
- .meta({ id: "BudgetListOut" });
49
+ export const BudgetListOut = pageOut(BudgetOut, "BudgetListOut");
51
50
 
52
51
  // ── Request bodies ──────────────────────────────────────────────────────────
53
52
 
@@ -18,6 +18,7 @@
18
18
  * `#/components/schemas/<id>` rather than inlining it.
19
19
  */
20
20
  import { z } from "zod";
21
+ import { pageOut } from "./_page.js";
21
22
 
22
23
  /** OAuth token material the tenant pushes in; IC stores it encrypted and never
23
24
  * echoes it back. Only `kind: "oauth_tokens"` is accepted. */
@@ -44,9 +45,7 @@ export const ConnectionOut = z
44
45
  })
45
46
  .meta({ id: "ConnectionOut" });
46
47
 
47
- export const ConnectionListOut = z
48
- .object({ data: z.array(ConnectionOut) })
49
- .meta({ id: "ConnectionListOut" });
48
+ export const ConnectionListOut = pageOut(ConnectionOut, "ConnectionListOut");
50
49
 
51
50
  // ── Request bodies ──────────────────────────────────────────────────────────
52
51
 
@@ -17,7 +17,7 @@
17
17
  * endpoint.
18
18
  */
19
19
  import { z } from "zod";
20
- import { pageOut } from "./_page.js";
20
+ import { oaiListOut } from "./_page.js";
21
21
 
22
22
  /** A conversation — the OpenAI Conversations object + IC extensions. */
23
23
  export const ConversationOut = z
@@ -37,7 +37,8 @@ export const ConversationOut = z
37
37
  })
38
38
  .meta({ id: "ConversationOut" });
39
39
 
40
- export const ConversationListOut = pageOut(ConversationOut, "ConversationListOut");
40
+ /** The conversation list, in OpenAI's `list` envelope (page with `?after=`). */
41
+ export const ConversationListOut = oaiListOut(ConversationOut, "ConversationListOut");
41
42
 
42
43
  /** The delete acknowledgement, in OpenAI's `*.deleted` shape. */
43
44
  export const ConversationDeleted = z
@@ -71,15 +72,10 @@ export const ConversationItem = z
71
72
  .meta({ id: "ConversationItem" });
72
73
 
73
74
  /** A conversation's items, in OpenAI's `list` envelope (not the IC cursor page). */
74
- export const ConversationItemListOut = z
75
- .object({
76
- object: z.literal("list"),
77
- data: z.array(ConversationItem),
78
- first_id: z.string().nullable(),
79
- last_id: z.string().nullable(),
80
- has_more: z.boolean(),
81
- })
82
- .meta({ id: "ConversationItemListOut" });
75
+ export const ConversationItemListOut = oaiListOut(
76
+ ConversationItem,
77
+ "ConversationItemListOut",
78
+ );
83
79
 
84
80
  /** Create body — OpenAI accepts `metadata`; `title` is the IC extension. */
85
81
  export const ConversationCreate = z
@@ -112,7 +112,43 @@ export const DeploymentPatch = z
112
112
  })
113
113
  .meta({ id: "DeploymentPatch" });
114
114
 
115
+ // ── Inbound events ───────────────────────────────────────────────────────────
116
+
117
+ /**
118
+ * One message as it arrived, before anything interpreted it — the immutable
119
+ * ingest record behind every channel-triggered run, in CloudEvents terms
120
+ * (`source` / `type` / `subject` / `data`).
121
+ *
122
+ * It is recorded before resolution, so an event that matched no smith is here
123
+ * too, with `smith_id: ""` — "the webhook fired and nothing happened" is a
124
+ * readable answer, not an absence. `idempotency_key` is the provider's own
125
+ * delivery id (`Message-Id`, `X-GitHub-Delivery`); a re-delivery of the same key
126
+ * records once, so this log is also the dedup ledger. `""` throughout means the
127
+ * source supplied nothing, never "unknown".
128
+ */
129
+ export const InboundEventOut = z
130
+ .object({
131
+ id: z.string(),
132
+ /** The channel it arrived on: `email`, `telegram`, `slack`, `whatsapp`, … */
133
+ source: z.string(),
134
+ /** The provider's event name (`email.received`); `""` if it names none. */
135
+ type: z.string(),
136
+ /** The addressed resource — inbox address, channel, repo. */
137
+ subject: z.string(),
138
+ /** The provider's delivery id, and this log's dedup key. */
139
+ idempotency_key: z.string(),
140
+ /** The smith it woke; `""` when the sender resolved to none. */
141
+ smith_id: z.string(),
142
+ /** The provider payload as received. */
143
+ data: z.record(z.string(), z.unknown()),
144
+ created_at: z.string().nullable(),
145
+ })
146
+ .meta({ id: "InboundEventOut" });
147
+
148
+ export const InboundEventListOut = pageOut(InboundEventOut, "InboundEventListOut");
149
+
115
150
  // ── Inferred consumer-facing types (re-exported by ../responses) ─────────────
116
151
 
117
152
  export type ICDeployment = z.infer<typeof DeploymentOut>;
118
153
  export type ICDeploymentCreated = z.infer<typeof DeploymentCreatedOut>;
154
+ export type ICInboundEvent = z.infer<typeof InboundEventOut>;
package/ts/zod/files.ts CHANGED
@@ -11,6 +11,7 @@
11
11
  * listed.
12
12
  */
13
13
  import { z } from "zod";
14
+ import { oaiListOut } from "./_page.js";
14
15
 
15
16
  /** OpenAI's upload purposes. Vector-store source files are `assistants`. */
16
17
  export const FilePurpose = z.enum([
@@ -39,15 +40,7 @@ export const FileOut = z
39
40
  .meta({ id: "FileOut" });
40
41
 
41
42
  /** Files, in OpenAI's `list` envelope (not the IC cursor page). */
42
- export const FileListOut = z
43
- .object({
44
- object: z.literal("list"),
45
- data: z.array(FileOut),
46
- first_id: z.string().nullable(),
47
- last_id: z.string().nullable(),
48
- has_more: z.boolean(),
49
- })
50
- .meta({ id: "FileListOut" });
43
+ export const FileListOut = oaiListOut(FileOut, "FileListOut");
51
44
 
52
45
  /** The delete acknowledgement, in OpenAI's `*.deleted` shape. */
53
46
  export const FileDeleted = z
package/ts/zod/index.ts CHANGED
@@ -8,9 +8,11 @@
8
8
  * when the last one lands, the generated file and the `openapi-zod-client` step
9
9
  * are deleted and this becomes the sole `schemas` source.
10
10
  */
11
+ export * from "./_actor.js";
11
12
  export * from "./_page.js";
12
13
  export * from "./agents.js";
13
14
  export * from "./approvals.js";
15
+ export * from "./billing.js";
14
16
  export * from "./budgets.js";
15
17
  export * from "./catalog.js";
16
18
  export * from "./connections.js";
@@ -26,6 +28,7 @@ export * from "./observability.js";
26
28
  export * from "./projects.js";
27
29
  export * from "./runs.js";
28
30
  export * from "./schedules.js";
31
+ export * from "./skills.js";
29
32
  export * from "./slack.js";
30
33
  export * from "./smith-revisions.js";
31
34
  export * from "./smiths.js";