@noodleseed/one 0.184.0 → 0.185.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 (63) hide show
  1. package/dist/commands/solutions-conversations.d.ts.map +1 -1
  2. package/dist/commands/solutions-conversations.js +3 -3
  3. package/dist/commands/solutions-conversations.js.map +1 -1
  4. package/dist/commands/solutions-history.d.ts.map +1 -1
  5. package/dist/commands/solutions-history.js +6 -3
  6. package/dist/commands/solutions-history.js.map +1 -1
  7. package/dist/commands/whatsapp-ops.d.ts +2 -1
  8. package/dist/commands/whatsapp-ops.d.ts.map +1 -1
  9. package/dist/commands/whatsapp-ops.js +63 -27
  10. package/dist/commands/whatsapp-ops.js.map +1 -1
  11. package/dist/commands/whatsapp-output.d.ts +1 -1
  12. package/dist/commands/whatsapp-output.d.ts.map +1 -1
  13. package/dist/commands/whatsapp-output.js +13 -7
  14. package/dist/commands/whatsapp-output.js.map +1 -1
  15. package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +1 -1
  16. package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.js +2 -2
  17. package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
  18. package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-model-context.js +7 -2
  19. package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-turn-context.d.ts +2 -1
  20. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-coordinator.d.ts +88 -8
  21. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-coordinator.js +42 -30
  22. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-spend.js +2 -2
  23. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-types.d.ts +60 -11
  24. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-types.js +31 -3
  25. package/node_modules/@noodle-borg/assistant-gateway/dist/model-request.d.ts +2 -1
  26. package/node_modules/@noodle-borg/assistant-gateway/dist/public-surface.d.ts +4 -2
  27. package/node_modules/@noodle-borg/assistant-gateway/dist/public-surface.js +4 -3
  28. package/node_modules/@noodle-borg/authoring/dist/assistant.d.ts +2 -1
  29. package/node_modules/@noodle-borg/authoring/dist/assistant.js +5 -4
  30. package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-channels.js +72 -51
  31. package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-solution-conversations.js +1 -1
  32. package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-solution-history.js +1 -0
  33. package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts +16 -4
  34. package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js +8 -3
  35. package/node_modules/@noodle-borg/runtime/dist/connector/types.d.ts +1 -1
  36. package/node_modules/@noodle-borg/service/dist/application-history-settings.js +6 -2
  37. package/node_modules/@noodle-borg/service/dist/build-info.js +3 -2
  38. package/node_modules/@noodle-borg/service/dist/channels/instagram-meta.js +196 -0
  39. package/node_modules/@noodle-borg/service/dist/channels/instagram-webhook.js +78 -0
  40. package/node_modules/@noodle-borg/service/dist/channels/provider.js +1 -1
  41. package/node_modules/@noodle-borg/service/dist/channels/reply-bound.js +24 -0
  42. package/node_modules/@noodle-borg/service/dist/channels/runtime.js +35 -24
  43. package/node_modules/@noodle-borg/service/dist/conversation-history/capture.js +5 -5
  44. package/node_modules/@noodle-borg/service/dist/conversation-history/contracts.js +2 -1
  45. package/node_modules/@noodle-borg/service/dist/conversation-history/operator.js +2 -2
  46. package/node_modules/@noodle-borg/service/dist/routes/instagram-meta.js +79 -0
  47. package/node_modules/@noodle-borg/service/dist/routes/meta-webhook.js +36 -0
  48. package/node_modules/@noodle-borg/service/dist/routes/service-probes.js +4 -1
  49. package/node_modules/@noodle-borg/service/dist/routes/whatsapp-meta.js +3 -34
  50. package/node_modules/@noodle-borg/service/dist/routes/whatsapp.js +45 -24
  51. package/node_modules/@noodle-borg/service/dist/service.js +1 -1
  52. package/node_modules/@noodle-borg/service/package.json +1 -1
  53. package/node_modules/@noodle-borg/wire-contracts/dist/application-history-settings.d.ts +7 -0
  54. package/node_modules/@noodle-borg/wire-contracts/dist/application-history-settings.js +1 -0
  55. package/node_modules/@noodle-borg/wire-contracts/dist/conversation-history.d.ts +12 -0
  56. package/node_modules/@noodle-borg/wire-contracts/dist/conversation-history.js +1 -1
  57. package/node_modules/@noodle-borg/wire-contracts/dist/index.d.ts +1 -0
  58. package/node_modules/@noodle-borg/wire-contracts/dist/index.js +1 -0
  59. package/node_modules/@noodle-borg/wire-contracts/dist/instagram.d.ts +181 -0
  60. package/node_modules/@noodle-borg/wire-contracts/dist/instagram.js +50 -0
  61. package/node_modules/@noodle-borg/wire-contracts/dist/service-info.d.ts +2 -0
  62. package/node_modules/@noodle-borg/wire-contracts/dist/service-info.js +3 -0
  63. package/package.json +2 -2
