@ingram-cloud/sdk 1.1.0 → 1.2.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
@@ -314,6 +314,9 @@ export class IngramCloud {
314
314
  usage = {
315
315
  /** Token/cost/run totals grouped by app, smith, model, or customer. */
316
316
  breakdown: (query, opts) => this.json("GET", "/usage", { ...opts, query }),
317
+ /** The raw billable-usage event ledger (keyset-paginated, newest first) — the
318
+ * per-event rows the breakdown aggregates. */
319
+ events: (query, opts) => this.page("/usage/events", query, opts),
317
320
  };
318
321
  // ── Files (the OpenAI Files API) ─────────────────────────────────────────
319
322
  files = {
@@ -382,6 +385,10 @@ export class IngramCloud {
382
385
  }),
383
386
  delete: (wid, opts) => this.empty("DELETE", `/tenant/webhooks/${enc(wid)}`, opts),
384
387
  test: (wid, opts) => this.json("POST", `/tenant/webhooks/${enc(wid)}/test`, opts),
388
+ /** The persisted delivery attempts for a webhook (durable retry audit trail). */
389
+ deliveries: (wid, query, opts) => this.page(`/tenant/webhooks/${enc(wid)}/deliveries`, query, opts),
390
+ /** Force a fresh delivery attempt for one record (e.g. after the endpoint recovers). */
391
+ redeliver: (wid, did, opts) => this.json("POST", `/tenant/webhooks/${enc(wid)}/deliveries/${enc(did)}/redeliver`, opts),
385
392
  },
386
393
  providers: {
387
394
  list: (opts) => this.data("GET", "/tenant/providers", opts),
@@ -438,6 +445,17 @@ export class IngramCloud {
438
445
  delete: (opts) => this.empty("DELETE", "/tenant/email", opts),
439
446
  },
440
447
  };
448
+ // ── Delegated connector consent (connector OAuth, #123) ─────────────────
449
+ // Tenant-admin token. The tenant's hosted consent page (the provider's
450
+ // `authorize_url`) reads the pending request, then completes or declines it
451
+ // server-to-server; the returned `redirect_url` is where to 302 the browser.
452
+ oauth = {
453
+ authorizeRequests: {
454
+ get: (requestId, opts) => this.json("GET", `/oauth/authorize-requests/${enc(requestId)}`, opts),
455
+ complete: (requestId, body, opts) => this.json("POST", `/oauth/authorize-requests/${enc(requestId)}/complete`, { ...opts, body }),
456
+ decline: (requestId, opts) => this.json("POST", `/oauth/authorize-requests/${enc(requestId)}/decline`, opts),
457
+ },
458
+ };
441
459
  // ── Organization (org token: projects + billing) ────────────────────────
442
460
  organization = {
443
461
  projects: {
@@ -31,7 +31,17 @@ export const DeploymentTarget = z
31
31
  * (`DeploymentIn.kind`) and the response (`DeploymentOut.kind`); the API derives
32
32
  * its accepted-kinds set from these options, so the enum is the discoverable list. */
33
33
  export const DeploymentKind = z
34
- .enum(["whatsapp", "telegram", "slack", "discord", "sms", "voice", "email", "mcp"])
34
+ .enum([
35
+ "whatsapp",
36
+ "telegram",
37
+ "slack",
38
+ "discord",
39
+ "sms",
40
+ "voice",
41
+ "email",
42
+ "mcp",
43
+ "web",
44
+ ])
35
45
  .meta({ id: "DeploymentKind" });
36
46
  export const DeploymentOut = z
37
47
  .object({
@@ -46,6 +56,9 @@ export const DeploymentOut = z
46
56
  /** The connectable MCP endpoint — present only for `kind: "mcp"`. Paste into
47
57
  * Claude / ChatGPT as the server URL; survives a later GET, not just create. */
48
58
  mcp_url: z.string().optional(),
59
+ /** The shareable hosted-page URL — present only for `kind: "web"`. Open in a
60
+ * browser to chat with the agent; survives a later GET, not just create. */
61
+ page_url: z.string().optional(),
49
62
  status: z.string(),
50
63
  created_at: z.string().nullable(),
51
64
  })
@@ -59,6 +72,7 @@ export const DeploymentListOut = pageOut(DeploymentOut, "DeploymentListOut");
59
72
  * - slack `provision`/`oauth_install`: `install_url`, `state`, optional `slack_app_id`.
60
73
  * - email `provision`: no extras (plain `DeploymentOut`).
61
74
  * - mcp: `mcp_url` (on the base `DeploymentOut`, so it also survives a GET).
75
+ * - web: `page_url` (on the base `DeploymentOut`, so it also survives a GET).
62
76
  * All are optional — which appear depends on the kind + setup mode.
63
77
  */
64
78
  export const DeploymentCreatedOut = DeploymentOut.extend({
@@ -67,6 +67,32 @@ export const WebhookPatch = z
67
67
  active: z.boolean().nullish(),
68
68
  })
69
69
  .meta({ id: "WebhookPatch" });
70
+ /** One persisted delivery attempt record for a webhook — the audit trail behind
71
+ * durable, retried delivery. `status` is `pending` | `succeeded` | `dead`. */
72
+ export const WebhookDeliveryOut = z
73
+ .object({
74
+ id: z.string(),
75
+ event_id: z.string(),
76
+ event_type: z.string(),
77
+ url: z.string(),
78
+ status: z.string(),
79
+ attempts: z.number(),
80
+ last_status: z.number().nullable(),
81
+ last_error: z.string(),
82
+ next_attempt_at: z.string().nullable(),
83
+ delivered_at: z.string().nullable(),
84
+ created_at: z.string().nullable(),
85
+ })
86
+ .meta({ id: "WebhookDeliveryOut" });
87
+ export const WebhookDeliveryListOut = pageOut(WebhookDeliveryOut, "WebhookDeliveryListOut");
88
+ /** The redeliver ack — the outcome of the forced re-attempt. */
89
+ export const WebhookRedeliverOut = z
90
+ .object({
91
+ delivery_id: z.string(),
92
+ delivered: z.boolean(),
93
+ status: z.number().nullable(),
94
+ })
95
+ .meta({ id: "WebhookRedeliverOut" });
70
96
  // ── Tokens (mint / list / revoke RS256 JWTs) ─────────────────────────────────
71
97
  /** A minted-token *summary* — the list/listing shape. The secret `token` is
72
98
  * NEVER echoed here; it only appears in {@link MintedTokenOut} on create. */
@@ -184,6 +210,7 @@ export const ProviderOut = z
184
210
  token_uri: z.string().nullable(),
185
211
  scopes_allowed: z.array(z.string()),
186
212
  refresh_webhook: z.string().nullable(),
213
+ authorize_url: z.string().nullable(),
187
214
  has_client_secret: z.boolean(),
188
215
  })
189
216
  .meta({ id: "ProviderOut" });
@@ -204,8 +231,34 @@ export const ProviderIn = z
204
231
  token_uri: z.string().nullish(),
205
232
  scopes_allowed: z.array(z.string()).default([]),
206
233
  refresh_webhook: z.string().nullish(),
234
+ /** Tenant-hosted connector consent page (#123): the connector OAuth
235
+ * authorize endpoint redirects the end-user here (`?request_id=…`)
236
+ * instead of rendering the built-in connect-token page. */
237
+ authorize_url: z.string().nullish(),
207
238
  })
208
239
  .meta({ id: "ProviderIn" });