@@ -0,0 +1,36 @@
1
+ import { createHmac, timingSafeEqual } from 'node:crypto';
2
+ import { sendJson } from '@noodle-borg/transport-http';
3
+ /** Meta webhook authentication shared by every channel on Noodle Seed's Meta app. */
4
+ export const META_SIGNATURE_HEADER = 'x-hub-signature-256';
5
+ /** After a valid signature, only these failures answer non-200 so Meta retries. */
6
+ export const META_RETRYABLE = new Set([
7
+ 'ingress_capacity',
8
+ 'channel_unavailable',
9
+ 'history_policy_unavailable',
10
+ ]);
11
+ function same(actual, expected) {
12
+ const left = Buffer.from(actual), right = Buffer.from(expected);
13
+ return left.length === right.length && timingSafeEqual(left, right);
14
+ }
15
+ export function verifyMetaSignature(raw, header, appSecret) {
16
+ if (typeof header !== 'string' || !/^sha256=[a-f0-9]{64}$/i.test(header))
17
+ return false;
18
+ const expected = createHmac('sha256', appSecret).update(raw).digest();
19
+ const actual = Buffer.from(header.slice(7), 'hex');
20
+ return actual.length === expected.length && timingSafeEqual(actual, expected);
21
+ }
22
+ export function handshake(res, url, verifyToken) {
23
+ const token = url.searchParams.get('hub.verify_token');
24
+ const challenge = url.searchParams.get('hub.challenge');
25
+ if (url.searchParams.get('hub.mode') !== 'subscribe' ||
26
+ token === null ||
27
+ challenge === null ||
28
+ !/^[\x21-\x7e]{1,1024}$/.test(challenge) ||
29
+ !same(token, verifyToken)) {
30
+ sendJson(res, 403, { error: 'forbidden' });
31
+ return;
32
+ }
33
+ res.writeHead(200, { 'content-type': 'text/plain; charset=utf-8' });
34
+ res.end(challenge);
35
+ }
36
+ //# sourceMappingURL=meta-webhook.js.map
@@ -26,7 +26,10 @@ function handleServiceProbe(req, res, url, { tls, moduleHost, buildInfo, options
26
26
  // post-deploy smoke can confirm exactly which commit is live. Non-sensitive fields only.
27
27
  if (req.method === 'GET' && url.pathname === '/v1/service/info') {
28
28
  applySecurityHeaders(res, tls);
29
- return sendJson(res, 200, serviceInfoPayload(buildInfo, options.developerMcp === true, whatsapp !== undefined));
29
+ return sendJson(res, 200, serviceInfoPayload(buildInfo, options.developerMcp === true, {
30
+ whatsapp: whatsapp !== undefined,
31
+ instagram: whatsapp?.options.meta !== undefined,
32
+ }));
30
33
  }
31
34
  }
32
35
  //# sourceMappingURL=service-probes.js.map
@@ -1,8 +1,8 @@
1
- import { createHmac, timingSafeEqual } from 'node:crypto';
2
1
  import { ChannelError, recordChannelDelivery } from '@noodle-borg/assistant-gateway/portable';
3
2
  import { readBodyBuffer, sendJson } from '@noodle-borg/transport-http';
4
3
  import { z } from 'zod';
5
4
  import { parseWhatsAppWebhook } from '../channels/360dialog.js';
5
+ import { handshake, META_RETRYABLE as RETRYABLE, META_SIGNATURE_HEADER as SIGNATURE_HEADER, verifyMetaSignature, } from './meta-webhook.js';
6
6
  /**
7
7
  * Meta webhook endpoint contract, read 2026-09-22
8
8
  * (https://developers.facebook.com/documentation/business-messaging/whatsapp/webhooks/create-webhook-endpoint):
@@ -12,12 +12,6 @@ import { parseWhatsAppWebhook } from '../channels/360dialog.js';
12
12
  * days (https://developers.facebook.com/docs/whatsapp/cloud-api/guides/set-up-webhooks), so after a
13
13
  * valid signature only a retryable failure answers otherwise.
14
14
  */
15
- const SIGNATURE_HEADER = 'x-hub-signature-256';
16
- const RETRYABLE = new Set([
17
- 'ingress_capacity',
18
- 'channel_unavailable',
19
- 'history_policy_unavailable',
20
- ]);
21
15
  const envelope = z.object({
22
16
  object: z.literal('whatsapp_business_account'),
23
17
  entry: z
@@ -28,31 +22,6 @@ const envelope = z.object({
28
22
  .max(100),
29
23
  });
30
24
  const routed = z.object({ metadata: z.object({ phone_number_id: z.string().min(1).max(512) }) });
31
- function same(actual, expected) {
32
- const left = Buffer.from(actual), right = Buffer.from(expected);
33
- return left.length === right.length && timingSafeEqual(left, right);
34
- }
35
- export function verifyMetaSignature(raw, header, appSecret) {
36
- if (typeof header !== 'string' || !/^sha256=[a-f0-9]{64}$/i.test(header))
37
- return false;
38
- const expected = createHmac('sha256', appSecret).update(raw).digest();
39
- const actual = Buffer.from(header.slice(7), 'hex');
40
- return actual.length === expected.length && timingSafeEqual(actual, expected);
41
- }
42
- function handshake(res, url, verifyToken) {
43
- const token = url.searchParams.get('hub.verify_token');
44
- const challenge = url.searchParams.get('hub.challenge');
45
- if (url.searchParams.get('hub.mode') !== 'subscribe' ||
46
- token === null ||
47
- challenge === null ||
48
- !/^[\x21-\x7e]{1,1024}$/.test(challenge) ||
49
- !same(token, verifyToken)) {
50
- sendJson(res, 403, { error: 'forbidden' });
51
- return;
52
- }
53
- res.writeHead(200, { 'content-type': 'text/plain; charset=utf-8' });
54
- res.end(challenge);
55
- }
56
25
  export async function metaWebhook(req, res, url, runtime) {
57
26
  const meta = runtime.options.meta;
58
27
  if (!meta)
@@ -101,11 +70,11 @@ export async function metaWebhook(req, res, url, runtime) {
101
70
  skip('batch_too_large');
102
71
  for (const [phoneNumberId, group] of groups) {
103
72
  try {
104
- const id = await runtime.channels.bindingForAsset(phoneNumberId);
73
+ const id = await runtime.channels.bindingForAsset('whatsapp', phoneNumberId);
105
74
  if (!id)
106
75
  throw new ChannelError('binding_unknown');
107
76
  const binding = await runtime.channels.internal(id);
108
- if (binding.provider !== 'meta')
77
+ if (binding.channel !== 'whatsapp' || binding.provider !== 'meta')
109
78
  throw new ChannelError('provider_mismatch');
110
79
  // Defense in depth: the number must arrive under the WABA the operator bound it to.
111
80
  const changes = group.filter((item) => item.waba === binding.wabaId);
@@ -2,8 +2,10 @@ import { ChannelError, channelParticipantId, recordChannelDelivery, } from '@noo
2
2
  import { readJsonBody, sendJson } from '@noodle-borg/transport-http';
3
3
  import * as wire from '@noodle-borg/wire-contracts';
4
4
  import { parseWhatsAppWebhook, verifyWhatsAppWebhookSecret, WHATSAPP_CALLBACK_HEADER, } from '../channels/360dialog.js';
5
+ import { INSTAGRAM_META_CALLBACK_PATH } from '../channels/instagram-meta.js';
5
6
  import { WHATSAPP_META_CALLBACK_PATH } from '../channels/meta-cloud.js';
6
7
  import { authorizeTenantControl, developerGrantRouteAccess } from './control-plane.js';
8
+ import { instagramWebhook } from './instagram-meta.js';
7
9
  import { metaWebhook } from './whatsapp-meta.js';
8
10
  const participant = /^p_[a-f0-9]{64}$/;
9
11
  const eventId = /^e_[0-9_]+$/;
@@ -33,9 +35,10 @@ async function body(req, schema) {
33
35
  }
34
36
  export function dispatchWhatsAppRoutes(req, res, url, runtime, grants) {
35
37
  const callback = /^\/v1\/channels\/whatsapp\/webhooks\/([a-z0-9-]+)$/.exec(url.pathname);
36
- const operator = /^\/v1\/orgs\/([^/]+)\/apps\/([^/]+)\/envs\/([^/]+)\/channels\/whatsapp(?:\/(.*))?$/.exec(url.pathname);
38
+ const operator = /^\/v1\/orgs\/([^/]+)\/apps\/([^/]+)\/envs\/([^/]+)\/channels\/(whatsapp|instagram)(?:\/(.*))?$/.exec(url.pathname);
37
39
  const meta = url.pathname === WHATSAPP_META_CALLBACK_PATH;
38
- if (!callback && !operator && !meta)
40
+ const instagram = url.pathname === INSTAGRAM_META_CALLBACK_PATH;
41
+ if (!callback && !operator && !meta && !instagram)
39
42
  return false;
40
43
  res.setHeader('Cache-Control', 'no-store');
41
44
  if (!runtime) {
@@ -47,13 +50,15 @@ export function dispatchWhatsAppRoutes(req, res, url, runtime, grants) {
47
50
  }
48
51
  const run = Promise.resolve().then(() => meta
49
52
  ? metaWebhook(req, res, url, runtime)
50
- : callback
51
- ? webhook(req, res, callback[1], runtime)
52
- : operate(req, res, url, {
53
- org: decodeURIComponent(operator[1]),
54
- app: decodeURIComponent(operator[2]),
55
- env: decodeURIComponent(operator[3]),
56
- }, operator[4] ?? '', runtime, grants));
53
+ : instagram
54
+ ? instagramWebhook(req, res, url, runtime)
55
+ : callback
56
+ ? webhook(req, res, callback[1], runtime)
57
+ : operate(req, res, url, {
58
+ org: decodeURIComponent(operator[1]),
59
+ app: decodeURIComponent(operator[2]),
60
+ env: decodeURIComponent(operator[3]),
61
+ }, operator[4], operator[5] ?? '', runtime, grants));
57
62
  void run.catch((error) => {
58
63
  const code = error instanceof ChannelError ? error.code : 'channel_unavailable';
59
64
  const status = code === 'channel_not_found'
@@ -79,7 +84,7 @@ async function webhook(req, res, id, runtime) {
79
84
  return sendJson(res, 405, { error: 'method_not_allowed' });
80
85
  const binding = await runtime.channels.internal(id);
81
86
  // Meta numbers share the signed app callback; only 360dialog has a per-binding address.
82
- if (binding.provider !== '360dialog')
87
+ if (binding.channel !== 'whatsapp' || binding.provider !== '360dialog')
83
88
  return sendJson(res, 404, { error: 'not_found' });
84
89
  const { webhookSecret } = await runtime.provider(binding);
85
90
  if (!webhookSecret ||
@@ -95,7 +100,7 @@ async function webhook(req, res, id, runtime) {
95
100
  sendJson(res, 200, { ok: true });
96
101
  runtime.options.worker.wake();
97
102
  }
98
- async function operate(req, res, url, tenant, path, runtime, grants) {
103
+ async function operate(req, res, url, tenant, channel, path, runtime, grants) {
99
104
  const { deps, channels } = runtime;
100
105
  const read = req.method === 'GET';
101
106
  const identity = await authorizeTenantControl(req, res, deps.gate, deps.controlPlane, tenant.org, developerGrantRouteAccess(grants, read ? 'cloud:read' : 'config:write'));
@@ -111,7 +116,11 @@ async function operate(req, res, url, tenant, path, runtime, grants) {
111
116
  if (!read && (typeof key !== 'string' || !key || key.length > 200))
112
117
  throw new ChannelError('idempotency_key_invalid');
113
118
  const idempotency = typeof key === 'string' ? key : '';
114
- const visible = await channels.get(tenant);
119
+ const visible = await channels.get(tenant, channel);
120
+ // Every other operation's shape is channel-neutral; the binding and its configuration are not.
121
+ const bindingSchema = channel === 'instagram'
122
+ ? wire.InstagramBindingResponseSchema
123
+ : wire.WhatsAppBindingResponseSchema;
115
124
  const audit = async (action) => deps.audit.emit({
116
125
  eventType: `assistant.channel.${action}`,
117
126
  ...tenant,
@@ -120,16 +129,23 @@ async function operate(req, res, url, tenant, path, runtime, grants) {
120
129
  status: 200,
121
130
  });
122
131
  if (!path && req.method === 'GET')
123
- return respond(res, wire.WhatsAppBindingResponseSchema, visible ?? null);
132
+ return respond(res, bindingSchema, visible ?? null);
124
133
  if (!path && req.method === 'PUT') {
125
- const parsed = await body(req, wire.WhatsAppConfigureRequestSchema);
126
134
  const target = await deps.registry.getActiveByTenant(tenant);
127
135
  if (!target?.deploymentId)
128
136
  throw new ChannelError('deployment_missing');
129
- const { expectedRevision, ...configuration } = parsed;
130
- const configured = await channels.configure({ ...configuration, tenant, deploymentId: target.deploymentId }, identity.subject, idempotency, expectedRevision);
137
+ const deploymentId = target.deploymentId;
138
+ let configured;
139
+ if (channel === 'instagram') {
140
+ const { expectedRevision, ...configuration } = await body(req, wire.InstagramConfigureRequestSchema);
141
+ configured = await channels.configure({ ...configuration, channel, tenant, deploymentId }, identity.subject, idempotency, expectedRevision);
142
+ }
143
+ else {
144
+ const { expectedRevision, ...configuration } = await body(req, wire.WhatsAppConfigureRequestSchema);
145
+ configured = await channels.configure({ ...configuration, tenant, deploymentId }, identity.subject, idempotency, expectedRevision);
146
+ }
131
147
  await audit('configured');
132
- return respond(res, wire.WhatsAppBindingResponseSchema, configured);
148
+ return respond(res, bindingSchema, configured);
133
149
  }
134
150
  if (!visible)
135
151
  throw new ChannelError('channel_not_found');
@@ -147,15 +163,15 @@ async function operate(req, res, url, tenant, path, runtime, grants) {
147
163
  };
148
164
  const updated = await channels.setState(id, parsed.state, identity.subject, idempotency, parsed.expectedRevision);
149
165
  await audit(parsed.state);
150
- return respond(res, wire.WhatsAppBindingResponseSchema, updated);
166
+ return respond(res, bindingSchema, updated);
151
167
  }
152
168
  if (path === 'limits' && req.method === 'GET')
153
- return respond(res, wire.WhatsAppBindingResponseSchema, visible);
169
+ return respond(res, bindingSchema, visible);
154
170
  if (path === 'limits' && req.method === 'PATCH') {
155
171
  const parsed = await body(req, wire.WhatsAppLimitsRequestSchema);
156
172
  const updated = await channels.updateLimits(id, parsed.limits, identity.subject, idempotency, parsed.expectedRevision);
157
173
  await audit('limits_changed');
158
- return respond(res, wire.WhatsAppBindingResponseSchema, updated);
174
+ return respond(res, bindingSchema, updated);
159
175
  }
160
176
  if (path === 'usage' && read)
161
177
  return respond(res, wire.WhatsAppUsageResponseSchema, await channels.usage(id));
@@ -176,12 +192,15 @@ async function operate(req, res, url, tenant, path, runtime, grants) {
176
192
  return sendJson(res, 200, wire.WhatsAppBlocksResponseSchema.parse({ ok: true, ...(await runtime.blocks(id, after)) }));
177
193
  }
178
194
  if (path === 'blocks' && req.method === 'POST') {
179
- const parsed = await body(req, wire.WhatsAppBlockRequestSchema);
180
- const participantId = parsed.participantId ??
181
- channelParticipantId(await channels.internal(id), {
195
+ const parsed = channel === 'instagram'
196
+ ? await body(req, wire.InstagramBlockRequestSchema)
197
+ : await body(req, wire.WhatsAppBlockRequestSchema);
198
+ const participantId = 'phone' in parsed && parsed.phone
199
+ ? channelParticipantId(await channels.internal(id), {
182
200
  kind: 'phone',
183
201
  value: parsed.phone.slice(1),
184
- });
202
+ })
203
+ : parsed.participantId;
185
204
  await channels.block(id, participantId, identity.subject, idempotency, parsed.until);
186
205
  if (parsed.scope === 'provider')
187
206
  await runtime.providerBlock(id, participantId, true, identity.subject, idempotency);
@@ -191,6 +210,8 @@ async function operate(req, res, url, tenant, path, runtime, grants) {
191
210
  const [kind, value, action] = path.split('/');
192
211
  if (kind === 'blocks' && value && participant.test(value) && req.method === 'DELETE') {
193
212
  const parsed = await body(req, wire.WhatsAppUnblockRequestSchema);
213
+ if (channel === 'instagram' && parsed.phone)
214
+ throw new ChannelError('request_invalid');
194
215
  if (parsed.scope === 'provider')
195
216
  await runtime.providerBlock(id, value, false, identity.subject, idempotency, parsed.phone);
196
217
  else
@@ -352,7 +352,7 @@ export function createServiceHandler(registry, options = {}) {
352
352
  })) {
353
353
  return;
354
354
  }
355
- if (url.pathname.includes('/channels/whatsapp')) {
355
+ if (/\/channels\/(whatsapp|instagram)(\/|$)/.test(url.pathname)) {
356
356
  applySecurityHeaders(res, tls);
357
357
  if (enforceHttps(req, res, tls))
358
358
  return;
@@ -41,7 +41,7 @@
41
41
  "@noodle-borg/managed-capabilities": "0.0.0",
42
42
  "@modelcontextprotocol/sdk": "^1.29.0",
43
43
  "@noodle-borg/admission-limits": "0.0.0",
44
- "@noodle-borg/agent-kit": "0.109.0",
44
+ "@noodle-borg/agent-kit": "0.110.0",
45
45
  "@noodle-borg/app-package": "0.0.0",
46
46
  "@noodle-borg/assistant-gateway": "0.0.0",
47
47
  "@noodle-borg/auth": "0.0.0",
@@ -3,6 +3,7 @@ export declare const HistorySourcesSchema: z.ZodObject<{
3
3
  websiteVisitors: z.ZodBoolean;
4
4
  signedInCustomers: z.ZodBoolean;
5
5
  whatsapp: z.ZodBoolean;
6
+ instagram: z.ZodBoolean;
6
7
  }, z.core.$strict>;
7
8
  /** A surface the application declared `history: false` on, named by its authoring constructor. */
8
9
  export declare const ApplicationHistoryDisabledSurfaceSchema: z.ZodEnum<{
@@ -28,6 +29,7 @@ export declare const ApplicationHistorySettingsSchema: z.ZodObject<{
28
29
  websiteVisitors: z.ZodBoolean;
29
30
  signedInCustomers: z.ZodBoolean;
30
31
  whatsapp: z.ZodBoolean;
32
+ instagram: z.ZodBoolean;
31
33
  }, z.core.$strict>;
32
34
  disabledByApplication: z.ZodOptional<z.ZodArray<z.ZodEnum<{
33
35
  publicWebsite: "publicWebsite";
@@ -56,6 +58,7 @@ export declare const ApplicationHistorySettingsResponseSchema: z.ZodObject<{
56
58
  websiteVisitors: z.ZodBoolean;
57
59
  signedInCustomers: z.ZodBoolean;
58
60
  whatsapp: z.ZodBoolean;
61
+ instagram: z.ZodBoolean;
59
62
  }, z.core.$strict>;
60
63
  disabledByApplication: z.ZodOptional<z.ZodArray<z.ZodEnum<{
61
64
  publicWebsite: "publicWebsite";
@@ -76,6 +79,7 @@ export declare const ApplicationHistorySettingsSaveRequestSchema: z.ZodObject<{
76
79
  websiteVisitors: z.ZodOptional<z.ZodBoolean>;
77
80
  signedInCustomers: z.ZodOptional<z.ZodBoolean>;
78
81
  whatsapp: z.ZodOptional<z.ZodBoolean>;
82
+ instagram: z.ZodOptional<z.ZodBoolean>;
79
83
  }, z.core.$strict>>;
80
84
  dryRun: z.ZodOptional<z.ZodBoolean>;
81
85
  }, z.core.$strict>;
@@ -106,6 +110,7 @@ export declare const ApplicationHistorySettingsSaveResponseSchema: z.ZodObject<{
106
110
  websiteVisitors: z.ZodBoolean;
107
111
  signedInCustomers: z.ZodBoolean;
108
112
  whatsapp: z.ZodBoolean;
113
+ instagram: z.ZodBoolean;
109
114
  }, z.core.$strict>;
110
115
  disabledByApplication: z.ZodOptional<z.ZodArray<z.ZodEnum<{
111
116
  publicWebsite: "publicWebsite";
@@ -129,6 +134,7 @@ export declare const ApplicationHistorySettingsClientResponseSchema: z.ZodObject
129
134
  websiteVisitors: z.ZodBoolean;
130
135
  signedInCustomers: z.ZodBoolean;
131
136
  whatsapp: z.ZodBoolean;
137
+ instagram: z.ZodBoolean;
132
138
  }, z.core.$strip>;
133
139
  state: z.ZodEnum<{
134
140
  off: "off";
@@ -163,6 +169,7 @@ export declare const ApplicationHistorySettingsSaveClientResponseSchema: z.ZodOb
163
169
  websiteVisitors: z.ZodBoolean;
164
170
  signedInCustomers: z.ZodBoolean;
165
171
  whatsapp: z.ZodBoolean;
172
+ instagram: z.ZodBoolean;
166
173
  }, z.core.$strip>;
167
174
  state: z.ZodEnum<{
168
175
  off: "off";
@@ -11,6 +11,7 @@ export const HistorySourcesSchema = z.strictObject({
11
11
  websiteVisitors: z.boolean(),
12
12
  signedInCustomers: z.boolean(),
13
13
  whatsapp: z.boolean(),
14
+ instagram: z.boolean(),
14
15
  });
15
16
  /** A surface the application declared `history: false` on, named by its authoring constructor. */
16
17
  export const ApplicationHistoryDisabledSurfaceSchema = z.enum([
@@ -6,6 +6,7 @@ import { z } from 'zod';
6
6
  export declare const ConversationIdSchema: z.ZodString;
7
7
  export declare const ConversationChannelSchema: z.ZodEnum<{
8
8
  whatsapp: "whatsapp";
9
+ instagram: "instagram";
9
10
  website: "website";
10
11
  }>;
11
12
  /** Staff review state; a failed tool outcome sets `needs_attention` automatically. */
@@ -19,6 +20,7 @@ export declare const ConversationSummarySchema: z.ZodObject<{
19
20
  id: z.ZodString;
20
21
  channel: z.ZodEnum<{
21
22
  whatsapp: "whatsapp";
23
+ instagram: "instagram";
22
24
  website: "website";
23
25
  }>;
24
26
  subject: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -84,6 +86,7 @@ export declare const ConversationDetailSchema: z.ZodObject<{
84
86
  id: z.ZodString;
85
87
  channel: z.ZodEnum<{
86
88
  whatsapp: "whatsapp";
89
+ instagram: "instagram";
87
90
  website: "website";
88
91
  }>;
89
92
  subject: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -141,6 +144,7 @@ export declare const ConversationShowSchema: z.ZodObject<{
141
144
  id: z.ZodString;
142
145
  channel: z.ZodEnum<{
143
146
  whatsapp: "whatsapp";
147
+ instagram: "instagram";
144
148
  website: "website";
145
149
  }>;
146
150
  subject: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -168,6 +172,7 @@ export declare const ConversationListResponseSchema: z.ZodObject<{
168
172
  id: z.ZodString;
169
173
  channel: z.ZodEnum<{
170
174
  whatsapp: "whatsapp";
175
+ instagram: "instagram";
171
176
  website: "website";
172
177
  }>;
173
178
  subject: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -228,6 +233,7 @@ export declare const ConversationShowResponseSchema: z.ZodObject<{
228
233
  id: z.ZodString;
229
234
  channel: z.ZodEnum<{
230
235
  whatsapp: "whatsapp";
236
+ instagram: "instagram";
231
237
  website: "website";
232
238
  }>;
233
239
  subject: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -288,6 +294,7 @@ export declare const ConversationExportResponseSchema: z.ZodObject<{
288
294
  id: z.ZodString;
289
295
  channel: z.ZodEnum<{
290
296
  whatsapp: "whatsapp";
297
+ instagram: "instagram";
291
298
  website: "website";
292
299
  }>;
293
300
  subject: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -348,6 +355,7 @@ export declare const ConversationListClientResponseSchema: z.ZodObject<{
348
355
  id: z.ZodString;
349
356
  channel: z.ZodEnum<{
350
357
  whatsapp: "whatsapp";
358
+ instagram: "instagram";
351
359
  website: "website";
352
360
  }>;
353
361
  startedAt: z.ZodISODateTime;
@@ -407,6 +415,7 @@ export declare const ConversationShowClientResponseSchema: z.ZodObject<{
407
415
  id: z.ZodString;
408
416
  channel: z.ZodEnum<{
409
417
  whatsapp: "whatsapp";
418
+ instagram: "instagram";
410
419
  website: "website";
411
420
  }>;
412
421
  startedAt: z.ZodISODateTime;
@@ -457,6 +466,7 @@ export declare const ConversationExportClientResponseSchema: z.ZodObject<{
457
466
  id: z.ZodString;
458
467
  channel: z.ZodEnum<{
459
468
  whatsapp: "whatsapp";
469
+ instagram: "instagram";
460
470
  website: "website";
461
471
  }>;
462
472
  startedAt: z.ZodISODateTime;
@@ -501,6 +511,7 @@ export declare const AssistantConversationListResponseSchema: z.ZodObject<{
501
511
  id: z.ZodString;
502
512
  channel: z.ZodEnum<{
503
513
  whatsapp: "whatsapp";
514
+ instagram: "instagram";
504
515
  website: "website";
505
516
  }>;
506
517
  startedAt: z.ZodISODateTime;
@@ -517,6 +528,7 @@ export declare const AssistantConversationListClientResponseSchema: z.ZodObject<
517
528
  id: z.ZodString;
518
529
  channel: z.ZodEnum<{
519
530
  whatsapp: "whatsapp";
531
+ instagram: "instagram";
520
532
  website: "website";
521
533
  }>;
522
534
  startedAt: z.ZodISODateTime;
@@ -4,7 +4,7 @@ import { z } from 'zod';
4
4
  * `*ClientResponseSchema` variants let older clients ignore additive fields.
5
5
  */
6
6
  export const ConversationIdSchema = z.string().regex(/^cv_[A-Za-z0-9_-]{8,64}$/);
7
- export const ConversationChannelSchema = z.enum(['website', 'whatsapp']);
7
+ export const ConversationChannelSchema = z.enum(['website', 'whatsapp', 'instagram']);
8
8
  /** Staff review state; a failed tool outcome sets `needs_attention` automatically. */
9
9
  export const ConversationReviewStatusSchema = z.enum(['new', 'needs_attention', 'reviewed']);
10
10
  const SubjectRefSchema = z.string().min(1).max(256);
@@ -397,6 +397,7 @@ export * from './billing-catalog.js';
397
397
  export * from './business-workspaces.js';
398
398
  export * from './conversation-history.js';
399
399
  export * from './deployment-deletion.js';
400
+ export * from './instagram.js';
400
401
  export * from './native-record-lifecycle.js';
401
402
  export * from './operation-coordination.js';
402
403
  export { MIXED_CUSTOMER_AUTH_FEATURE_VERSION, type ServiceInfoClientResponse, type ServiceInfoResponse, serviceInfoClientResponseSchema, serviceInfoResponseSchema, } from './service-info.js';
@@ -236,6 +236,7 @@ export * from './billing-catalog.js';
236
236
  export * from './business-workspaces.js';
237
237
  export * from './conversation-history.js';
238
238
  export * from './deployment-deletion.js';
239
+ export * from './instagram.js';
239
240
  export * from './native-record-lifecycle.js';
240
241
  export * from './operation-coordination.js';
241
242
  export { MIXED_CUSTOMER_AUTH_FEATURE_VERSION, serviceInfoClientResponseSchema, serviceInfoResponseSchema, } from './service-info.js';
@@ -0,0 +1,181 @@
1
+ import { z } from 'zod';
2
+ export declare const InstagramConfigureRequestSchema: z.ZodObject<{
3
+ expectedRevision: z.ZodNumber;
4
+ instagramAccountId: z.ZodString;
5
+ pageId: z.ZodString;
6
+ apiKeySecret: z.ZodString;
7
+ capabilities: z.ZodArray<z.ZodObject<{
8
+ kind: z.ZodEnum<{
9
+ tool: "tool";
10
+ knowledge: "knowledge";
11
+ }>;
12
+ name: z.ZodString;
13
+ }, z.core.$strict>>;
14
+ supportEmail: z.ZodEmail;
15
+ limits: z.ZodOptional<z.ZodObject<{
16
+ perMinute: z.ZodOptional<z.ZodNumber>;
17
+ perHour: z.ZodOptional<z.ZodNumber>;
18
+ perDay: z.ZodOptional<z.ZodNumber>;
19
+ channelPerDay: z.ZodOptional<z.ZodNumber>;
20
+ newParticipantsPerDay: z.ZodOptional<z.ZodNumber>;
21
+ concurrent: z.ZodOptional<z.ZodNumber>;
22
+ pendingPerParticipant: z.ZodOptional<z.ZodNumber>;
23
+ pending: z.ZodOptional<z.ZodNumber>;
24
+ textCharacters: z.ZodOptional<z.ZodNumber>;
25
+ dailyMicroUsd: z.ZodOptional<z.ZodNumber>;
26
+ }, z.core.$strict>>;
27
+ }, z.core.$strict>;
28
+ export declare const InstagramBindingSchema: z.ZodObject<{
29
+ createdAt: z.ZodNumber;
30
+ id: z.ZodString;
31
+ state: z.ZodEnum<{
32
+ paused: "paused";
33
+ enabled: "enabled";
34
+ disconnected: "disconnected";
35
+ }>;
36
+ revision: z.ZodNumber;
37
+ capabilities: z.ZodArray<z.ZodObject<{
38
+ kind: z.ZodEnum<{
39
+ tool: "tool";
40
+ knowledge: "knowledge";
41
+ }>;
42
+ name: z.ZodString;
43
+ }, z.core.$strict>>;
44
+ deploymentId: z.ZodString;
45
+ updatedAt: z.ZodNumber;
46
+ generation: z.ZodNumber;
47
+ limits: z.ZodObject<{
48
+ perMinute: z.ZodNumber;
49
+ perHour: z.ZodNumber;
50
+ perDay: z.ZodNumber;
51
+ channelPerDay: z.ZodNumber;
52
+ newParticipantsPerDay: z.ZodNumber;
53
+ concurrent: z.ZodNumber;
54
+ pendingPerParticipant: z.ZodNumber;
55
+ pending: z.ZodNumber;
56
+ textCharacters: z.ZodNumber;
57
+ dailyMicroUsd: z.ZodNumber;
58
+ }, z.core.$strict>;
59
+ apiKeySecret: z.ZodString;
60
+ supportEmail: z.ZodEmail;
61
+ tenant: z.ZodObject<{
62
+ org: z.ZodString;
63
+ app: z.ZodString;
64
+ env: z.ZodString;
65
+ }, z.core.$strict>;
66
+ actor: z.ZodString;
67
+ readyRevision: z.ZodOptional<z.ZodNumber>;
68
+ readyAt: z.ZodOptional<z.ZodNumber>;
69
+ channel: z.ZodLiteral<"instagram">;
70
+ provider: z.ZodLiteral<"meta">;
71
+ instagramAccountId: z.ZodString;
72
+ pageId: z.ZodString;
73
+ }, z.core.$strict>;
74
+ export declare const InstagramBindingResponseSchema: z.ZodObject<{
75
+ ok: z.ZodLiteral<true>;
76
+ data: z.ZodNullable<z.ZodObject<{
77
+ createdAt: z.ZodNumber;
78
+ id: z.ZodString;
79
+ state: z.ZodEnum<{
80
+ paused: "paused";
81
+ enabled: "enabled";
82
+ disconnected: "disconnected";
83
+ }>;
84
+ revision: z.ZodNumber;
85
+ capabilities: z.ZodArray<z.ZodObject<{
86
+ kind: z.ZodEnum<{
87
+ tool: "tool";
88
+ knowledge: "knowledge";
89
+ }>;
90
+ name: z.ZodString;
91
+ }, z.core.$strict>>;
92
+ deploymentId: z.ZodString;
93
+ updatedAt: z.ZodNumber;
94
+ generation: z.ZodNumber;
95
+ limits: z.ZodObject<{
96
+ perMinute: z.ZodNumber;
97
+ perHour: z.ZodNumber;
98
+ perDay: z.ZodNumber;
99
+ channelPerDay: z.ZodNumber;
100
+ newParticipantsPerDay: z.ZodNumber;
101
+ concurrent: z.ZodNumber;
102
+ pendingPerParticipant: z.ZodNumber;
103
+ pending: z.ZodNumber;
104
+ textCharacters: z.ZodNumber;
105
+ dailyMicroUsd: z.ZodNumber;
106
+ }, z.core.$strict>;
107
+ apiKeySecret: z.ZodString;
108
+ supportEmail: z.ZodEmail;
109
+ tenant: z.ZodObject<{
110
+ org: z.ZodString;
111
+ app: z.ZodString;
112
+ env: z.ZodString;
113
+ }, z.core.$strict>;
114
+ actor: z.ZodString;
115
+ readyRevision: z.ZodOptional<z.ZodNumber>;
116
+ readyAt: z.ZodOptional<z.ZodNumber>;
117
+ channel: z.ZodLiteral<"instagram">;
118
+ provider: z.ZodLiteral<"meta">;
119
+ instagramAccountId: z.ZodString;
120
+ pageId: z.ZodString;
121
+ }, z.core.$strict>>;
122
+ }, z.core.$strict>;
123
+ export declare const InstagramBindingClientResponseSchema: z.ZodObject<{
124
+ ok: z.ZodLiteral<true>;
125
+ data: z.ZodNullable<z.ZodObject<{
126
+ createdAt: z.ZodNumber;
127
+ id: z.ZodString;
128
+ state: z.ZodEnum<{
129
+ paused: "paused";
130
+ enabled: "enabled";
131
+ disconnected: "disconnected";
132
+ }>;
133
+ revision: z.ZodNumber;
134
+ deploymentId: z.ZodString;
135
+ updatedAt: z.ZodNumber;
136
+ generation: z.ZodNumber;
137
+ apiKeySecret: z.ZodString;
138
+ supportEmail: z.ZodEmail;
139
+ actor: z.ZodString;
140
+ readyRevision: z.ZodOptional<z.ZodNumber>;
141
+ readyAt: z.ZodOptional<z.ZodNumber>;
142
+ channel: z.ZodLiteral<"instagram">;
143
+ provider: z.ZodLiteral<"meta">;
144
+ instagramAccountId: z.ZodString;
145
+ pageId: z.ZodString;
146
+ tenant: z.ZodObject<{
147
+ org: z.ZodString;
148
+ app: z.ZodString;
149
+ env: z.ZodString;
150
+ }, z.core.$strip>;
151
+ capabilities: z.ZodArray<z.ZodObject<{
152
+ kind: z.ZodEnum<{
153
+ tool: "tool";
154
+ knowledge: "knowledge";
155
+ }>;
156
+ name: z.ZodString;
157
+ }, z.core.$strip>>;
158
+ limits: z.ZodObject<{
159
+ perMinute: z.ZodNumber;
160
+ perHour: z.ZodNumber;
161
+ perDay: z.ZodNumber;
162
+ channelPerDay: z.ZodNumber;
163
+ newParticipantsPerDay: z.ZodNumber;
164
+ concurrent: z.ZodNumber;
165
+ pendingPerParticipant: z.ZodNumber;
166
+ pending: z.ZodNumber;
167
+ textCharacters: z.ZodNumber;
168
+ dailyMicroUsd: z.ZodNumber;
169
+ }, z.core.$strip>;
170
+ }, z.core.$strip>>;
171
+ }, z.core.$strip>;
172
+ /** Instagram participants have no phone number: a block names the participant id. */
173
+ export declare const InstagramBlockRequestSchema: z.ZodObject<{
174
+ participantId: z.ZodString;
175
+ until: z.ZodNullable<z.ZodNumber>;
176
+ scope: z.ZodDefault<z.ZodEnum<{
177
+ local: "local";
178
+ provider: "provider";
179
+ }>>;
180
+ }, z.core.$strict>;
181
+ //# sourceMappingURL=instagram.d.ts.map