240
+ // ── Delegated connector consent (connector OAuth, #123) ─────────────────────
241
+ /** Render data for a tenant-hosted consent page: the pending authorize request
242
+ * stashed by `GET /oauth/authorize` when the tenant's provider registers an
243
+ * `authorize_url`. */
244
+ export const AuthorizeRequestOut = z
245
+ .object({
246
+ client_name: z.string(),
247
+ target_name: z.string(),
248
+ tenant: z.string(),
249
+ resource: z.string(),
250
+ deployment_id: z.string(),
251
+ })
252
+ .meta({ id: "AuthorizeRequestOut" });
253
+ /** Complete the delegated grant: the tenant asserts (server-to-server) which
254
+ * smith the end-user authorized. */
255
+ export const AuthorizeCompleteIn = z
256
+ .object({ smith_id: z.string() })
257
+ .meta({ id: "AuthorizeCompleteIn" });
258
+ /** Where the tenant 302s the browser after completing or declining. */
259
+ export const AuthorizeRedirectOut = z
260
+ .object({ redirect_url: z.string() })
261
+ .meta({ id: "AuthorizeRedirectOut" });
209
262
  // ── Hosted-tool catalog ──────────────────────────────────────────────────────
210
263
  /** One tool hosted by Ingram Cloud that the catalog advertises. */
211
264
  export const HostedToolOut = z
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ingram-cloud/sdk",
3
- "version": "1.1.0",
3
+ "version": "1.2.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",
@@ -56,10 +56,10 @@
56
56
  "prepublishOnly": "bun run build"
57
57
  },
58
58
  "devDependencies": {
59
- "@ingram-tech/oxlint-config": "^0.2.1",
60
- "oxfmt": "^0.57.0",
61
- "oxlint": "^1.70.0",
62
- "typescript": "^6.0.0"
59
+ "@ingram-tech/oxlint-config": "^0.2.2",
60
+ "oxfmt": "^0.58.0",
61
+ "oxlint": "^1.73.0",
62
+ "typescript": "^6"
63
63
  },
64
64
  "dependencies": {
65
65
  "zod": "^4.4.3"
package/ts/client.ts CHANGED
@@ -29,6 +29,7 @@ import type {
29
29
  ICAgent,
30
30
  ICAgentVersion,
31
31
  ICApproval,
32
+ ICAuthorizeRequest,
32
33
  ICBudget,
33
34
  ICBudgetStatus,
34
35
  ICCatalogEntry,
@@ -63,11 +64,13 @@ import type {
63
64
  ICUiResource,
64
65
  ICUsage,
65
66
  ICUsageBreakdown,
67
+ ICUsageEvent,
66
68
  ICVectorStore,
67
69
  ICVectorStoreFile,
68
70
  ICVectorStoreFileBatch,
69
71
  ICVectorStoreSearchPage,
70
72
  ICWebhook,
73
+ ICWebhookDelivery,
71
74
  ICWhatsAppConfig,
72
75
  ICWorkingMemory,
73
76
  } from "./responses.js";
@@ -110,6 +113,8 @@ import type { RestoreIn } from "./zod/smith-revisions.js";
110
113
  import type { SmithCreate, SmithPatch } from "./zod/smiths.js";
111
114
  import type { TelegramBotIn } from "./zod/telegram.js";
112
115
  import type {
116
+ AuthorizeCompleteIn,
117
+ AuthorizeRedirectOut,
113
118
  HostedToolOut,
114
119
  ModelKeyConfiguredOut,
115
120
  ModelKeyIn,
@@ -119,6 +124,7 @@ import type {
119
124
  WebhookCreateOut,
120
125
  WebhookIn,
121
126
  WebhookPatch,
127
+ WebhookRedeliverOut,
122
128
  } from "./zod/tenant.js";
123
129
  import type { WhatsAppConfigIn } from "./zod/whatsapp.js";
124
130
 
@@ -811,6 +817,18 @@ export class IngramCloud {
811
817
  },
812
818
  opts?: RequestOptions,
813
819
  ) => this.json<ICUsageBreakdown>("GET", "/usage", { ...opts, query }),
820
+ /** The raw billable-usage event ledger (keyset-paginated, newest first) — the
821
+ * per-event rows the breakdown aggregates. */
822
+ events: (
823
+ query?: PageOpts & {
824
+ smith_id?: string;
825
+ meter?: string;
826
+ customer_id?: string;
827
+ from?: string;
828
+ to?: string;
829
+ },
830
+ opts?: RequestOptions,
831
+ ) => this.page<ICUsageEvent>("/usage/events", query, opts),
814
832
  };
815
833
 
816
834
  // ── Files (the OpenAI Files API) ─────────────────────────────────────────
@@ -1022,6 +1040,20 @@ export class IngramCloud {
1022
1040
  `/tenant/webhooks/${enc(wid)}/test`,
1023
1041
  opts,
1024
1042
  ),
1043
+ /** The persisted delivery attempts for a webhook (durable retry audit trail). */
1044
+ deliveries: (wid: string, query?: PageOpts, opts?: RequestOptions) =>
1045
+ this.page<ICWebhookDelivery>(
1046
+ `/tenant/webhooks/${enc(wid)}/deliveries`,
1047
+ query,
1048
+ opts,
1049
+ ),
1050
+ /** Force a fresh delivery attempt for one record (e.g. after the endpoint recovers). */
1051
+ redeliver: (wid: string, did: string, opts?: RequestOptions) =>
1052
+ this.json<z.infer<typeof WebhookRedeliverOut>>(
1053
+ "POST",
1054
+ `/tenant/webhooks/${enc(wid)}/deliveries/${enc(did)}/redeliver`,
1055
+ opts,
1056
+ ),
1025
1057
  },
1026
1058
 
1027
1059
  providers: {
@@ -1146,6 +1178,38 @@ export class IngramCloud {
1146
1178
  },
1147
1179
  };
1148
1180
 
1181
+ // ── Delegated connector consent (connector OAuth, #123) ─────────────────
1182
+ // Tenant-admin token. The tenant's hosted consent page (the provider's
1183
+ // `authorize_url`) reads the pending request, then completes or declines it
1184
+ // server-to-server; the returned `redirect_url` is where to 302 the browser.
1185
+
1186
+ readonly oauth = {
1187
+ authorizeRequests: {
1188
+ get: (requestId: string, opts?: RequestOptions) =>
1189
+ this.json<ICAuthorizeRequest>(
1190
+ "GET",
1191
+ `/oauth/authorize-requests/${enc(requestId)}`,
1192
+ opts,
1193
+ ),
1194
+ complete: (
1195
+ requestId: string,
1196
+ body: z.input<typeof AuthorizeCompleteIn>,
1197
+ opts?: RequestOptions,
1198
+ ) =>
1199
+ this.json<z.infer<typeof AuthorizeRedirectOut>>(
1200
+ "POST",
1201
+ `/oauth/authorize-requests/${enc(requestId)}/complete`,
1202
+ { ...opts, body },
1203
+ ),
1204
+ decline: (requestId: string, opts?: RequestOptions) =>
1205
+ this.json<z.infer<typeof AuthorizeRedirectOut>>(
1206
+ "POST",
1207
+ `/oauth/authorize-requests/${enc(requestId)}/decline`,
1208
+ opts,
1209
+ ),
1210
+ },
1211
+ };
1212
+
1149
1213
  // ── Organization (org token: projects + billing) ────────────────────────
1150
1214
 
1151
1215
  readonly organization = {
package/ts/responses.ts CHANGED
@@ -52,6 +52,7 @@ export type {
52
52
  ICTrace,
53
53
  ICTraceDetail,
54
54
  ICUsageBreakdown,
55
+ ICUsageEvent,
55
56
  } from "./zod/observability.js";
56
57
  export type { ICProject } from "./zod/projects.js";
57
58
  export type { ICRun, ICRunUsage, ICInputMessage, ICRunEvent } from "./zod/runs.js";
@@ -63,6 +64,7 @@ export type { ICTelegramBot } from "./zod/telegram.js";
63
64
  export type {
64
65
  ICEvent,
65
66
  ICWebhook,
67
+ ICWebhookDelivery,
66
68
  ICToken,
67
69
  ICMintedToken,
68
70
  ICUsage,
@@ -71,6 +73,7 @@ export type {
71
73
  ICModelCatalog,
72
74
  ICModelKey,
73
75
  ICProvider,
76
+ ICAuthorizeRequest,
74
77
  } from "./zod/tenant.js";
75
78
  export type { ICWhatsAppConfig } from "./zod/whatsapp.js";
76
79
  export type {
@@ -33,7 +33,17 @@ export const DeploymentTarget = z
33
33
  * (`DeploymentIn.kind`) and the response (`DeploymentOut.kind`); the API derives
34
34
  * its accepted-kinds set from these options, so the enum is the discoverable list. */
35
35
  export const DeploymentKind = z
36
- .enum(["whatsapp", "telegram", "slack", "discord", "sms", "voice", "email", "mcp"])
36
+ .enum([
37
+ "whatsapp",
38
+ "telegram",
39
+ "slack",
40
+ "discord",
41
+ "sms",
42
+ "voice",
43
+ "email",
44
+ "mcp",
45
+ "web",
46
+ ])
37
47
  .meta({ id: "DeploymentKind" });
38
48
 
39
49
  export const DeploymentOut = z
@@ -49,6 +59,9 @@ export const DeploymentOut = z
49
59
  /** The connectable MCP endpoint — present only for `kind: "mcp"`. Paste into
50
60
  * Claude / ChatGPT as the server URL; survives a later GET, not just create. */
51
61
  mcp_url: z.string().optional(),
62
+ /** The shareable hosted-page URL — present only for `kind: "web"`. Open in a
63
+ * browser to chat with the agent; survives a later GET, not just create. */
64
+ page_url: z.string().optional(),
52
65
  status: z.string(),
53
66
  created_at: z.string().nullable(),
54
67
  })
@@ -64,6 +77,7 @@ export const DeploymentListOut = pageOut(DeploymentOut, "DeploymentListOut");
64
77
  * - slack `provision`/`oauth_install`: `install_url`, `state`, optional `slack_app_id`.
65
78
  * - email `provision`: no extras (plain `DeploymentOut`).
66
79
  * - mcp: `mcp_url` (on the base `DeploymentOut`, so it also survives a GET).
80
+ * - web: `page_url` (on the base `DeploymentOut`, so it also survives a GET).
67
81
  * All are optional — which appear depends on the kind + setup mode.
68
82
  */
69
83
  export const DeploymentCreatedOut = DeploymentOut.extend({
@@ -153,3 +153,4 @@ export type ICSpanNode = z.infer<typeof SpanNodeOut>;
153
153
  export type ICTrace = z.infer<typeof TraceOut>;
154
154
  export type ICTraceDetail = z.infer<typeof TraceDetailOut>;
155
155
  export type ICUsageBreakdown = z.infer<typeof UsageBreakdownOut>;
156
+ export type ICUsageEvent = z.infer<typeof UsageEventOut>;
package/ts/zod/tenant.ts CHANGED
@@ -78,6 +78,35 @@ export const WebhookPatch = z
78
78
  })
79
79
  .meta({ id: "WebhookPatch" });
80
80
 
81
+ /** One persisted delivery attempt record for a webhook — the audit trail behind
82
+ * durable, retried delivery. `status` is `pending` | `succeeded` | `dead`. */
83
+ export const WebhookDeliveryOut = z
84
+ .object({
85
+ id: z.string(),
86
+ event_id: z.string(),
87
+ event_type: z.string(),
88
+ url: z.string(),
89
+ status: z.string(),
90
+ attempts: z.number(),
91
+ last_status: z.number().nullable(),
92
+ last_error: z.string(),
93
+ next_attempt_at: z.string().nullable(),
94
+ delivered_at: z.string().nullable(),
95
+ created_at: z.string().nullable(),
96
+ })
97
+ .meta({ id: "WebhookDeliveryOut" });
98
+
99
+ export const WebhookDeliveryListOut = pageOut(WebhookDeliveryOut, "WebhookDeliveryListOut");
100
+
101
+ /** The redeliver ack — the outcome of the forced re-attempt. */
102
+ export const WebhookRedeliverOut = z
103
+ .object({
104
+ delivery_id: z.string(),
105
+ delivered: z.boolean(),
106
+ status: z.number().nullable(),
107
+ })
108
+ .meta({ id: "WebhookRedeliverOut" });
109
+
81
110
  // ── Tokens (mint / list / revoke RS256 JWTs) ─────────────────────────────────
82
111
 
83
112
  /** A minted-token *summary* — the list/listing shape. The secret `token` is
@@ -213,6 +242,7 @@ export const ProviderOut = z
213
242
  token_uri: z.string().nullable(),
214
243
  scopes_allowed: z.array(z.string()),
215
244
  refresh_webhook: z.string().nullable(),
245
+ authorize_url: z.string().nullable(),
216
246
  has_client_secret: z.boolean(),
217
247
  })
218
248
  .meta({ id: "ProviderOut" });
@@ -236,9 +266,39 @@ export const ProviderIn = z
236
266
  token_uri: z.string().nullish(),
237
267
  scopes_allowed: z.array(z.string()).default([]),
238
268
  refresh_webhook: z.string().nullish(),
269
+ /** Tenant-hosted connector consent page (#123): the connector OAuth
270
+ * authorize endpoint redirects the end-user here (`?request_id=…`)
271
+ * instead of rendering the built-in connect-token page. */
272
+ authorize_url: z.string().nullish(),
239
273
  })
240
274
  .meta({ id: "ProviderIn" });
241
275
 
276
+ // ── Delegated connector consent (connector OAuth, #123) ─────────────────────
277
+
278
+ /** Render data for a tenant-hosted consent page: the pending authorize request
279
+ * stashed by `GET /oauth/authorize` when the tenant's provider registers an
280
+ * `authorize_url`. */
281
+ export const AuthorizeRequestOut = z
282
+ .object({
283
+ client_name: z.string(),
284
+ target_name: z.string(),
285
+ tenant: z.string(),
286
+ resource: z.string(),
287
+ deployment_id: z.string(),
288
+ })
289
+ .meta({ id: "AuthorizeRequestOut" });
290
+
291
+ /** Complete the delegated grant: the tenant asserts (server-to-server) which
292
+ * smith the end-user authorized. */
293
+ export const AuthorizeCompleteIn = z
294
+ .object({ smith_id: z.string() })
295
+ .meta({ id: "AuthorizeCompleteIn" });
296
+
297
+ /** Where the tenant 302s the browser after completing or declining. */
298
+ export const AuthorizeRedirectOut = z
299
+ .object({ redirect_url: z.string() })
300
+ .meta({ id: "AuthorizeRedirectOut" });
301
+
242
302
  // ── Hosted-tool catalog ──────────────────────────────────────────────────────
243
303
 
244
304
  /** One tool hosted by Ingram Cloud that the catalog advertises. */
@@ -257,6 +317,7 @@ export const HostedToolsListOut = z
257
317
 
258
318
  export type ICEvent = z.infer<typeof EventOut>;
259
319
  export type ICWebhook = z.infer<typeof WebhookOut>;
320
+ export type ICWebhookDelivery = z.infer<typeof WebhookDeliveryOut>;
260
321
  export type ICToken = z.infer<typeof TokenOut>;
261
322
  export type ICMintedToken = z.infer<typeof MintedTokenOut>;
262
323
  export type ICUsage = z.infer<typeof UsageOut>;
@@ -265,3 +326,4 @@ export type ICModelProvider = z.infer<typeof ModelProviderOut>;
265
326
  export type ICModelCatalog = z.infer<typeof ModelsListOut>;
266
327
  export type ICModelKey = z.infer<typeof ModelKeyOut>;
267
328
  export type ICProvider = z.infer<typeof ProviderOut>;
329
+ export type ICAuthorizeRequest = z.infer<typeof AuthorizeRequestOut>;