@tangle-network/agent-integrations 0.67.0 → 0.67.1

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.
@@ -449,7 +449,6 @@ function normalizeLinqWhatsappConversation(input) {
449
449
  if (!Array.isArray(message.parts) || !message.parts.length || message.parts.length > 50) return invalid$4("Invalid message parts");
450
450
  const text = [];
451
451
  const attachments = [];
452
- let historyOnly = false;
453
452
  for (const part of message.parts) {
454
453
  if (!object$2(part)) return invalid$4("Invalid message part");
455
454
  if (part.type === "media") {
@@ -457,7 +456,6 @@ function normalizeLinqWhatsappConversation(input) {
457
456
  if (!media) return invalid$4("Invalid media attachment");
458
457
  attachments.push(media.attachment);
459
458
  if (media.caption) text.push(media.caption);
460
- if (!media.attachment.url) historyOnly = true;
461
459
  } else if (part.type === "text" && typeof part.body === "string" && part.body.length <= 4096) text.push(part.body);
462
460
  else return {
463
461
  ok: false,
@@ -495,7 +493,7 @@ function normalizeLinqWhatsappConversation(input) {
495
493
  occurredAt,
496
494
  transport: "whatsapp",
497
495
  isGroup: false,
498
- historyOnly
496
+ historyOnly: false
499
497
  }
500
498
  };
501
499
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["normalizeConversationEvent","object","invalid","record","phone","invalid","unsupported","record","invalid","object","invalid","normalizeExistingConversationEvent"],"sources":["../../src/conversation-events/core.ts","../../src/conversation-events/linq-whatsapp.ts","../../src/conversation-events/mobile.ts","../../src/conversation-events/resend.ts","../../src/conversation-events/telegram.ts","../../src/conversation-events/reply.ts","../../src/conversation-events/channels.ts","../../src/conversation-events/presence.ts","../../src/conversation-events/index.ts"],"sourcesContent":["import type { TriggerEventCatalog } from '../webhooks/router.js'\n\nexport const MICROSOFT_TEAMS_PROVIDER_ID = 'microsoft-teams' as const\nexport const MICROSOFT_TEAMS_MESSAGE_EVENT = 'teams.message' as const\n\nexport const MICROSOFT_TEAMS_TRIGGER_EVENT_CATALOG = {\n namespace: 'teams.',\n closed: true,\n events: [{ id: MICROSOFT_TEAMS_MESSAGE_EVENT }],\n} as const satisfies TriggerEventCatalog\n\nexport interface InboundEmailAttachment {\n filename?: string\n contentType?: string\n contentBase64?: string\n url?: string\n size?: number\n}\n\n/** Payload emitted by Tangle's verified inbound-email receiver. */\nexport interface InboundEmailPayload {\n messageId?: string\n from: string\n to: string\n subject?: string\n text?: string\n html?: string\n headers?: Record<string, string>\n attachments?: InboundEmailAttachment[]\n receivedAt?: number\n}\n\nexport interface ProviderConversationEvent {\n provider: string\n type: string\n deliveryId?: string\n payload: unknown\n}\n\nexport interface ConversationParticipant {\n id: string | null\n address: string | null\n displayName: string | null\n /** Explicitly marks an unauthenticated email From address. An omitted status makes no claim. */\n verificationStatus?: 'unverified'\n}\n\nexport interface ConversationDestination {\n kind: 'mailbox' | 'channel' | 'chat' | 'user'\n id: string | null\n address: string | null\n displayName: string | null\n}\n\nexport interface ConversationAttachment {\n id: string | null\n name: string | null\n contentType: string | null\n size: number | null\n contentBase64: string | null\n url: string | null\n}\n\n/**\n * Provider-neutral message data for product ingestion.\n *\n * The signed Hub delivery remains the audit record. This projection contains\n * only the stable fields products need for threading, prompts, and files.\n */\nexport interface ConversationEvent {\n version: 1\n provider: 'email' | 'slack' | 'teams'\n eventType: string\n operation: 'created' | 'updated' | 'deleted'\n eventId: string | null\n conversationId: string | null\n parentEventIds: string[]\n sender: ConversationParticipant\n destinations: ConversationDestination[]\n subject: string | null\n text: string | null\n html: string | null\n attachments: ConversationAttachment[]\n occurredAt: number | null\n}\n\nexport type ConversationEventNormalizationErrorCode =\n | 'unsupported_provider'\n | 'unsupported_event'\n | 'invalid_payload'\n\nexport type ConversationEventNormalizationResult =\n | { ok: true; event: ConversationEvent }\n | {\n ok: false\n code: ConversationEventNormalizationErrorCode\n message: string\n }\n\nconst MAX_BODY_LENGTH = 1_000_000\nconst MAX_ATTACHMENTS = 50\nconst MAX_INLINE_ATTACHMENT_LENGTH = 1_100_000\nconst MAX_ATTACHMENT_SIZE = 20 * 1024 * 1024\nconst MAX_HEADERS = 200\n\nexport function normalizeConversationEvent(\n value: unknown,\n): ConversationEventNormalizationResult {\n if (\n !isRecord(value) ||\n typeof value.provider !== 'string' ||\n typeof value.type !== 'string' ||\n (value.deliveryId !== undefined &&\n typeof value.deliveryId !== 'string') ||\n !Object.prototype.hasOwnProperty.call(value, 'payload')\n ) {\n return invalidPayload(\n 'Provider conversation event requires provider, type, and payload',\n )\n }\n const input: ProviderConversationEvent = {\n provider: value.provider,\n type: value.type,\n ...(typeof value.deliveryId === 'string'\n ? { deliveryId: value.deliveryId }\n : {}),\n payload: value.payload,\n }\n if (input.provider === 'email') {\n if (input.type !== 'email.received') {\n return unsupportedEvent(input.provider, input.type)\n }\n return normalizeEmail(input)\n }\n if (input.provider === 'slack') {\n if (input.type !== 'slack.message' && input.type !== 'slack.app_mention') {\n return unsupportedEvent(input.provider, input.type)\n }\n return normalizeSlack(input)\n }\n if (input.provider === MICROSOFT_TEAMS_PROVIDER_ID) {\n if (input.type !== MICROSOFT_TEAMS_MESSAGE_EVENT) {\n return unsupportedEvent(input.provider, input.type)\n }\n return normalizeMicrosoftTeams(input)\n }\n return {\n ok: false,\n code: 'unsupported_provider',\n message: `Conversation events do not support provider ${input.provider}`,\n }\n}\n\nfunction normalizeMicrosoftTeams(\n input: ProviderConversationEvent,\n): ConversationEventNormalizationResult {\n const activity = input.payload\n if (!isRecord(activity) || activity.type !== 'message') {\n return invalidPayload('Teams payload requires a message activity')\n }\n if (\n activity.channelId !== undefined &&\n activity.channelId !== 'msteams'\n ) {\n return invalidPayload('Teams activity came from an unsupported channel')\n }\n const text = optionalString(activity.text, MAX_BODY_LENGTH)\n if (text === undefined) {\n return invalidPayload('Teams message text is invalid')\n }\n const conversation = isRecord(activity.conversation)\n ? activity.conversation\n : null\n const conversationId = normalizeNullableString(conversation?.id, 2_000)\n if (!conversationId) {\n return invalidPayload('Teams message requires a conversation id')\n }\n const channelData = isRecord(activity.channelData)\n ? activity.channelData\n : null\n const tenant = resolveMicrosoftTeamsTenantId(activity)\n if (!tenant.ok) return invalidPayload(tenant.message)\n const tenantId = tenant.tenantId\n const from = isRecord(activity.from) ? activity.from : null\n const channel = isRecord(channelData?.channel)\n ? channelData.channel\n : null\n const team = isRecord(channelData?.team) ? channelData.team : null\n const channelId = normalizeNullableString(channel?.id, 2_000)\n const channelName = normalizeNullableString(channel?.name, 300)\n const teamId = normalizeNullableString(team?.id, 2_000)\n const replyToId = normalizeNullableString(activity.replyToId, 2_000)\n const eventId =\n normalizeNullableString(activity.id, 2_000) ??\n normalizeNullableString(input.deliveryId, 2_000)\n const attachments = normalizeTeamsAttachments(activity.attachments)\n if (!attachments.ok) return attachments\n const timestamp = normalizeTeamsTimestamp(\n activity.timestamp ?? activity.localTimestamp,\n )\n if (timestamp === undefined) {\n return invalidPayload('Teams message timestamp is invalid')\n }\n\n return {\n ok: true,\n event: {\n version: 1,\n provider: 'teams',\n eventType: input.type,\n operation: 'created',\n eventId,\n conversationId: `${tenantId}:${conversationId}`,\n parentEventIds: replyToId ? [replyToId] : [],\n sender: {\n id:\n normalizeNullableString(from?.aadObjectId, 300) ??\n normalizeNullableString(from?.id, 2_000),\n address: null,\n displayName: normalizeNullableString(from?.name, 300),\n },\n destinations: [\n {\n kind: channelId ? 'channel' : 'chat',\n id: channelId ?? conversationId,\n address: null,\n displayName: channelName,\n },\n ...(teamId\n ? [\n {\n kind: 'channel' as const,\n id: teamId,\n address: null,\n displayName: normalizeNullableString(team?.name, 300),\n },\n ]\n : []),\n ],\n subject: null,\n text: text ?? null,\n html: null,\n attachments: attachments.value,\n occurredAt: timestamp ?? null,\n },\n }\n}\n\nexport type MicrosoftTeamsTenantResolution =\n | { ok: true; tenantId: string }\n | { ok: false; message: string }\n\n/**\n * Resolve the authenticated Teams tenant identity shared by the platform\n * receiver and product normalizer. Teams may repeat it in both\n * `channelData.tenant.id` and `conversation.tenantId`; disagreement is\n * rejected so an event can never be attributed to a guessed tenant.\n */\nexport function resolveMicrosoftTeamsTenantId(\n payload: unknown,\n): MicrosoftTeamsTenantResolution {\n if (!isRecord(payload)) {\n return { ok: false, message: 'Teams payload requires an activity object' }\n }\n const conversation = isRecord(payload.conversation)\n ? payload.conversation\n : null\n const channelData = isRecord(payload.channelData)\n ? payload.channelData\n : null\n const channelDataTenant = isRecord(channelData?.tenant)\n ? normalizeNullableString(channelData.tenant.id, 300)\n : null\n const conversationTenant = normalizeNullableString(\n conversation?.tenantId,\n 300,\n )\n if (\n channelDataTenant &&\n conversationTenant &&\n channelDataTenant !== conversationTenant\n ) {\n return {\n ok: false,\n message: 'Teams activity contains conflicting tenant ids',\n }\n }\n const tenantId = channelDataTenant ?? conversationTenant\n return tenantId\n ? { ok: true, tenantId }\n : { ok: false, message: 'Teams message requires a tenant id' }\n}\n\nfunction normalizeEmail(\n input: ProviderConversationEvent,\n): ConversationEventNormalizationResult {\n const payload = input.payload\n if (!isRecord(payload)) return invalidPayload('Email payload must be an object')\n const from = optionalString(payload.from, 320)\n const to = optionalString(payload.to, 320)\n if (\n from === undefined ||\n from === null ||\n to === undefined ||\n to === null ||\n !from.trim() ||\n !to.trim()\n ) {\n return invalidPayload('Email payload requires non-empty string from and to')\n }\n const messageId = optionalString(payload.messageId, 1_000)\n const subject = optionalString(payload.subject, 2_000)\n const text = optionalString(payload.text, MAX_BODY_LENGTH)\n const html = optionalString(payload.html, MAX_BODY_LENGTH)\n if (\n messageId === undefined ||\n subject === undefined ||\n text === undefined ||\n html === undefined\n ) {\n return invalidPayload('Email payload contains an invalid string field')\n }\n const receivedAt = optionalFiniteNumber(payload.receivedAt, 0)\n if (receivedAt === undefined) {\n return invalidPayload('Email receivedAt must be a non-negative number')\n }\n const headers = normalizeHeaders(payload.headers)\n if (!headers.ok) return headers\n const attachments = normalizeEmailAttachments(payload.attachments)\n if (!attachments.ok) return attachments\n\n return {\n ok: true,\n event: {\n version: 1,\n provider: 'email',\n eventType: input.type,\n operation: 'created',\n eventId:\n normalizeMessageId(messageId) ??\n normalizeNullableString(input.deliveryId, 1_000),\n conversationId: null,\n parentEventIds: referencedMessageIds(headers.value),\n sender: {\n id: null,\n address: normalizeNullableString(from, 320),\n displayName: null,\n verificationStatus: 'unverified',\n },\n destinations: [\n {\n kind: 'mailbox',\n id: null,\n address: normalizeMailbox(to),\n displayName: null,\n },\n ],\n subject: normalizeNullableString(subject, 2_000),\n text: text ?? null,\n html: html ?? null,\n attachments: attachments.value,\n occurredAt: receivedAt ?? null,\n },\n }\n}\n\nfunction normalizeSlack(\n input: ProviderConversationEvent,\n): ConversationEventNormalizationResult {\n const wrapper = input.payload\n if (!isRecord(wrapper) || !isRecord(wrapper.event)) {\n return invalidPayload('Slack payload requires an Events API event object')\n }\n const outerEvent = wrapper.event\n const changedMessage =\n outerEvent.subtype === 'message_changed' && isRecord(outerEvent.message)\n ? outerEvent.message\n : null\n const deletedMessage =\n outerEvent.subtype === 'message_deleted' &&\n isRecord(outerEvent.previous_message)\n ? outerEvent.previous_message\n : null\n const message = changedMessage ?? deletedMessage ?? outerEvent\n if (\n message.type !== 'message' &&\n input.type !== 'slack.app_mention'\n ) {\n return invalidPayload('Slack event does not contain a message')\n }\n const text = optionalString(message.text, MAX_BODY_LENGTH)\n if (text === undefined) {\n return invalidPayload('Slack message text is invalid')\n }\n const channel =\n normalizeNullableString(outerEvent.channel, 300) ??\n normalizeNullableString(message.channel, 300)\n if (!channel) return invalidPayload('Slack message requires a channel')\n const timestamp =\n normalizeNullableString(message.ts, 100) ??\n normalizeNullableString(outerEvent.event_ts, 100)\n const threadTimestamp = normalizeNullableString(message.thread_ts, 100)\n const team =\n normalizeNullableString(wrapper.team_id, 300) ??\n normalizeNullableString(wrapper.context_team_id, 300)\n const rootTimestamp = threadTimestamp ?? timestamp\n const files = normalizeSlackFiles(message.files)\n if (!files.ok) return files\n const subtype = normalizeNullableString(outerEvent.subtype, 100)\n\n return {\n ok: true,\n event: {\n version: 1,\n provider: 'slack',\n eventType: input.type,\n operation:\n subtype === 'message_deleted'\n ? 'deleted'\n : subtype === 'message_changed'\n ? 'updated'\n : 'created',\n eventId:\n normalizeNullableString(wrapper.event_id, 300) ??\n normalizeNullableString(message.client_msg_id, 300) ??\n normalizeNullableString(input.deliveryId, 300) ??\n timestamp,\n conversationId: rootTimestamp\n ? [team, channel, rootTimestamp].filter(Boolean).join(':')\n : null,\n parentEventIds:\n threadTimestamp && timestamp && threadTimestamp !== timestamp\n ? [threadTimestamp]\n : [],\n sender: {\n id:\n normalizeNullableString(message.user, 300) ??\n normalizeNullableString(message.bot_id, 300),\n address: null,\n displayName:\n normalizeNullableString(message.username, 300) ??\n (isRecord(message.user_profile)\n ? normalizeNullableString(\n message.user_profile.display_name,\n 300,\n )\n : null),\n },\n destinations: [\n {\n kind: 'channel',\n id: channel,\n address: null,\n displayName: null,\n },\n ],\n subject: null,\n text: text ?? null,\n html: null,\n attachments: files.value,\n occurredAt:\n slackTimestampMs(timestamp) ??\n epochSecondsMs(wrapper.event_time) ??\n null,\n },\n }\n}\n\nfunction normalizeHeaders(\n value: unknown,\n):\n | { ok: true; value: Record<string, string> }\n | {\n ok: false\n code: 'invalid_payload'\n message: string\n } {\n if (value === undefined) return { ok: true, value: {} }\n if (!isRecord(value) || Object.keys(value).length > MAX_HEADERS) {\n return invalidPayload('Email headers must be a bounded string record')\n }\n const headers: Record<string, string> = {}\n for (const [key, entry] of Object.entries(value)) {\n if (\n key.length === 0 ||\n key.length > 200 ||\n typeof entry !== 'string' ||\n entry.length > 4_000\n ) {\n return invalidPayload('Email headers must be a bounded string record')\n }\n headers[key.toLowerCase()] = entry\n }\n return { ok: true, value: headers }\n}\n\nfunction normalizeEmailAttachments(\n value: unknown,\n):\n | { ok: true; value: ConversationAttachment[] }\n | {\n ok: false\n code: 'invalid_payload'\n message: string\n } {\n if (value === undefined) return { ok: true, value: [] }\n if (!Array.isArray(value) || value.length > MAX_ATTACHMENTS) {\n return invalidPayload('Email attachments exceed the supported limit')\n }\n const attachments: ConversationAttachment[] = []\n for (const entry of value) {\n if (!isRecord(entry)) {\n return invalidPayload('Email attachment must be an object')\n }\n const name = optionalString(entry.filename, 240)\n const contentType = optionalString(entry.contentType, 200)\n const contentBase64 = optionalString(\n entry.contentBase64,\n MAX_INLINE_ATTACHMENT_LENGTH,\n )\n const url = optionalString(entry.url, 2_048)\n const size = optionalFiniteNumber(entry.size, 0, MAX_ATTACHMENT_SIZE, true)\n if (\n name === undefined ||\n contentType === undefined ||\n contentBase64 === undefined ||\n url === undefined ||\n size === undefined\n ) {\n return invalidPayload('Email attachment contains an invalid field')\n }\n attachments.push({\n id: null,\n name: name ?? null,\n contentType: contentType ?? null,\n size: size ?? null,\n contentBase64: contentBase64 ?? null,\n url: url ?? null,\n })\n }\n return { ok: true, value: attachments }\n}\n\nfunction normalizeSlackFiles(\n value: unknown,\n):\n | { ok: true; value: ConversationAttachment[] }\n | {\n ok: false\n code: 'invalid_payload'\n message: string\n } {\n if (value === undefined) return { ok: true, value: [] }\n if (!Array.isArray(value) || value.length > MAX_ATTACHMENTS) {\n return invalidPayload('Slack files exceed the supported limit')\n }\n const files: ConversationAttachment[] = []\n for (const entry of value) {\n if (!isRecord(entry)) return invalidPayload('Slack file must be an object')\n const size = optionalFiniteNumber(entry.size, 0, MAX_ATTACHMENT_SIZE, true)\n if (size === undefined) return invalidPayload('Slack file size is invalid')\n files.push({\n id: normalizeNullableString(entry.id, 300),\n name:\n normalizeNullableString(entry.name, 240) ??\n normalizeNullableString(entry.title, 240),\n contentType: normalizeNullableString(entry.mimetype, 200),\n size: size ?? null,\n contentBase64: null,\n // Slack file URLs require the workspace bot token. Products use the\n // `slack.download_file` Hub action with this file id; exposing a private\n // URL here would make downstream runtimes attempt an unauthenticated fetch.\n url: null,\n })\n }\n return { ok: true, value: files }\n}\n\nfunction normalizeTeamsAttachments(\n value: unknown,\n):\n | { ok: true; value: ConversationAttachment[] }\n | {\n ok: false\n code: 'invalid_payload'\n message: string\n } {\n if (value === undefined) return { ok: true, value: [] }\n if (!Array.isArray(value) || value.length > MAX_ATTACHMENTS) {\n return invalidPayload('Teams attachments exceed the supported limit')\n }\n const attachments: ConversationAttachment[] = []\n for (const entry of value) {\n if (!isRecord(entry)) {\n return invalidPayload('Teams attachment must be an object')\n }\n const id = optionalString(entry.id, 300)\n const name = optionalString(entry.name, 240)\n const contentType = optionalString(entry.contentType, 200)\n if (\n id === undefined ||\n name === undefined ||\n contentType === undefined\n ) {\n return invalidPayload('Teams attachment contains an invalid field')\n }\n attachments.push({\n id: normalizeNullableString(id, 300),\n name: normalizeNullableString(name, 240),\n contentType: normalizeNullableString(contentType, 200),\n size: null,\n contentBase64: null,\n // Bot attachment URLs require Microsoft authorization. The receiver\n // keeps that credential inside Hub; products only receive stable metadata.\n url: null,\n })\n }\n return { ok: true, value: attachments }\n}\n\nfunction normalizeTeamsTimestamp(value: unknown): number | null | undefined {\n if (value === undefined || value === null) return null\n if (typeof value !== 'string' || value.length > 100) return undefined\n const timestamp = Date.parse(value)\n return Number.isFinite(timestamp) && timestamp >= 0\n ? timestamp\n : undefined\n}\n\nfunction referencedMessageIds(headers: Record<string, string>): string[] {\n const values = [headers['in-reply-to'], headers.references].filter(\n (value): value is string => Boolean(value?.trim()),\n )\n const ids: string[] = []\n for (const value of values) {\n const bracketed = value.match(/<[^<>]{1,1000}>/g)\n const candidates = bracketed ?? value.split(/\\s+/)\n for (const candidate of candidates) {\n const normalized = normalizeMessageId(candidate)\n if (normalized && !ids.includes(normalized)) ids.push(normalized)\n }\n }\n return ids.slice(0, 50)\n}\n\nfunction normalizeMessageId(value: string | null | undefined): string | null {\n if (!value) return null\n const trimmed = value.trim()\n if (!trimmed) return null\n return trimmed.startsWith('<') && trimmed.endsWith('>')\n ? trimmed.slice(1, -1).trim() || null\n : trimmed\n}\n\nfunction normalizeMailbox(value: string): string {\n return value.trim().toLowerCase()\n}\n\nfunction normalizeNullableString(\n value: unknown,\n maxLength: number,\n): string | null {\n return typeof value === 'string' && value.length <= maxLength\n ? value.trim() || null\n : null\n}\n\n/**\n * Undefined means invalid; null means the optional field was absent.\n */\nfunction optionalString(\n value: unknown,\n maxLength: number,\n): string | null | undefined {\n if (value === undefined) return null\n return typeof value === 'string' && value.length <= maxLength\n ? value\n : undefined\n}\n\n/**\n * Undefined means invalid; null means the optional field was absent.\n */\nfunction optionalFiniteNumber(\n value: unknown,\n minimum: number,\n maximum = Number.MAX_SAFE_INTEGER,\n integer = false,\n): number | null | undefined {\n if (value === undefined) return null\n if (\n typeof value !== 'number' ||\n !Number.isFinite(value) ||\n value < minimum ||\n value > maximum ||\n (integer && !Number.isInteger(value))\n ) {\n return undefined\n }\n return value\n}\n\nfunction slackTimestampMs(value: string | null): number | null {\n if (!value || !/^\\d{1,12}(?:\\.\\d{1,9})?$/.test(value)) return null\n const seconds = Number(value)\n return Number.isFinite(seconds) ? Math.round(seconds * 1_000) : null\n}\n\nfunction epochSecondsMs(value: unknown): number | null {\n return typeof value === 'number' && Number.isFinite(value) && value >= 0\n ? Math.round(value * 1_000)\n : null\n}\n\nfunction unsupportedEvent(\n provider: string,\n type: string,\n): ConversationEventNormalizationResult {\n return {\n ok: false,\n code: 'unsupported_event',\n message: `Conversation events do not support ${provider} event ${type}`,\n }\n}\n\nfunction invalidPayload(\n message: string,\n): {\n ok: false\n code: 'invalid_payload'\n message: string\n} {\n return { ok: false, code: 'invalid_payload', message }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import type { ConversationEventNormalizationResult, ProviderConversationEvent } from './index.js'\nimport { linqWhatsappAttachmentUrl } from '../linq-whatsapp-attachment-url.js'\n\nfunction object(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\nfunction id(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0 && value.length <= 256 && !/[\\u0000-\\u001f\\u007f]/.test(value)\n}\nconst invalid = (message: string): ConversationEventNormalizationResult => ({ ok: false, code: 'invalid_payload', message })\nconst MEDIA_KINDS = new Set(['image', 'video', 'audio', 'document', 'sticker'])\n\nfunction mediaPart(part: Record<string, unknown>) {\n if (typeof part.kind !== 'string' || !MEDIA_KINDS.has(part.kind)) return null\n const url = part.url == null ? null : linqWhatsappAttachmentUrl(part.url)\n if (part.url != null && !url) return null\n if (!id(part.media_id)) return null\n if (part.filename !== undefined && (typeof part.filename !== 'string' || part.filename.length > 240 || /[\\u0000-\\u001f\\u007f]/.test(part.filename))) return null\n if (part.mime_type !== undefined && (typeof part.mime_type !== 'string' || part.mime_type.length > 200 || /[\\u0000-\\u001f\\u007f]/.test(part.mime_type))) return null\n if (part.caption !== undefined && (typeof part.caption !== 'string' || part.caption.length > 1024)) return null\n if (part.byte_size !== undefined && (!Number.isSafeInteger(part.byte_size) || (part.byte_size as number) < 0)) return null\n return {\n attachment: { id: typeof part.media_id === 'string' ? part.media_id : null,\n name: typeof part.filename === 'string' ? part.filename : null,\n contentType: typeof part.mime_type === 'string' ? part.mime_type : null,\n size: typeof part.byte_size === 'number' ? part.byte_size : null,\n contentBase64: null, url },\n caption: typeof part.caption === 'string' && part.caption.length <= 1024 ? part.caption : null,\n }\n}\n\n/** Fresh webhook snapshots only. Historical range notifications need journal hydration.\n * A chat represents one customer, but the message does not contain their address.\n * Keep that customer opaque; never mislabel message.from (our number) as the sender. */\nexport function normalizeLinqWhatsappConversation(input: ProviderConversationEvent): ConversationEventNormalizationResult {\n const value = input.payload\n if (!object(value) || input.type !== `linq-whatsapp.${value.type}`) return invalid('Event type does not match the provider envelope')\n if (value.type !== 'message.received') return { ok: false, code: 'unsupported_event', message: 'Not an incoming message' }\n if (!object(value.data) || !object(value.data.message)) return invalid('Read the chat journal to hydrate this historical event')\n const message = value.data.message\n if (!id(value.id) || !id(message.id) || !id(message.chat_id) || !id(message.from) || message.direction !== 'inbound') {\n return invalid('Incoming message requires a stable identity, conversation and owned destination')\n }\n if (value.data.chat_id !== undefined && value.data.chat_id !== message.chat_id) return invalid('Chat identity mismatch')\n if (!Array.isArray(message.parts) || !message.parts.length || message.parts.length > 50) return invalid('Invalid message parts')\n const text: string[] = []\n const attachments: NonNullable<ReturnType<typeof mediaPart>>['attachment'][] = []\n let historyOnly = false\n for (const part of message.parts) {\n if (!object(part)) return invalid('Invalid message part')\n if (part.type === 'media') {\n const media = mediaPart(part)\n if (!media) return invalid('Invalid media attachment')\n attachments.push(media.attachment)\n if (media.caption) text.push(media.caption)\n if (!media.attachment.url) historyOnly = true\n } else if (part.type === 'text' && typeof part.body === 'string' && part.body.length <= 4096) {\n text.push(part.body)\n } else {\n return { ok: false, code: 'unsupported_event', message: 'This message requires non-text handling' }\n }\n }\n const occurredAt = typeof message.created_at === 'string' ? Date.parse(message.created_at) : NaN\n if (!Number.isSafeInteger(occurredAt) || occurredAt < 0) return invalid('Invalid message timestamp')\n return { ok: true, event: {\n version: 1, provider: 'linq-whatsapp', eventType: input.type, operation: 'created', eventId: message.id,\n conversationId: message.chat_id, parentEventIds: [],\n sender: { id: `customer:${message.chat_id}`, address: null, displayName: null },\n destinations: [{ kind: 'chat', id: message.from, address: message.from, displayName: null }],\n subject: null, text: text.join('\\n'), html: null, attachments, occurredAt, transport: 'whatsapp', isGroup: false, historyOnly,\n } }\n}\n","import type { ConversationAttachment, ConversationEvent, ConversationEventNormalizationResult, ProviderConversationEvent } from './index.js'\n\ntype RecordValue = Record<string, unknown>\nfunction record(value: unknown): value is RecordValue { return value !== null && typeof value === 'object' && !Array.isArray(value) }\nfunction string(value: unknown, max = 2000): string | null {\n return typeof value === 'string' && value.length > 0 && value.length <= max && !/[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]/.test(value) ? value : null\n}\nfunction timestamp(value: unknown): number | null {\n const n = typeof value === 'number' ? value * 1000 : typeof value === 'string' ? Date.parse(value) : NaN\n return Number.isSafeInteger(n) && n >= 0 ? n : null\n}\nfunction phone(value: unknown): value is string {\n return typeof value === 'string' && /^\\+[1-9]\\d{6,14}$/.test(value)\n}\nconst invalid = (message: string): ConversationEventNormalizationResult => ({ ok: false, code: 'invalid_payload', message })\nconst unsupported = (): ConversationEventNormalizationResult => ({ ok: false, code: 'unsupported_event', message: 'Not a supported incoming conversation message' })\n\nfunction attachment(value: unknown): ConversationAttachment | null {\n if (!record(value)) return null\n const url = string(value.url ?? value.value, 8192)\n if (!url) return null\n try { const u = new URL(url); if (u.protocol !== 'https:' || u.username || u.password) return null } catch { return null }\n return { id: string(value.id), name: string(value.filename ?? value.name, 255),\n contentType: string(value.mime_type ?? value.mime ?? value.content_type, 200), size: null, contentBase64: null, url }\n}\n\nfunction finish(input: ProviderConversationEvent, data: {\n id: unknown; conversation: unknown; sender: unknown; destination: unknown;\n destinationAddress?: unknown; text: unknown; time: unknown; media?: unknown; parent?: unknown;\n subject?: unknown; destinationKind?: 'chat' | 'mailbox'; isGroup?: boolean; historyOnly?: boolean;\n senderVerificationStatus?: 'unverified';\n transport?: ConversationEvent['transport'];\n}): ConversationEventNormalizationResult {\n const id = string(data.id), conversation = string(data.conversation), sender = string(data.sender), destination = string(data.destination)\n if (!id || !conversation || !sender || !destination) return invalid('Message identity, conversation, sender and destination are required')\n if (data.text !== null && data.text !== undefined && (typeof data.text !== 'string' || data.text.length > 1_000_000)) return invalid('Invalid message text')\n if (data.media !== undefined && data.media !== null && (!Array.isArray(data.media) || data.media.length > 50)) return invalid('Invalid attachment list')\n const media = (data.media ?? []) as unknown[]\n const attachments = media.map(attachment)\n if (attachments.some((a) => !a)) return invalid('Attachments require HTTPS references; bytes must be resolved through the authorized file boundary')\n const time = timestamp(data.time)\n if (time === null) return invalid('A valid provider timestamp is required')\n const provider = input.provider as 'inkbox' | 'linq' | 'contiguity' | 'sendblue' | 'twilio-sms'\n const event: ConversationEvent = {\n version: 1, provider, eventType: input.type, operation: 'created', eventId: id,\n conversationId: conversation, parentEventIds: string(data.parent) ? [String(data.parent)] : [],\n sender: { id: sender, address: sender, displayName: null,\n ...(data.senderVerificationStatus ? { verificationStatus: data.senderVerificationStatus } : {}) },\n destinations: [{ kind: data.destinationKind ?? 'chat', id: destination, address: string(data.destinationAddress), displayName: null }],\n subject: string(data.subject, 998), text: (data.text as string | null | undefined) ?? null, html: null,\n attachments: attachments as ConversationAttachment[], occurredAt: time,\n isGroup: data.isGroup === true, historyOnly: data.historyOnly === true,\n ...(data.transport ? { transport: data.transport } : {}),\n }\n return { ok: true, event }\n}\n\n/** Called after the host verifies signatures and resolves the owning connection. */\nexport function normalizeMobileConversation(input: ProviderConversationEvent): ConversationEventNormalizationResult {\n const p = input.payload\n if (!record(p)) return invalid('Provider payload requires an object')\n if (input.provider === 'sendblue') {\n if (input.type !== 'sendblue.message.received') return unsupported()\n if (p.is_outbound !== false || String(p.status).toUpperCase() !== 'RECEIVED' || !phone(p.from_number)\n || !phone(p.sendblue_number) || (p.to_number !== undefined && p.to_number !== p.sendblue_number)\n || (p.number !== undefined && p.number !== p.from_number)) {\n return invalid('Sendblue requires an inbound received message with exact line and contact routing')\n }\n const service = typeof p.service === 'string' ? p.service.toLowerCase() : null\n const transport = service === 'imessage' ? 'imessage'\n : service === 'sms' ? 'sms' : service === 'rcs' ? 'rcs' : null\n const messageType = typeof p.message_type === 'string' ? p.message_type.toLowerCase() : null\n if (!transport || (messageType !== 'message' && messageType !== 'group')) return unsupported()\n const group = messageType === 'group' || Boolean(p.group_id)\n if (group && !string(p.group_id, 256)) return invalid('Group messages require a group id')\n if (p.media_url !== undefined && p.media_url !== null && typeof p.media_url !== 'string') return invalid('Invalid Sendblue media URL')\n return finish(input, { id: p.message_handle,\n conversation: group ? p.group_id : JSON.stringify(['sendblue', p.sendblue_number, p.from_number]),\n sender: p.from_number, destination: p.sendblue_number, destinationAddress: p.sendblue_number,\n text: p.content, time: p.date_sent, media: p.media_url ? [{ url: p.media_url }] : [],\n parent: record(p.reply_to) ? p.reply_to.message_handle : undefined,\n isGroup: group, historyOnly: p.opted_out === true, transport })\n }\n if (input.provider === 'twilio-sms') {\n if (input.type !== 'twilio-sms.message.received') return unsupported()\n if (!/^AC[a-f\\d]{32}$/i.test(String(p.AccountSid ?? '')) || !phone(p.From) || !phone(p.To)\n || !/^(SM|MM)[a-f\\d]{32}$/i.test(String(p.MessageSid ?? ''))) {\n return invalid('Twilio message requires its signed account, SID, and phone routing')\n }\n const count = Number(p.NumMedia ?? 0)\n if (!Number.isSafeInteger(count) || count < 0 || count > 10) return invalid('Invalid Twilio media count')\n const media: RecordValue[] = []\n for (let index = 0; index < count; index++) {\n const rawUrl = string(p[`MediaUrl${index}`], 8192)\n if (!rawUrl) return invalid('Missing Twilio media URL')\n let url: URL\n try { url = new URL(rawUrl) } catch { return invalid('Invalid Twilio media URL') }\n const parts = /^\\/2010-04-01\\/Accounts\\/(AC[a-f\\d]{32})\\/Messages\\/((?:SM|MM)[a-f\\d]{32})\\/Media\\/(ME[a-f\\d]{32})$/i.exec(url.pathname)\n if (url.origin !== 'https://api.twilio.com' || url.username || url.password || url.search || !parts\n || parts[1]!.toLowerCase() !== String(p.AccountSid).toLowerCase()\n || parts[2]!.toLowerCase() !== String(p.MessageSid).toLowerCase()) {\n return invalid('Twilio media URL must belong to the signed message and account')\n }\n media.push({ id: parts[3], url: rawUrl, mime_type: p[`MediaContentType${index}`] })\n }\n return finish(input, { id: p.MessageSid, conversation: JSON.stringify(['twilio-sms', p.To, p.From]),\n sender: p.From, destination: p.To, destinationAddress: p.To, text: p.Body,\n time: p.__receivedAt, media, transport: 'sms' })\n }\n if (!record(p.data)) return invalid('Provider payload requires a data object')\n const data = p.data\n if (input.provider === 'inkbox') {\n if (input.type !== `inkbox.${p.event_type}`) return invalid('Event type does not match the provider envelope')\n if (p.event_type === 'imessage.received') {\n const m = data.message\n if (!record(m) || m.direction !== 'inbound') return invalid('Expected an inbound iMessage')\n return finish(input, { id: m.id, conversation: m.conversation_id, sender: m.sender_number ?? m.remote_number,\n destination: m.conversation_id, text: m.content, time: m.created_at ?? p.timestamp, media: m.media, isGroup: m.is_group === true, transport: 'imessage' })\n }\n if (p.event_type === 'text.received') {\n const m = data.text_message\n if (!record(m) || m.direction !== 'inbound') return invalid('Expected an inbound phone text')\n return finish(input, { id: m.id, conversation: m.conversation_id, sender: m.sender_phone_number ?? m.remote_phone_number,\n destination: m.local_phone_number, destinationAddress: m.local_phone_number, text: m.text, time: m.created_at ?? p.timestamp,\n media: m.media, isGroup: m.is_group === true, transport: 'sms' })\n }\n if (p.event_type === 'message.received') {\n const m = data.message\n if (!record(m) || m.direction !== 'inbound') return invalid('Expected inbound mail')\n return finish(input, { id: m.id, conversation: m.thread_id ?? m.id, sender: m.from_address,\n destination: m.email_address, destinationAddress: m.email_address, destinationKind: 'mailbox', text: m.body,\n time: m.created_at ?? p.timestamp, subject: m.subject,\n senderVerificationStatus: 'unverified',\n historyOnly: m.body_state !== 'complete' || m.body_truncated === true, transport: 'email' })\n }\n return unsupported()\n }\n if (input.provider === 'linq') {\n if (input.type !== `linq.${p.event_type}`) return invalid('Event type does not match the provider envelope')\n if (p.event_type !== 'message.received') return unsupported()\n if (p.webhook_version !== '2026-02-03' || data.direction !== 'inbound' || !record(data.chat)\n || !record(data.sender_handle) || !record(data.chat.owner_handle) || data.chat.owner_handle.is_me !== true || data.sender_handle.is_me === true) {\n return invalid('Linq requires v2026-02-03 incoming payloads with explicit sender and owner handles')\n }\n const transport = data.service === 'iMessage' ? 'imessage'\n : data.service === 'SMS' ? 'sms' : data.service === 'RCS' ? 'rcs' : null\n if (!transport) return invalid('Linq incoming message requires its actual service')\n if (!Array.isArray(data.parts) || data.parts.length > 50) return invalid('Invalid Linq parts')\n const texts: string[] = [], media: RecordValue[] = []\n for (const part of data.parts) {\n if (!record(part)) return invalid('Invalid Linq part')\n if (part.type === 'text' || part.type === 'link') {\n if (typeof part.value !== 'string') return invalid('Invalid Linq text')\n texts.push(part.value)\n } else if (part.type === 'media') media.push(part)\n else return unsupported()\n }\n return finish(input, { id: data.id, conversation: data.chat.id, sender: data.sender_handle.handle,\n destination: data.chat.id, destinationAddress: data.chat.owner_handle.handle,\n text: texts.join('\\n'), time: data.sent_at ?? p.created_at, media,\n parent: record(data.reply_to) ? data.reply_to.message_id : undefined,\n isGroup: data.chat.is_group === true, historyOnly: data.reconciled_at != null || data.zero_retention === true,\n transport })\n }\n if (input.provider === 'contiguity') {\n if (input.type !== `contiguity.${p.type}`) return invalid('Event type does not match the provider envelope')\n if (!['imessage.incoming', 'text.incoming.sms', 'text.incoming.mms'].includes(String(p.type))) return unsupported()\n if (!string(data.to, 320) || !string(data.from, 320)) return invalid('Missing Contiguity phone routing')\n // No native chat id in v2: use a collision-free tuple, not a bare sender across channels.\n return finish(input, { id: p.id, conversation: JSON.stringify([p.type === 'imessage.incoming' ? 'imessage' : 'text', data.to, data.from]),\n sender: data.from, destination: data.to, destinationAddress: data.to, text: data.body,\n time: data.timestamp ?? p.timestamp, media: data.attachments,\n transport: p.type === 'imessage.incoming' ? 'imessage' : 'sms' })\n }\n return { ok: false, code: 'unsupported_provider', message: 'Unsupported mobile provider' }\n}\n","import type { ConversationEvent, ConversationEventNormalizationResult, ProviderConversationEvent } from './index.js'\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\nfunction address(value: unknown): string | null {\n if (typeof value !== 'string' || value.length > 320) return null\n const match = /^(?:[^<>]*<)?([^<>\\s]+@[^<>\\s]+)(?:>)?$/.exec(value.trim())\n return match?.[1]?.toLowerCase() ?? null\n}\nconst invalid = (message: string): ConversationEventNormalizationResult => ({ ok: false, code: 'invalid_payload', message })\n\n/** The host adds the provider-read email after verifying the notification. */\nexport function normalizeResendConversation(input: ProviderConversationEvent): ConversationEventNormalizationResult {\n const payload = input.payload\n if (input.type !== 'resend.email.received' || !record(payload) || payload.type !== 'email.received'\n || !record(payload.data) || !record(payload.received)) return invalid('Resend requires a hydrated received-email notification')\n const data = payload.data, received = payload.received\n if (typeof data.email_id !== 'string' || received.id !== data.email_id\n || !Array.isArray(received.to) || received.to.length < 1 || received.to.length > 50\n || (received.cc !== undefined && (!Array.isArray(received.cc) || received.cc.length > 50))\n || !address(received.from)\n || (received.text != null && typeof received.text !== 'string')\n || typeof received.created_at !== 'string' || !Number.isFinite(Date.parse(received.created_at))) {\n return invalid('Resend email identity, sender, recipient, body or time is invalid')\n }\n const recipients = [...received.to, ...((received.cc ?? []) as unknown[])]\n .map(address)\n if (recipients.some(item => !item)) return invalid('Resend recipient address is invalid')\n const attachments = Array.isArray(received.attachments) ? received.attachments : []\n if (attachments.length > 50 || attachments.some(item => !record(item) || typeof item.id !== 'string')) {\n return invalid('Resend attachments require provider ids')\n }\n const sender = address(received.from)!\n const event: ConversationEvent = {\n version: 1, provider: 'resend', eventType: input.type, operation: 'created',\n eventId: data.email_id, conversationId: data.email_id, parentEventIds: [],\n sender: { id: sender, address: sender, displayName: null, verificationStatus: 'unverified' },\n destinations: recipients.map(destination => ({ kind: 'mailbox', id: destination, address: destination, displayName: null })),\n subject: typeof received.subject === 'string' ? received.subject.slice(0, 998) : null,\n text: typeof received.text === 'string' ? received.text : null,\n html: null,\n attachments: attachments.map(item => {\n const value = item as Record<string, unknown>\n return { id: value.id as string, name: typeof value.filename === 'string' ? value.filename : null,\n contentType: typeof value.content_type === 'string' ? value.content_type : null,\n size: null, contentBase64: null, url: null }\n }),\n occurredAt: Date.parse(received.created_at), transport: 'email',\n historyOnly: typeof received.text !== 'string' || recipients.length !== 1,\n }\n return { ok: true, event }\n}\n","import type { ConversationAttachment, ConversationEventNormalizationResult, ProviderConversationEvent } from './index.js'\n\nfunction object(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\nfunction integer(value: unknown, positive = true): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value) && (positive ? value > 0 : value !== 0)\n}\nconst invalid = (message: string): ConversationEventNormalizationResult => ({ ok: false, code: 'invalid_payload', message })\n\n/** Parse only new human messages. The verified webhook proves origin; the host\n * must still check live bot membership and the sender's authority before acting.\n * Addresses include chat, forum topic and sender to prevent session reuse across\n * groups, topics or people. Anonymous/channel senders cannot acquire user rights. */\nexport function normalizeTelegramConversation(input: ProviderConversationEvent): ConversationEventNormalizationResult {\n if (input.type !== 'telegram.message') return { ok: false, code: 'unsupported_event', message: 'Not a new Telegram message' }\n const envelope = input.payload\n if (!object(envelope) || !Number.isSafeInteger(envelope.update_id)\n || (envelope.update_id as number) < 0 || !object(envelope.message)) {\n return invalid('Telegram requires an update id and message')\n }\n const message = envelope.message\n const chat = message.chat\n const from = message.from\n if (!object(chat) || !object(from) || !integer(chat.id, false) || !integer(from.id)\n || from.is_bot !== false || message.sender_chat !== undefined || !integer(message.message_id)\n || !integer(message.date) || !Number.isSafeInteger(message.date * 1000)\n || !['private', 'group', 'supergroup'].includes(String(chat.type))\n || (chat.type === 'private' ? chat.id !== from.id : chat.id >= 0)) {\n return invalid('Telegram requires a human sender and supported chat identity')\n }\n const topic = message.message_thread_id\n if (topic !== undefined && (!integer(topic) || chat.type !== 'supergroup')) return invalid('Invalid Telegram topic')\n const text = message.text ?? message.caption ?? ''\n if (typeof text !== 'string' || text.length > 4096 || text.includes('\\0')) return invalid('Invalid Telegram message text')\n const media: unknown[] = []\n if (message.photo !== undefined) {\n if (!Array.isArray(message.photo) || message.photo.length === 0 || message.photo.length > 20) return invalid('Invalid Telegram photo')\n media.push(message.photo[message.photo.length - 1])\n }\n for (const kind of ['document', 'audio', 'voice', 'video', 'video_note', 'animation', 'sticker']) {\n if (message[kind] !== undefined) media.push(message[kind])\n }\n const attachments: ConversationAttachment[] = []\n for (const file of media) {\n if (!object(file) || typeof file.file_id !== 'string' || !/^[A-Za-z0-9_-]{1,512}$/.test(file.file_id)\n || (file.file_size !== undefined && (!Number.isSafeInteger(file.file_size) || (file.file_size as number) < 0))) {\n return invalid('Invalid Telegram attachment')\n }\n attachments.push({ id: file.file_id, name: typeof file.file_name === 'string' ? file.file_name.slice(0, 255) : null,\n contentType: typeof file.mime_type === 'string' ? file.mime_type.slice(0, 200) : null,\n size: typeof file.file_size === 'number' ? file.file_size : null, contentBase64: null, url: null })\n }\n if (!text.trim() && attachments.length === 0) return { ok: false, code: 'unsupported_event', message: 'No message content' }\n return { ok: true, event: {\n version: 1, provider: 'telegram', eventType: input.type, operation: 'created',\n eventId: `${chat.id}:${message.message_id}`, conversationId: String(chat.id),\n parentEventIds: object(message.reply_to_message) && integer(message.reply_to_message.message_id)\n ? [`${chat.id}:${message.reply_to_message.message_id}`] : [],\n sender: { id: String(from.id), address: `telegram:${chat.id}:${topic ?? 0}:${from.id}`,\n displayName: typeof from.first_name === 'string' ? from.first_name.slice(0, 100) : null },\n destinations: [{ kind: 'chat', id: String(chat.id), address: `telegram:${chat.id}`, displayName: null }],\n subject: null, text, html: null, attachments, occurredAt: message.date * 1000,\n transport: 'telegram', isGroup: chat.type !== 'private', historyOnly: false,\n } }\n}\n","import { normalizeConversationEvent, type ConversationEventNormalizationResult, type ProviderConversationEvent } from './index.js'\n\nexport interface ConversationReply {\n /** Qualified existing Hub action. The host supplies the bound connection. */\n action: string\n input: Record<string, unknown>\n /** Pass as the invocation's idempotency key, unchanged on every retry of this reply. */\n idempotencyKey: string\n}\n\nexport interface ConversationMediaReplyDescriptor {\n /** HTTPS location of one authorized media asset, using a DNS host rather than a direct IP. */\n url: string\n}\n\ntype Failure = Exclude<ConversationEventNormalizationResult, { ok: true }>\nfunction object(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : {}\n}\nconst fail = (message: string): Failure => ({ ok: false, code: 'invalid_payload', message })\nconst validOperationId = (value: unknown): value is string =>\n typeof value === 'string' && value.length > 0 && value.length <= 255 && /^[\\x21-\\x7e]+$/.test(value)\nfunction validMediaHost(host: string): boolean {\n if (host.length > 253 || host.endsWith('.local') || host.endsWith('.localhost')\n || host.startsWith('[') || /^\\d+(?:\\.\\d+){3}$/.test(host)) return false\n const labels = host.split('.')\n return labels.length >= 2 && labels.every((label) => label.length <= 63\n && /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(label))\n}\nfunction validMediaUrl(value: unknown): value is string {\n if (typeof value !== 'string' || !value.startsWith('https://') || value.length > 2048\n || /[\\u0000-\\u0020\\u007f]/.test(value)) return false\n try {\n const url = new URL(value)\n return validMediaHost(url.hostname.toLowerCase()) && !url.username && !url.password && !url.hash\n } catch {\n return false\n }\n}\n// Optional threading forwards only dot-atom IDs with DNS-style domains; other valid legacy forms are omitted.\nconst messageIdDotAtom = /^[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+)*$/\nconst messageIdDomainLabel = /^[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?$/\nfunction rfcMessageId(value: unknown): string | null {\n if (typeof value !== 'string' || value.length > 256 || !value.startsWith('<') || !value.endsWith('>')) return null\n const parts = value.slice(1, -1).split('@')\n if (parts.length !== 2 || !messageIdDotAtom.test(parts[0]!)) return null\n const labels = parts[1]!.split('.')\n return labels.every((label) => label.length <= 63 && messageIdDomainLabel.test(label)) ? value : null\n}\n\n/**\n * Derive a plain-text reply from a previously authenticated, stored event.\n * No model-selected recipient, sender, fallback channel or credential.\n * This is routing, not permission: recheck the bound connection and current\n * grant, persist the outbox key/body, then invoke through the existing Hub SDK.\n */\nexport function buildMessagingReply(\n input: ProviderConversationEvent,\n text: string,\n operationId: string,\n): { ok: true; reply: ConversationReply } | Failure {\n const normalized = normalizeConversationEvent(input)\n if (!normalized.ok) return normalized\n const event = normalized.event\n if (typeof text !== 'string' || !text.trim() || text.length > 10000 || text.includes('\\0')) return fail('Reply text is empty or exceeds its limit')\n if (!validOperationId(operationId)) return fail('A stable operation id is required')\n if (event.historyOnly || (event.isGroup && event.provider !== 'telegram')) return fail('This event requires review or complete input before a reply')\n if (event.provider === 'telegram') {\n if (text.length > 4096) return fail('Telegram text is limited to 4096 characters')\n const message = object(object(input.payload).message)\n return { ok: true, reply: { idempotencyKey: operationId, action: 'telegram.sendMessage', input: {\n chat_id: event.conversationId,\n text,\n reply_parameters: { message_id: message.message_id, allow_sending_without_reply: true },\n ...(message.message_thread_id === undefined ? {} : { message_thread_id: message.message_thread_id }),\n } } }\n }\n const data = object(object(input.payload).data)\n if (event.provider === 'inkbox') {\n if (event.eventType === 'inkbox.imessage.received') {\n return { ok: true, reply: { idempotencyKey: operationId, action: 'inkbox.imessage.reply', input: { conversation_id: event.conversationId, text } } }\n }\n if (event.eventType === 'inkbox.text.received') {\n const message = object(data.text_message)\n if (typeof message.phone_number_id !== 'string' || !message.phone_number_id || text.length > 1600) return fail('SMS requires its owned phone id and at most 1600 characters')\n return { ok: true, reply: { idempotencyKey: operationId, action: 'inkbox.sms.reply', input: { phone_number_id: message.phone_number_id, conversation_id: event.conversationId, text } } }\n }\n if (event.eventType === 'inkbox.message.received') {\n const message = object(data.message)\n if (!event.sender.address || typeof message.email_address !== 'string') return fail('Mail reply requires an explicit sender and mailbox')\n const subject = event.subject ?? ''\n const messageId = rfcMessageId(message.message_id)\n return { ok: true, reply: { idempotencyKey: operationId, action: 'inkbox.email.send', input: {\n email_address: message.email_address, to: [event.sender.address],\n subject: /^re:/i.test(subject) ? subject : `Re: ${subject}`.slice(0, 998), text,\n ...(messageId ? { in_reply_to_message_id: messageId } : {}),\n } } }\n }\n }\n if (event.provider === 'linq-whatsapp') {\n if (text.length > 4096) return fail('WhatsApp text is limited to 4096 characters')\n return { ok: true, reply: { idempotencyKey: operationId, action: 'linq-whatsapp.messages.reply', input: { chat_id: event.conversationId, text } } }\n }\n if (event.provider === 'linq') {\n return { ok: true, reply: { idempotencyKey: operationId, action: 'linq.messages.reply', input: { chat_id: event.conversationId, text, message_key: operationId } } }\n }\n if (event.provider === 'resend') {\n const received = object(object(input.payload).received)\n if (!event.sender.address || !event.destinations[0]?.address) {\n return fail('Resend reply requires the authenticated mailbox and sender')\n }\n const subject = event.subject ?? 'Message'\n if (/[\\u0000-\\u001f\\u007f]/.test(subject)) return fail('Email subject contains unsafe control characters')\n const parent = rfcMessageId(received.message_id)\n if (!parent) return fail('Resend reply requires a valid parent Message-ID')\n return { ok: true, reply: { idempotencyKey: operationId, action: 'resend.emails.reply', input: {\n from: event.destinations[0].address, to: [event.sender.address],\n subject: /^re:/i.test(subject) ? subject : `Re: ${subject}`.slice(0, 998), text,\n message_key: operationId, in_reply_to: parent,\n } } }\n }\n if (event.provider === 'contiguity') {\n return { ok: true, reply: { idempotencyKey: operationId, action: event.eventType === 'contiguity.imessage.incoming' ? 'contiguity.messages.send_imessage' : 'contiguity.sms.send',\n input: { to: event.sender.address, from: event.destinations[0]?.address, message: text } } }\n }\n if (event.provider === 'sendblue') {\n if (!event.sender.address || !event.destinations[0]?.address) return fail('Sendblue reply requires the contact and owned line')\n return { ok: true, reply: { idempotencyKey: operationId, action: 'sendblue.messages.send',\n input: { from_number: event.destinations[0].address, number: event.sender.address, content: text } } }\n }\n if (event.provider === 'twilio-sms') {\n if (text.length > 1600 || !event.sender.address || !event.destinations[0]?.address) {\n return fail('Twilio SMS reply requires two phone numbers and at most 1600 characters')\n }\n return { ok: true, reply: { idempotencyKey: operationId, action: 'twilio-sms.send_sms',\n input: { from: event.destinations[0].address, to: event.sender.address, body: text } } }\n }\n return { ok: false, code: 'unsupported_provider', message: 'Use the existing channel-specific reply tool for this provider' }\n}\n\n/**\n * Plan one Linq media reply from a previously authenticated, stored inbound event.\n * The caller must authorize the media asset, bind the existing connection and grant,\n * and retain the same outbox key and body before every Hub invocation or retry.\n */\nexport function buildMessagingMediaReply(\n input: ProviderConversationEvent,\n media: ConversationMediaReplyDescriptor,\n operationId: string,\n): { ok: true; reply: ConversationReply } | Failure {\n const normalized = normalizeConversationEvent(input)\n if (!normalized.ok) return normalized\n const event = normalized.event\n if (event.provider !== 'linq') {\n return { ok: false, code: 'unsupported_provider', message: 'Media replies require a Linq inbound event' }\n }\n if (event.eventType !== 'linq.message.received' || event.historyOnly || event.isGroup\n || !event.conversationId || event.conversationId.length > 256) {\n return fail('Media reply requires a current one-to-one Linq conversation')\n }\n if (!validOperationId(operationId)) return fail('A stable operation id is required')\n const descriptor = object(media)\n const url = descriptor.url\n if (Object.keys(descriptor).length !== 1 || !validMediaUrl(url)) {\n return fail('Media reply requires one HTTPS URL with a DNS host and no credentials or fragment')\n }\n return { ok: true, reply: {\n idempotencyKey: operationId,\n action: 'linq.messages.media.reply',\n input: { chat_id: event.conversationId, url, message_key: operationId },\n } }\n}\n","/** Protocol metadata, not a claim that a deployment or account is configured. */\nexport interface ConversationChannel {\n providerId: string\n eventType: string\n label: string\n transport: 'email' | 'imessage' | 'sms' | 'rcs' | 'whatsapp' | 'telegram'\n sourceKind: 'channel' | 'connection'\n replies: boolean\n inventoryAction?: string\n replyAction?: string\n reactionAction?: string\n typingAction?: string\n readReceiptAction?: string\n numberProvisioning?: 'provider-assigned'\n}\n\nconst channels: readonly ConversationChannel[] = [\n { providerId: 'telegram', eventType: 'telegram.message', label: 'Telegram', transport: 'telegram', sourceKind: 'connection', replies: true, replyAction: 'telegram.sendMessage' },\n { providerId: 'email', eventType: 'email.received', label: 'Tangle email', transport: 'email', sourceKind: 'channel', replies: false },\n { providerId: 'inkbox', eventType: 'inkbox.imessage.received', label: 'iMessage', transport: 'imessage', sourceKind: 'connection', replies: true, replyAction: 'inkbox.imessage.reply',\n reactionAction: 'inkbox.imessage.react', typingAction: 'inkbox.imessage.typing', readReceiptAction: 'inkbox.imessage.read_receipt' },\n { providerId: 'inkbox', eventType: 'inkbox.text.received', label: 'SMS', transport: 'sms', sourceKind: 'connection', replies: true, replyAction: 'inkbox.sms.reply' },\n { providerId: 'inkbox', eventType: 'inkbox.message.received', label: 'Email', transport: 'email', sourceKind: 'connection', replies: true, replyAction: 'inkbox.email.send' },\n { providerId: 'linq', eventType: 'linq.message.received', label: 'iMessage', transport: 'imessage', sourceKind: 'connection', replies: true, inventoryAction: 'linq.numbers.list', replyAction: 'linq.messages.reply',\n reactionAction: 'linq.messages.react', typingAction: 'linq.chats.typing', readReceiptAction: 'linq.chats.read_receipt', numberProvisioning: 'provider-assigned' },\n { providerId: 'linq', eventType: 'linq.message.received', label: 'SMS', transport: 'sms', sourceKind: 'connection', replies: true, inventoryAction: 'linq.numbers.list', replyAction: 'linq.messages.reply', numberProvisioning: 'provider-assigned' },\n { providerId: 'linq', eventType: 'linq.message.received', label: 'RCS', transport: 'rcs', sourceKind: 'connection', replies: true, inventoryAction: 'linq.numbers.list', replyAction: 'linq.messages.reply', numberProvisioning: 'provider-assigned' },\n { providerId: 'contiguity', eventType: 'contiguity.imessage.incoming', label: 'iMessage', transport: 'imessage', sourceKind: 'connection', replies: true, replyAction: 'contiguity.messages.send_imessage',\n typingAction: 'contiguity.imessage.typing', readReceiptAction: 'contiguity.imessage.read_receipt' },\n { providerId: 'contiguity', eventType: 'contiguity.text.incoming.sms', label: 'SMS', transport: 'sms', sourceKind: 'connection', replies: true, replyAction: 'contiguity.sms.send' },\n { providerId: 'linq-whatsapp', eventType: 'linq-whatsapp.message.received', label: 'WhatsApp', transport: 'whatsapp', sourceKind: 'connection', replies: true, inventoryAction: 'linq-whatsapp.numbers.list', replyAction: 'linq-whatsapp.messages.reply',\n reactionAction: 'linq-whatsapp.messages.react', readReceiptAction: 'linq-whatsapp.chats.read_receipt' },\n { providerId: 'resend', eventType: 'resend.email.received', label: 'Email', transport: 'email', sourceKind: 'connection', replies: true, replyAction: 'resend.emails.reply' },\n { providerId: 'sendblue', eventType: 'sendblue.message.received', label: 'iMessage', transport: 'imessage', sourceKind: 'connection', replies: true, inventoryAction: 'sendblue.lines.state', replyAction: 'sendblue.messages.send',\n reactionAction: 'sendblue.messages.react', typingAction: 'sendblue.typing.send', readReceiptAction: 'sendblue.read_receipts.send' },\n { providerId: 'sendblue', eventType: 'sendblue.message.received', label: 'SMS', transport: 'sms', sourceKind: 'connection', replies: true, inventoryAction: 'sendblue.lines.state', replyAction: 'sendblue.messages.send' },\n { providerId: 'sendblue', eventType: 'sendblue.message.received', label: 'RCS', transport: 'rcs', sourceKind: 'connection', replies: true, inventoryAction: 'sendblue.lines.state', replyAction: 'sendblue.messages.send' },\n { providerId: 'twilio-sms', eventType: 'twilio-sms.message.received', label: 'SMS / MMS', transport: 'sms', sourceKind: 'connection', replies: true, inventoryAction: 'twilio-sms.list_numbers', replyAction: 'twilio-sms.send_sms' },\n]\n\n/** Fresh copies let applications filter by their live Hub catalog without mutating ours. */\nexport function listConversationChannels(): ConversationChannel[] {\n return channels.map(channel => ({ ...channel }))\n}\n\nexport interface ConversationEndpointOption {\n id: string\n /** Provider display address. Use id, not a reformatted address, to select a resource. */\n address: string\n providerId: string\n channel: 'imessage' | 'sms' | 'whatsapp'\n health: 'healthy' | 'at-risk' | 'critical' | 'unknown'\n}\nfunction record(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\nfunction bounded(value: unknown, max: number): value is string {\n return typeof value === 'string' && value.trim().length > 0 && value.length <= max && !/[\\u0000-\\u001f\\u007f]/.test(value)\n}\n/** Project an authenticated provider-owned inventory response, not user input.\n * Protocol shapes stay with the adapters. Unknown provider health remains unknown;\n * configuration, customer eligibility and delivery readiness are separate facts. */\nexport function conversationEndpointOptions(providerId: string, result: unknown): ConversationEndpointOption[] {\n if (providerId === 'sendblue') {\n const rows = record(result) ? result.data : null\n if (!Array.isArray(rows) || rows.length > 1000) throw new Error('Invalid Sendblue line-state inventory')\n const seen = new Set<string>()\n return rows.map(row => {\n if (!record(row) || !bounded(row.sendblue_number, 16)\n || !/^\\+[1-9]\\d{6,14}$/.test(row.sendblue_number) || seen.has(row.sendblue_number)) {\n throw new Error('Invalid or ambiguous Sendblue line identity')\n }\n seen.add(row.sendblue_number)\n const health: ConversationEndpointOption['health'] = row.status === 'ONLINE' ? 'healthy'\n : row.status === 'DEGRADED' ? 'at-risk' : row.status === 'OFFLINE' ? 'critical' : 'unknown'\n return { id: row.sendblue_number, address: row.sendblue_number,\n providerId, channel: 'imessage' as const, health }\n })\n }\n if (providerId === 'twilio-sms') {\n const rows = record(result) ? result.numbers : null\n if (!Array.isArray(rows) || rows.length > 1000 || (record(result) && result.nextPageUri)) {\n throw new Error('Twilio phone inventory is missing or incomplete')\n }\n const ids = new Set<string>(), addresses = new Set<string>()\n return rows.filter(row => {\n if (!record(row) || !record(row.capabilities) || typeof row.capabilities.sms !== 'boolean') {\n throw new Error('Invalid Twilio phone capability row')\n }\n return row.capabilities.sms\n }).map(row => {\n if (!bounded(row.sid, 34) || !/^PN[a-f0-9]{32}$/i.test(row.sid)\n || !bounded(row.phone_number, 16) || !/^\\+[1-9]\\d{6,14}$/.test(row.phone_number)\n || ids.has(row.sid) || addresses.has(row.phone_number)) {\n throw new Error('Invalid or ambiguous Twilio SMS number identity')\n }\n ids.add(row.sid); addresses.add(row.phone_number)\n return { id: row.sid, address: row.phone_number,\n providerId, channel: 'sms' as const, health: 'unknown' as const }\n })\n }\n if (providerId !== 'linq' && providerId !== 'linq-whatsapp') throw new Error('Owned endpoint enumeration is not available for this provider')\n const whatsapp = providerId === 'linq-whatsapp'\n const values = record(result) ? result[whatsapp ? 'data' : 'phone_numbers'] : null\n if (!Array.isArray(values)) throw new Error('Provider did not return its owned phone-number inventory')\n if (values.length > 1000) throw new Error('Phone inventory exceeds the supported response limit')\n const ids = new Set<string>(), addresses = new Set<string>()\n return values.map(value => {\n if (!record(value)) throw new Error('Invalid phone inventory row')\n const { id, phone_number: address } = value\n if (!bounded(id, 256) || !bounded(address, 320) || ids.has(id) || addresses.has(address)) {\n throw new Error('Invalid or ambiguous owned phone-number identity')\n }\n if (!whatsapp && (!/^[a-f0-9]{8}-(?:[a-f0-9]{4}-){3}[a-f0-9]{12}$/i.test(id) || !/^\\+[1-9]\\d{6,14}$/.test(address))) {\n throw new Error('Invalid or ambiguous owned phone-number identity')\n }\n ids.add(id); addresses.add(address)\n const status = whatsapp ? value.quality_band : record(value.reputation) ? value.reputation.status : undefined\n // WhatsApp raw quality values evolve. Only its documented quality_band is classified.\n const health: ConversationEndpointOption['health'] = status === (whatsapp ? 'green' : 'HEALTHY') ? 'healthy'\n : status === (whatsapp ? 'yellow' : 'AT_RISK') ? 'at-risk'\n : status === (whatsapp ? 'red' : 'CRITICAL') ? 'critical' : 'unknown'\n return { id, address, providerId, channel: whatsapp ? 'whatsapp' as const : 'imessage' as const, health }\n })\n}\n","import { normalizeConversationEvent, type ConversationEventNormalizationResult, type ProviderConversationEvent } from './index.js'\nimport { listConversationChannels } from './channels.js'\n\nexport type ConversationReaction = 'like' | 'love' | 'laugh' | 'emphasize' | 'question' | 'dislike'\nconst whatsappEmoji: Record<ConversationReaction, string> = {\n like: '👍', love: '❤️', laugh: '😂', emphasize: '‼️', question: '❓', dislike: '👎',\n}\n\nexport interface ConversationPresenceCapabilities {\n reaction: boolean\n typing: boolean\n readReceipt: boolean\n}\n\n/** An action plan only. The host rechecks line and connection authority before invoking it. */\nexport interface ConversationPresenceAction {\n action: string\n input: Record<string, unknown>\n idempotencyKey: string\n}\n\ntype Failure = Exclude<ConversationEventNormalizationResult, { ok: true }>\ntype Result = { ok: true; plan: ConversationPresenceAction } | Failure\nconst unsupported = (message: string): Failure => ({ ok: false, code: 'unsupported_event', message })\nconst invalid = (message: string): Failure => ({ ok: false, code: 'invalid_payload', message })\nconst none = (): ConversationPresenceCapabilities => ({ reaction: false, typing: false, readReceipt: false })\n\nfunction eligible(input: ProviderConversationEvent) {\n const normalized = normalizeConversationEvent(input)\n if (!normalized.ok) return normalized\n const event = normalized.event\n if (event.historyOnly || event.isGroup || !event.transport) return unsupported('Presence requires a current one-to-one message with a known transport')\n const channel = listConversationChannels().find(row => row.providerId === event.provider\n && row.eventType === event.eventType && row.transport === event.transport)\n if (!channel) return unsupported('No presence actions are available for this channel')\n return { ok: true as const, event, channel }\n}\n\nfunction operation(value: string): boolean {\n return typeof value === 'string' && value.length > 0 && value.length <= 255 && /^[\\x21-\\x7e]+$/.test(value)\n}\nfunction target(value: string | null): value is string {\n return typeof value === 'string' && value.length > 0 && value.length <= 256 && !/[\\u0000-\\u001f\\u007f]/.test(value)\n}\nfunction phone(value: string | null): value is string {\n return typeof value === 'string' && /^\\+[1-9]\\d{6,14}$/.test(value)\n}\nfunction routedPhones(event: { sender: { address: string | null }; destinations: { address: string | null }[] }) {\n const to = event.sender.address, from = event.destinations[0]?.address ?? null\n return phone(to) && phone(from) && to !== from ? { to, from } : null\n}\n\n/** Protocol support for this authenticated, stored inbound event; account readiness is checked by the host. */\nexport function conversationPresenceCapabilities(input: ProviderConversationEvent): ConversationPresenceCapabilities {\n const matched = eligible(input)\n if (!matched.ok) return none()\n if ((matched.event.provider === 'sendblue' || matched.event.provider === 'contiguity')\n && !routedPhones(matched.event)) return none()\n return {\n reaction: Boolean(matched.channel.reactionAction && target(matched.event.eventId)),\n typing: Boolean(matched.channel.typingAction && target(matched.event.conversationId)),\n readReceipt: Boolean(matched.channel.readReceiptAction && target(matched.event.conversationId)),\n }\n}\n\nfunction plan(input: ProviderConversationEvent, operationId: string, kind: 'reaction' | 'typing' | 'readReceipt', reaction?: ConversationReaction): Result {\n const matched = eligible(input)\n if (!matched.ok) return matched\n if (!operation(operationId)) return invalid('A stable bounded operation id is required')\n const { event, channel } = matched\n const action = kind === 'reaction' ? channel.reactionAction : kind === 'typing' ? channel.typingAction : channel.readReceiptAction\n if (!action) return unsupported('This channel does not support the requested presence action')\n if (kind === 'reaction' && (!reaction || !(['like', 'love', 'laugh', 'emphasize', 'question', 'dislike'] as string[]).includes(reaction))) {\n return invalid('Unsupported reaction')\n }\n if (event.provider === 'sendblue' || event.provider === 'contiguity') {\n const route = routedPhones(event)\n if (!route) return invalid('Presence requires an exact owned line and contact phone number')\n if (event.provider === 'contiguity') {\n if (kind === 'reaction') return unsupported('Contiguity reactions need an explicit, unambiguous text target')\n return { ok: true, plan: { action, idempotencyKey: operationId,\n input: kind === 'typing' ? { to: route.to, from: route.from, action: 'start' }\n : { to: route.to, from: route.from } } }\n }\n const args = kind === 'reaction'\n ? { from_number: route.from, message_handle: event.eventId, reaction }\n : kind === 'typing'\n ? { from_number: route.from, number: route.to, state: 'start' }\n : { from_number: route.from, number: route.to }\n if (kind === 'reaction' && !target(event.eventId)) return invalid('Provider message handle is missing or invalid')\n return { ok: true, plan: { action, input: args, idempotencyKey: operationId } }\n }\n const inputKey = kind === 'reaction' ? 'message_id' : event.provider === 'inkbox' ? 'conversation_id' : 'chat_id'\n const id = kind === 'reaction' ? event.eventId : event.conversationId\n if (!target(id)) return invalid('Provider message or conversation id is missing or invalid')\n const args: Record<string, unknown> = { [inputKey]: id }\n if (kind === 'reaction' && event.provider === 'linq-whatsapp') {\n if (!target(event.conversationId)) return invalid('WhatsApp chat id is missing or invalid')\n args.chat_id = event.conversationId\n }\n if (kind === 'reaction') {\n if (!reaction) return invalid('Unsupported reaction')\n if (event.provider === 'linq-whatsapp') args.emoji = whatsappEmoji[reaction]\n else args.reaction = reaction\n }\n return { ok: true, plan: { action, input: args, idempotencyKey: operationId } }\n}\n\nexport function buildConversationReaction(input: ProviderConversationEvent, reaction: ConversationReaction, operationId: string): Result {\n return plan(input, operationId, 'reaction', reaction)\n}\nexport function buildConversationTyping(input: ProviderConversationEvent, operationId: string): Result {\n return plan(input, operationId, 'typing')\n}\nexport function buildConversationReadReceipt(input: ProviderConversationEvent, operationId: string): Result {\n return plan(input, operationId, 'readReceipt')\n}\n","import {\n normalizeConversationEvent as normalizeExistingConversationEvent,\n type ConversationEvent as ExistingConversationEvent,\n type ConversationEventNormalizationResult as ExistingNormalizationResult,\n} from './core.js'\nimport { normalizeLinqWhatsappConversation } from './linq-whatsapp.js'\nimport { normalizeMobileConversation } from './mobile.js'\nimport { normalizeResendConversation } from './resend.js'\nimport { normalizeTelegramConversation } from './telegram.js'\n\nexport * from './core.js'\nexport { buildMessagingReply, buildMessagingMediaReply, type ConversationReply, type ConversationMediaReplyDescriptor } from './reply.js'\nexport { listConversationChannels, conversationEndpointOptions, type ConversationChannel, type ConversationEndpointOption } from './channels.js'\nexport { conversationPresenceCapabilities, buildConversationReaction, buildConversationTyping, buildConversationReadReceipt,\n type ConversationReaction, type ConversationPresenceCapabilities, type ConversationPresenceAction } from './presence.js'\n\n/** Additive provider vocabulary. Neither sender identity nor group membership is authority. */\nexport interface ConversationEvent extends Omit<ExistingConversationEvent, 'provider'> {\n provider: ExistingConversationEvent['provider'] | 'inkbox' | 'linq' | 'contiguity' | 'linq-whatsapp' | 'resend' | 'sendblue' | 'twilio-sms' | 'telegram'\n /** Actual inbound protocol. Linq reports this per message, not per chat. */\n transport?: 'email' | 'imessage' | 'sms' | 'rcs' | 'whatsapp' | 'telegram'\n isGroup?: boolean\n /** Historical or incomplete input is not a new automatic command. */\n historyOnly?: boolean\n}\nexport type ConversationEventNormalizationResult =\n | { ok: true; event: ConversationEvent }\n | Exclude<ExistingNormalizationResult, { ok: true }>\n\nexport function normalizeConversationEvent(value: unknown): ConversationEventNormalizationResult {\n if (value && typeof value === 'object' && 'provider' in value\n && ['inkbox', 'linq', 'contiguity', 'linq-whatsapp', 'resend', 'sendblue', 'twilio-sms', 'telegram'].includes(String(value.provider))) {\n if (!('type' in value) || typeof value.type !== 'string' || !('payload' in value)) {\n return { ok: false, code: 'invalid_payload', message: 'Provider event requires type and payload' }\n }\n if (value.provider === 'telegram') return normalizeTelegramConversation({ provider: value.provider, type: value.type, payload: value.payload })\n if (value.provider === 'linq-whatsapp') return normalizeLinqWhatsappConversation({ provider: value.provider, type: value.type, payload: value.payload })\n if (value.provider === 'resend') return normalizeResendConversation({ provider: value.provider, type: value.type, payload: value.payload })\n return normalizeMobileConversation({ provider: String(value.provider), type: value.type, payload: value.payload })\n }\n return normalizeExistingConversationEvent(value)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["normalizeConversationEvent","object","invalid","record","phone","invalid","unsupported","record","invalid","object","invalid","normalizeExistingConversationEvent"],"sources":["../../src/conversation-events/core.ts","../../src/conversation-events/linq-whatsapp.ts","../../src/conversation-events/mobile.ts","../../src/conversation-events/resend.ts","../../src/conversation-events/telegram.ts","../../src/conversation-events/reply.ts","../../src/conversation-events/channels.ts","../../src/conversation-events/presence.ts","../../src/conversation-events/index.ts"],"sourcesContent":["import type { TriggerEventCatalog } from '../webhooks/router.js'\n\nexport const MICROSOFT_TEAMS_PROVIDER_ID = 'microsoft-teams' as const\nexport const MICROSOFT_TEAMS_MESSAGE_EVENT = 'teams.message' as const\n\nexport const MICROSOFT_TEAMS_TRIGGER_EVENT_CATALOG = {\n namespace: 'teams.',\n closed: true,\n events: [{ id: MICROSOFT_TEAMS_MESSAGE_EVENT }],\n} as const satisfies TriggerEventCatalog\n\nexport interface InboundEmailAttachment {\n filename?: string\n contentType?: string\n contentBase64?: string\n url?: string\n size?: number\n}\n\n/** Payload emitted by Tangle's verified inbound-email receiver. */\nexport interface InboundEmailPayload {\n messageId?: string\n from: string\n to: string\n subject?: string\n text?: string\n html?: string\n headers?: Record<string, string>\n attachments?: InboundEmailAttachment[]\n receivedAt?: number\n}\n\nexport interface ProviderConversationEvent {\n provider: string\n type: string\n deliveryId?: string\n payload: unknown\n}\n\nexport interface ConversationParticipant {\n id: string | null\n address: string | null\n displayName: string | null\n /** Explicitly marks an unauthenticated email From address. An omitted status makes no claim. */\n verificationStatus?: 'unverified'\n}\n\nexport interface ConversationDestination {\n kind: 'mailbox' | 'channel' | 'chat' | 'user'\n id: string | null\n address: string | null\n displayName: string | null\n}\n\nexport interface ConversationAttachment {\n id: string | null\n name: string | null\n contentType: string | null\n size: number | null\n contentBase64: string | null\n url: string | null\n}\n\n/**\n * Provider-neutral message data for product ingestion.\n *\n * The signed Hub delivery remains the audit record. This projection contains\n * only the stable fields products need for threading, prompts, and files.\n */\nexport interface ConversationEvent {\n version: 1\n provider: 'email' | 'slack' | 'teams'\n eventType: string\n operation: 'created' | 'updated' | 'deleted'\n eventId: string | null\n conversationId: string | null\n parentEventIds: string[]\n sender: ConversationParticipant\n destinations: ConversationDestination[]\n subject: string | null\n text: string | null\n html: string | null\n attachments: ConversationAttachment[]\n occurredAt: number | null\n}\n\nexport type ConversationEventNormalizationErrorCode =\n | 'unsupported_provider'\n | 'unsupported_event'\n | 'invalid_payload'\n\nexport type ConversationEventNormalizationResult =\n | { ok: true; event: ConversationEvent }\n | {\n ok: false\n code: ConversationEventNormalizationErrorCode\n message: string\n }\n\nconst MAX_BODY_LENGTH = 1_000_000\nconst MAX_ATTACHMENTS = 50\nconst MAX_INLINE_ATTACHMENT_LENGTH = 1_100_000\nconst MAX_ATTACHMENT_SIZE = 20 * 1024 * 1024\nconst MAX_HEADERS = 200\n\nexport function normalizeConversationEvent(\n value: unknown,\n): ConversationEventNormalizationResult {\n if (\n !isRecord(value) ||\n typeof value.provider !== 'string' ||\n typeof value.type !== 'string' ||\n (value.deliveryId !== undefined &&\n typeof value.deliveryId !== 'string') ||\n !Object.prototype.hasOwnProperty.call(value, 'payload')\n ) {\n return invalidPayload(\n 'Provider conversation event requires provider, type, and payload',\n )\n }\n const input: ProviderConversationEvent = {\n provider: value.provider,\n type: value.type,\n ...(typeof value.deliveryId === 'string'\n ? { deliveryId: value.deliveryId }\n : {}),\n payload: value.payload,\n }\n if (input.provider === 'email') {\n if (input.type !== 'email.received') {\n return unsupportedEvent(input.provider, input.type)\n }\n return normalizeEmail(input)\n }\n if (input.provider === 'slack') {\n if (input.type !== 'slack.message' && input.type !== 'slack.app_mention') {\n return unsupportedEvent(input.provider, input.type)\n }\n return normalizeSlack(input)\n }\n if (input.provider === MICROSOFT_TEAMS_PROVIDER_ID) {\n if (input.type !== MICROSOFT_TEAMS_MESSAGE_EVENT) {\n return unsupportedEvent(input.provider, input.type)\n }\n return normalizeMicrosoftTeams(input)\n }\n return {\n ok: false,\n code: 'unsupported_provider',\n message: `Conversation events do not support provider ${input.provider}`,\n }\n}\n\nfunction normalizeMicrosoftTeams(\n input: ProviderConversationEvent,\n): ConversationEventNormalizationResult {\n const activity = input.payload\n if (!isRecord(activity) || activity.type !== 'message') {\n return invalidPayload('Teams payload requires a message activity')\n }\n if (\n activity.channelId !== undefined &&\n activity.channelId !== 'msteams'\n ) {\n return invalidPayload('Teams activity came from an unsupported channel')\n }\n const text = optionalString(activity.text, MAX_BODY_LENGTH)\n if (text === undefined) {\n return invalidPayload('Teams message text is invalid')\n }\n const conversation = isRecord(activity.conversation)\n ? activity.conversation\n : null\n const conversationId = normalizeNullableString(conversation?.id, 2_000)\n if (!conversationId) {\n return invalidPayload('Teams message requires a conversation id')\n }\n const channelData = isRecord(activity.channelData)\n ? activity.channelData\n : null\n const tenant = resolveMicrosoftTeamsTenantId(activity)\n if (!tenant.ok) return invalidPayload(tenant.message)\n const tenantId = tenant.tenantId\n const from = isRecord(activity.from) ? activity.from : null\n const channel = isRecord(channelData?.channel)\n ? channelData.channel\n : null\n const team = isRecord(channelData?.team) ? channelData.team : null\n const channelId = normalizeNullableString(channel?.id, 2_000)\n const channelName = normalizeNullableString(channel?.name, 300)\n const teamId = normalizeNullableString(team?.id, 2_000)\n const replyToId = normalizeNullableString(activity.replyToId, 2_000)\n const eventId =\n normalizeNullableString(activity.id, 2_000) ??\n normalizeNullableString(input.deliveryId, 2_000)\n const attachments = normalizeTeamsAttachments(activity.attachments)\n if (!attachments.ok) return attachments\n const timestamp = normalizeTeamsTimestamp(\n activity.timestamp ?? activity.localTimestamp,\n )\n if (timestamp === undefined) {\n return invalidPayload('Teams message timestamp is invalid')\n }\n\n return {\n ok: true,\n event: {\n version: 1,\n provider: 'teams',\n eventType: input.type,\n operation: 'created',\n eventId,\n conversationId: `${tenantId}:${conversationId}`,\n parentEventIds: replyToId ? [replyToId] : [],\n sender: {\n id:\n normalizeNullableString(from?.aadObjectId, 300) ??\n normalizeNullableString(from?.id, 2_000),\n address: null,\n displayName: normalizeNullableString(from?.name, 300),\n },\n destinations: [\n {\n kind: channelId ? 'channel' : 'chat',\n id: channelId ?? conversationId,\n address: null,\n displayName: channelName,\n },\n ...(teamId\n ? [\n {\n kind: 'channel' as const,\n id: teamId,\n address: null,\n displayName: normalizeNullableString(team?.name, 300),\n },\n ]\n : []),\n ],\n subject: null,\n text: text ?? null,\n html: null,\n attachments: attachments.value,\n occurredAt: timestamp ?? null,\n },\n }\n}\n\nexport type MicrosoftTeamsTenantResolution =\n | { ok: true; tenantId: string }\n | { ok: false; message: string }\n\n/**\n * Resolve the authenticated Teams tenant identity shared by the platform\n * receiver and product normalizer. Teams may repeat it in both\n * `channelData.tenant.id` and `conversation.tenantId`; disagreement is\n * rejected so an event can never be attributed to a guessed tenant.\n */\nexport function resolveMicrosoftTeamsTenantId(\n payload: unknown,\n): MicrosoftTeamsTenantResolution {\n if (!isRecord(payload)) {\n return { ok: false, message: 'Teams payload requires an activity object' }\n }\n const conversation = isRecord(payload.conversation)\n ? payload.conversation\n : null\n const channelData = isRecord(payload.channelData)\n ? payload.channelData\n : null\n const channelDataTenant = isRecord(channelData?.tenant)\n ? normalizeNullableString(channelData.tenant.id, 300)\n : null\n const conversationTenant = normalizeNullableString(\n conversation?.tenantId,\n 300,\n )\n if (\n channelDataTenant &&\n conversationTenant &&\n channelDataTenant !== conversationTenant\n ) {\n return {\n ok: false,\n message: 'Teams activity contains conflicting tenant ids',\n }\n }\n const tenantId = channelDataTenant ?? conversationTenant\n return tenantId\n ? { ok: true, tenantId }\n : { ok: false, message: 'Teams message requires a tenant id' }\n}\n\nfunction normalizeEmail(\n input: ProviderConversationEvent,\n): ConversationEventNormalizationResult {\n const payload = input.payload\n if (!isRecord(payload)) return invalidPayload('Email payload must be an object')\n const from = optionalString(payload.from, 320)\n const to = optionalString(payload.to, 320)\n if (\n from === undefined ||\n from === null ||\n to === undefined ||\n to === null ||\n !from.trim() ||\n !to.trim()\n ) {\n return invalidPayload('Email payload requires non-empty string from and to')\n }\n const messageId = optionalString(payload.messageId, 1_000)\n const subject = optionalString(payload.subject, 2_000)\n const text = optionalString(payload.text, MAX_BODY_LENGTH)\n const html = optionalString(payload.html, MAX_BODY_LENGTH)\n if (\n messageId === undefined ||\n subject === undefined ||\n text === undefined ||\n html === undefined\n ) {\n return invalidPayload('Email payload contains an invalid string field')\n }\n const receivedAt = optionalFiniteNumber(payload.receivedAt, 0)\n if (receivedAt === undefined) {\n return invalidPayload('Email receivedAt must be a non-negative number')\n }\n const headers = normalizeHeaders(payload.headers)\n if (!headers.ok) return headers\n const attachments = normalizeEmailAttachments(payload.attachments)\n if (!attachments.ok) return attachments\n\n return {\n ok: true,\n event: {\n version: 1,\n provider: 'email',\n eventType: input.type,\n operation: 'created',\n eventId:\n normalizeMessageId(messageId) ??\n normalizeNullableString(input.deliveryId, 1_000),\n conversationId: null,\n parentEventIds: referencedMessageIds(headers.value),\n sender: {\n id: null,\n address: normalizeNullableString(from, 320),\n displayName: null,\n verificationStatus: 'unverified',\n },\n destinations: [\n {\n kind: 'mailbox',\n id: null,\n address: normalizeMailbox(to),\n displayName: null,\n },\n ],\n subject: normalizeNullableString(subject, 2_000),\n text: text ?? null,\n html: html ?? null,\n attachments: attachments.value,\n occurredAt: receivedAt ?? null,\n },\n }\n}\n\nfunction normalizeSlack(\n input: ProviderConversationEvent,\n): ConversationEventNormalizationResult {\n const wrapper = input.payload\n if (!isRecord(wrapper) || !isRecord(wrapper.event)) {\n return invalidPayload('Slack payload requires an Events API event object')\n }\n const outerEvent = wrapper.event\n const changedMessage =\n outerEvent.subtype === 'message_changed' && isRecord(outerEvent.message)\n ? outerEvent.message\n : null\n const deletedMessage =\n outerEvent.subtype === 'message_deleted' &&\n isRecord(outerEvent.previous_message)\n ? outerEvent.previous_message\n : null\n const message = changedMessage ?? deletedMessage ?? outerEvent\n if (\n message.type !== 'message' &&\n input.type !== 'slack.app_mention'\n ) {\n return invalidPayload('Slack event does not contain a message')\n }\n const text = optionalString(message.text, MAX_BODY_LENGTH)\n if (text === undefined) {\n return invalidPayload('Slack message text is invalid')\n }\n const channel =\n normalizeNullableString(outerEvent.channel, 300) ??\n normalizeNullableString(message.channel, 300)\n if (!channel) return invalidPayload('Slack message requires a channel')\n const timestamp =\n normalizeNullableString(message.ts, 100) ??\n normalizeNullableString(outerEvent.event_ts, 100)\n const threadTimestamp = normalizeNullableString(message.thread_ts, 100)\n const team =\n normalizeNullableString(wrapper.team_id, 300) ??\n normalizeNullableString(wrapper.context_team_id, 300)\n const rootTimestamp = threadTimestamp ?? timestamp\n const files = normalizeSlackFiles(message.files)\n if (!files.ok) return files\n const subtype = normalizeNullableString(outerEvent.subtype, 100)\n\n return {\n ok: true,\n event: {\n version: 1,\n provider: 'slack',\n eventType: input.type,\n operation:\n subtype === 'message_deleted'\n ? 'deleted'\n : subtype === 'message_changed'\n ? 'updated'\n : 'created',\n eventId:\n normalizeNullableString(wrapper.event_id, 300) ??\n normalizeNullableString(message.client_msg_id, 300) ??\n normalizeNullableString(input.deliveryId, 300) ??\n timestamp,\n conversationId: rootTimestamp\n ? [team, channel, rootTimestamp].filter(Boolean).join(':')\n : null,\n parentEventIds:\n threadTimestamp && timestamp && threadTimestamp !== timestamp\n ? [threadTimestamp]\n : [],\n sender: {\n id:\n normalizeNullableString(message.user, 300) ??\n normalizeNullableString(message.bot_id, 300),\n address: null,\n displayName:\n normalizeNullableString(message.username, 300) ??\n (isRecord(message.user_profile)\n ? normalizeNullableString(\n message.user_profile.display_name,\n 300,\n )\n : null),\n },\n destinations: [\n {\n kind: 'channel',\n id: channel,\n address: null,\n displayName: null,\n },\n ],\n subject: null,\n text: text ?? null,\n html: null,\n attachments: files.value,\n occurredAt:\n slackTimestampMs(timestamp) ??\n epochSecondsMs(wrapper.event_time) ??\n null,\n },\n }\n}\n\nfunction normalizeHeaders(\n value: unknown,\n):\n | { ok: true; value: Record<string, string> }\n | {\n ok: false\n code: 'invalid_payload'\n message: string\n } {\n if (value === undefined) return { ok: true, value: {} }\n if (!isRecord(value) || Object.keys(value).length > MAX_HEADERS) {\n return invalidPayload('Email headers must be a bounded string record')\n }\n const headers: Record<string, string> = {}\n for (const [key, entry] of Object.entries(value)) {\n if (\n key.length === 0 ||\n key.length > 200 ||\n typeof entry !== 'string' ||\n entry.length > 4_000\n ) {\n return invalidPayload('Email headers must be a bounded string record')\n }\n headers[key.toLowerCase()] = entry\n }\n return { ok: true, value: headers }\n}\n\nfunction normalizeEmailAttachments(\n value: unknown,\n):\n | { ok: true; value: ConversationAttachment[] }\n | {\n ok: false\n code: 'invalid_payload'\n message: string\n } {\n if (value === undefined) return { ok: true, value: [] }\n if (!Array.isArray(value) || value.length > MAX_ATTACHMENTS) {\n return invalidPayload('Email attachments exceed the supported limit')\n }\n const attachments: ConversationAttachment[] = []\n for (const entry of value) {\n if (!isRecord(entry)) {\n return invalidPayload('Email attachment must be an object')\n }\n const name = optionalString(entry.filename, 240)\n const contentType = optionalString(entry.contentType, 200)\n const contentBase64 = optionalString(\n entry.contentBase64,\n MAX_INLINE_ATTACHMENT_LENGTH,\n )\n const url = optionalString(entry.url, 2_048)\n const size = optionalFiniteNumber(entry.size, 0, MAX_ATTACHMENT_SIZE, true)\n if (\n name === undefined ||\n contentType === undefined ||\n contentBase64 === undefined ||\n url === undefined ||\n size === undefined\n ) {\n return invalidPayload('Email attachment contains an invalid field')\n }\n attachments.push({\n id: null,\n name: name ?? null,\n contentType: contentType ?? null,\n size: size ?? null,\n contentBase64: contentBase64 ?? null,\n url: url ?? null,\n })\n }\n return { ok: true, value: attachments }\n}\n\nfunction normalizeSlackFiles(\n value: unknown,\n):\n | { ok: true; value: ConversationAttachment[] }\n | {\n ok: false\n code: 'invalid_payload'\n message: string\n } {\n if (value === undefined) return { ok: true, value: [] }\n if (!Array.isArray(value) || value.length > MAX_ATTACHMENTS) {\n return invalidPayload('Slack files exceed the supported limit')\n }\n const files: ConversationAttachment[] = []\n for (const entry of value) {\n if (!isRecord(entry)) return invalidPayload('Slack file must be an object')\n const size = optionalFiniteNumber(entry.size, 0, MAX_ATTACHMENT_SIZE, true)\n if (size === undefined) return invalidPayload('Slack file size is invalid')\n files.push({\n id: normalizeNullableString(entry.id, 300),\n name:\n normalizeNullableString(entry.name, 240) ??\n normalizeNullableString(entry.title, 240),\n contentType: normalizeNullableString(entry.mimetype, 200),\n size: size ?? null,\n contentBase64: null,\n // Slack file URLs require the workspace bot token. Products use the\n // `slack.download_file` Hub action with this file id; exposing a private\n // URL here would make downstream runtimes attempt an unauthenticated fetch.\n url: null,\n })\n }\n return { ok: true, value: files }\n}\n\nfunction normalizeTeamsAttachments(\n value: unknown,\n):\n | { ok: true; value: ConversationAttachment[] }\n | {\n ok: false\n code: 'invalid_payload'\n message: string\n } {\n if (value === undefined) return { ok: true, value: [] }\n if (!Array.isArray(value) || value.length > MAX_ATTACHMENTS) {\n return invalidPayload('Teams attachments exceed the supported limit')\n }\n const attachments: ConversationAttachment[] = []\n for (const entry of value) {\n if (!isRecord(entry)) {\n return invalidPayload('Teams attachment must be an object')\n }\n const id = optionalString(entry.id, 300)\n const name = optionalString(entry.name, 240)\n const contentType = optionalString(entry.contentType, 200)\n if (\n id === undefined ||\n name === undefined ||\n contentType === undefined\n ) {\n return invalidPayload('Teams attachment contains an invalid field')\n }\n attachments.push({\n id: normalizeNullableString(id, 300),\n name: normalizeNullableString(name, 240),\n contentType: normalizeNullableString(contentType, 200),\n size: null,\n contentBase64: null,\n // Bot attachment URLs require Microsoft authorization. The receiver\n // keeps that credential inside Hub; products only receive stable metadata.\n url: null,\n })\n }\n return { ok: true, value: attachments }\n}\n\nfunction normalizeTeamsTimestamp(value: unknown): number | null | undefined {\n if (value === undefined || value === null) return null\n if (typeof value !== 'string' || value.length > 100) return undefined\n const timestamp = Date.parse(value)\n return Number.isFinite(timestamp) && timestamp >= 0\n ? timestamp\n : undefined\n}\n\nfunction referencedMessageIds(headers: Record<string, string>): string[] {\n const values = [headers['in-reply-to'], headers.references].filter(\n (value): value is string => Boolean(value?.trim()),\n )\n const ids: string[] = []\n for (const value of values) {\n const bracketed = value.match(/<[^<>]{1,1000}>/g)\n const candidates = bracketed ?? value.split(/\\s+/)\n for (const candidate of candidates) {\n const normalized = normalizeMessageId(candidate)\n if (normalized && !ids.includes(normalized)) ids.push(normalized)\n }\n }\n return ids.slice(0, 50)\n}\n\nfunction normalizeMessageId(value: string | null | undefined): string | null {\n if (!value) return null\n const trimmed = value.trim()\n if (!trimmed) return null\n return trimmed.startsWith('<') && trimmed.endsWith('>')\n ? trimmed.slice(1, -1).trim() || null\n : trimmed\n}\n\nfunction normalizeMailbox(value: string): string {\n return value.trim().toLowerCase()\n}\n\nfunction normalizeNullableString(\n value: unknown,\n maxLength: number,\n): string | null {\n return typeof value === 'string' && value.length <= maxLength\n ? value.trim() || null\n : null\n}\n\n/**\n * Undefined means invalid; null means the optional field was absent.\n */\nfunction optionalString(\n value: unknown,\n maxLength: number,\n): string | null | undefined {\n if (value === undefined) return null\n return typeof value === 'string' && value.length <= maxLength\n ? value\n : undefined\n}\n\n/**\n * Undefined means invalid; null means the optional field was absent.\n */\nfunction optionalFiniteNumber(\n value: unknown,\n minimum: number,\n maximum = Number.MAX_SAFE_INTEGER,\n integer = false,\n): number | null | undefined {\n if (value === undefined) return null\n if (\n typeof value !== 'number' ||\n !Number.isFinite(value) ||\n value < minimum ||\n value > maximum ||\n (integer && !Number.isInteger(value))\n ) {\n return undefined\n }\n return value\n}\n\nfunction slackTimestampMs(value: string | null): number | null {\n if (!value || !/^\\d{1,12}(?:\\.\\d{1,9})?$/.test(value)) return null\n const seconds = Number(value)\n return Number.isFinite(seconds) ? Math.round(seconds * 1_000) : null\n}\n\nfunction epochSecondsMs(value: unknown): number | null {\n return typeof value === 'number' && Number.isFinite(value) && value >= 0\n ? Math.round(value * 1_000)\n : null\n}\n\nfunction unsupportedEvent(\n provider: string,\n type: string,\n): ConversationEventNormalizationResult {\n return {\n ok: false,\n code: 'unsupported_event',\n message: `Conversation events do not support ${provider} event ${type}`,\n }\n}\n\nfunction invalidPayload(\n message: string,\n): {\n ok: false\n code: 'invalid_payload'\n message: string\n} {\n return { ok: false, code: 'invalid_payload', message }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import type { ConversationEventNormalizationResult, ProviderConversationEvent } from './index.js'\nimport { linqWhatsappAttachmentUrl } from '../linq-whatsapp-attachment-url.js'\n\nfunction object(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\nfunction id(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0 && value.length <= 256 && !/[\\u0000-\\u001f\\u007f]/.test(value)\n}\nconst invalid = (message: string): ConversationEventNormalizationResult => ({ ok: false, code: 'invalid_payload', message })\nconst MEDIA_KINDS = new Set(['image', 'video', 'audio', 'document', 'sticker'])\n\nfunction mediaPart(part: Record<string, unknown>) {\n if (typeof part.kind !== 'string' || !MEDIA_KINDS.has(part.kind)) return null\n const url = part.url == null ? null : linqWhatsappAttachmentUrl(part.url)\n if (part.url != null && !url) return null\n if (!id(part.media_id)) return null\n if (part.filename !== undefined && (typeof part.filename !== 'string' || part.filename.length > 240 || /[\\u0000-\\u001f\\u007f]/.test(part.filename))) return null\n if (part.mime_type !== undefined && (typeof part.mime_type !== 'string' || part.mime_type.length > 200 || /[\\u0000-\\u001f\\u007f]/.test(part.mime_type))) return null\n if (part.caption !== undefined && (typeof part.caption !== 'string' || part.caption.length > 1024)) return null\n if (part.byte_size !== undefined && (!Number.isSafeInteger(part.byte_size) || (part.byte_size as number) < 0)) return null\n return {\n attachment: { id: typeof part.media_id === 'string' ? part.media_id : null,\n name: typeof part.filename === 'string' ? part.filename : null,\n contentType: typeof part.mime_type === 'string' ? part.mime_type : null,\n size: typeof part.byte_size === 'number' ? part.byte_size : null,\n contentBase64: null, url },\n caption: typeof part.caption === 'string' && part.caption.length <= 1024 ? part.caption : null,\n }\n}\n\n/** Fresh webhook snapshots only. Historical range notifications need journal hydration.\n * A chat represents one customer, but the message does not contain their address.\n * Keep that customer opaque; never mislabel message.from (our number) as the sender. */\nexport function normalizeLinqWhatsappConversation(input: ProviderConversationEvent): ConversationEventNormalizationResult {\n const value = input.payload\n if (!object(value) || input.type !== `linq-whatsapp.${value.type}`) return invalid('Event type does not match the provider envelope')\n if (value.type !== 'message.received') return { ok: false, code: 'unsupported_event', message: 'Not an incoming message' }\n if (!object(value.data) || !object(value.data.message)) return invalid('Read the chat journal to hydrate this historical event')\n const message = value.data.message\n if (!id(value.id) || !id(message.id) || !id(message.chat_id) || !id(message.from) || message.direction !== 'inbound') {\n return invalid('Incoming message requires a stable identity, conversation and owned destination')\n }\n if (value.data.chat_id !== undefined && value.data.chat_id !== message.chat_id) return invalid('Chat identity mismatch')\n if (!Array.isArray(message.parts) || !message.parts.length || message.parts.length > 50) return invalid('Invalid message parts')\n const text: string[] = []\n const attachments: NonNullable<ReturnType<typeof mediaPart>>['attachment'][] = []\n for (const part of message.parts) {\n if (!object(part)) return invalid('Invalid message part')\n if (part.type === 'media') {\n const media = mediaPart(part)\n if (!media) return invalid('Invalid media attachment')\n attachments.push(media.attachment)\n if (media.caption) text.push(media.caption)\n } else if (part.type === 'text' && typeof part.body === 'string' && part.body.length <= 4096) {\n text.push(part.body)\n } else {\n return { ok: false, code: 'unsupported_event', message: 'This message requires non-text handling' }\n }\n }\n const occurredAt = typeof message.created_at === 'string' ? Date.parse(message.created_at) : NaN\n if (!Number.isSafeInteger(occurredAt) || occurredAt < 0) return invalid('Invalid message timestamp')\n return { ok: true, event: {\n version: 1, provider: 'linq-whatsapp', eventType: input.type, operation: 'created', eventId: message.id,\n conversationId: message.chat_id, parentEventIds: [],\n sender: { id: `customer:${message.chat_id}`, address: null, displayName: null },\n destinations: [{ kind: 'chat', id: message.from, address: message.from, displayName: null }],\n subject: null, text: text.join('\\n'), html: null, attachments, occurredAt, transport: 'whatsapp', isGroup: false, historyOnly: false,\n } }\n}\n","import type { ConversationAttachment, ConversationEvent, ConversationEventNormalizationResult, ProviderConversationEvent } from './index.js'\n\ntype RecordValue = Record<string, unknown>\nfunction record(value: unknown): value is RecordValue { return value !== null && typeof value === 'object' && !Array.isArray(value) }\nfunction string(value: unknown, max = 2000): string | null {\n return typeof value === 'string' && value.length > 0 && value.length <= max && !/[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]/.test(value) ? value : null\n}\nfunction timestamp(value: unknown): number | null {\n const n = typeof value === 'number' ? value * 1000 : typeof value === 'string' ? Date.parse(value) : NaN\n return Number.isSafeInteger(n) && n >= 0 ? n : null\n}\nfunction phone(value: unknown): value is string {\n return typeof value === 'string' && /^\\+[1-9]\\d{6,14}$/.test(value)\n}\nconst invalid = (message: string): ConversationEventNormalizationResult => ({ ok: false, code: 'invalid_payload', message })\nconst unsupported = (): ConversationEventNormalizationResult => ({ ok: false, code: 'unsupported_event', message: 'Not a supported incoming conversation message' })\n\nfunction attachment(value: unknown): ConversationAttachment | null {\n if (!record(value)) return null\n const url = string(value.url ?? value.value, 8192)\n if (!url) return null\n try { const u = new URL(url); if (u.protocol !== 'https:' || u.username || u.password) return null } catch { return null }\n return { id: string(value.id), name: string(value.filename ?? value.name, 255),\n contentType: string(value.mime_type ?? value.mime ?? value.content_type, 200), size: null, contentBase64: null, url }\n}\n\nfunction finish(input: ProviderConversationEvent, data: {\n id: unknown; conversation: unknown; sender: unknown; destination: unknown;\n destinationAddress?: unknown; text: unknown; time: unknown; media?: unknown; parent?: unknown;\n subject?: unknown; destinationKind?: 'chat' | 'mailbox'; isGroup?: boolean; historyOnly?: boolean;\n senderVerificationStatus?: 'unverified';\n transport?: ConversationEvent['transport'];\n}): ConversationEventNormalizationResult {\n const id = string(data.id), conversation = string(data.conversation), sender = string(data.sender), destination = string(data.destination)\n if (!id || !conversation || !sender || !destination) return invalid('Message identity, conversation, sender and destination are required')\n if (data.text !== null && data.text !== undefined && (typeof data.text !== 'string' || data.text.length > 1_000_000)) return invalid('Invalid message text')\n if (data.media !== undefined && data.media !== null && (!Array.isArray(data.media) || data.media.length > 50)) return invalid('Invalid attachment list')\n const media = (data.media ?? []) as unknown[]\n const attachments = media.map(attachment)\n if (attachments.some((a) => !a)) return invalid('Attachments require HTTPS references; bytes must be resolved through the authorized file boundary')\n const time = timestamp(data.time)\n if (time === null) return invalid('A valid provider timestamp is required')\n const provider = input.provider as 'inkbox' | 'linq' | 'contiguity' | 'sendblue' | 'twilio-sms'\n const event: ConversationEvent = {\n version: 1, provider, eventType: input.type, operation: 'created', eventId: id,\n conversationId: conversation, parentEventIds: string(data.parent) ? [String(data.parent)] : [],\n sender: { id: sender, address: sender, displayName: null,\n ...(data.senderVerificationStatus ? { verificationStatus: data.senderVerificationStatus } : {}) },\n destinations: [{ kind: data.destinationKind ?? 'chat', id: destination, address: string(data.destinationAddress), displayName: null }],\n subject: string(data.subject, 998), text: (data.text as string | null | undefined) ?? null, html: null,\n attachments: attachments as ConversationAttachment[], occurredAt: time,\n isGroup: data.isGroup === true, historyOnly: data.historyOnly === true,\n ...(data.transport ? { transport: data.transport } : {}),\n }\n return { ok: true, event }\n}\n\n/** Called after the host verifies signatures and resolves the owning connection. */\nexport function normalizeMobileConversation(input: ProviderConversationEvent): ConversationEventNormalizationResult {\n const p = input.payload\n if (!record(p)) return invalid('Provider payload requires an object')\n if (input.provider === 'sendblue') {\n if (input.type !== 'sendblue.message.received') return unsupported()\n if (p.is_outbound !== false || String(p.status).toUpperCase() !== 'RECEIVED' || !phone(p.from_number)\n || !phone(p.sendblue_number) || (p.to_number !== undefined && p.to_number !== p.sendblue_number)\n || (p.number !== undefined && p.number !== p.from_number)) {\n return invalid('Sendblue requires an inbound received message with exact line and contact routing')\n }\n const service = typeof p.service === 'string' ? p.service.toLowerCase() : null\n const transport = service === 'imessage' ? 'imessage'\n : service === 'sms' ? 'sms' : service === 'rcs' ? 'rcs' : null\n const messageType = typeof p.message_type === 'string' ? p.message_type.toLowerCase() : null\n if (!transport || (messageType !== 'message' && messageType !== 'group')) return unsupported()\n const group = messageType === 'group' || Boolean(p.group_id)\n if (group && !string(p.group_id, 256)) return invalid('Group messages require a group id')\n if (p.media_url !== undefined && p.media_url !== null && typeof p.media_url !== 'string') return invalid('Invalid Sendblue media URL')\n return finish(input, { id: p.message_handle,\n conversation: group ? p.group_id : JSON.stringify(['sendblue', p.sendblue_number, p.from_number]),\n sender: p.from_number, destination: p.sendblue_number, destinationAddress: p.sendblue_number,\n text: p.content, time: p.date_sent, media: p.media_url ? [{ url: p.media_url }] : [],\n parent: record(p.reply_to) ? p.reply_to.message_handle : undefined,\n isGroup: group, historyOnly: p.opted_out === true, transport })\n }\n if (input.provider === 'twilio-sms') {\n if (input.type !== 'twilio-sms.message.received') return unsupported()\n if (!/^AC[a-f\\d]{32}$/i.test(String(p.AccountSid ?? '')) || !phone(p.From) || !phone(p.To)\n || !/^(SM|MM)[a-f\\d]{32}$/i.test(String(p.MessageSid ?? ''))) {\n return invalid('Twilio message requires its signed account, SID, and phone routing')\n }\n const count = Number(p.NumMedia ?? 0)\n if (!Number.isSafeInteger(count) || count < 0 || count > 10) return invalid('Invalid Twilio media count')\n const media: RecordValue[] = []\n for (let index = 0; index < count; index++) {\n const rawUrl = string(p[`MediaUrl${index}`], 8192)\n if (!rawUrl) return invalid('Missing Twilio media URL')\n let url: URL\n try { url = new URL(rawUrl) } catch { return invalid('Invalid Twilio media URL') }\n const parts = /^\\/2010-04-01\\/Accounts\\/(AC[a-f\\d]{32})\\/Messages\\/((?:SM|MM)[a-f\\d]{32})\\/Media\\/(ME[a-f\\d]{32})$/i.exec(url.pathname)\n if (url.origin !== 'https://api.twilio.com' || url.username || url.password || url.search || !parts\n || parts[1]!.toLowerCase() !== String(p.AccountSid).toLowerCase()\n || parts[2]!.toLowerCase() !== String(p.MessageSid).toLowerCase()) {\n return invalid('Twilio media URL must belong to the signed message and account')\n }\n media.push({ id: parts[3], url: rawUrl, mime_type: p[`MediaContentType${index}`] })\n }\n return finish(input, { id: p.MessageSid, conversation: JSON.stringify(['twilio-sms', p.To, p.From]),\n sender: p.From, destination: p.To, destinationAddress: p.To, text: p.Body,\n time: p.__receivedAt, media, transport: 'sms' })\n }\n if (!record(p.data)) return invalid('Provider payload requires a data object')\n const data = p.data\n if (input.provider === 'inkbox') {\n if (input.type !== `inkbox.${p.event_type}`) return invalid('Event type does not match the provider envelope')\n if (p.event_type === 'imessage.received') {\n const m = data.message\n if (!record(m) || m.direction !== 'inbound') return invalid('Expected an inbound iMessage')\n return finish(input, { id: m.id, conversation: m.conversation_id, sender: m.sender_number ?? m.remote_number,\n destination: m.conversation_id, text: m.content, time: m.created_at ?? p.timestamp, media: m.media, isGroup: m.is_group === true, transport: 'imessage' })\n }\n if (p.event_type === 'text.received') {\n const m = data.text_message\n if (!record(m) || m.direction !== 'inbound') return invalid('Expected an inbound phone text')\n return finish(input, { id: m.id, conversation: m.conversation_id, sender: m.sender_phone_number ?? m.remote_phone_number,\n destination: m.local_phone_number, destinationAddress: m.local_phone_number, text: m.text, time: m.created_at ?? p.timestamp,\n media: m.media, isGroup: m.is_group === true, transport: 'sms' })\n }\n if (p.event_type === 'message.received') {\n const m = data.message\n if (!record(m) || m.direction !== 'inbound') return invalid('Expected inbound mail')\n return finish(input, { id: m.id, conversation: m.thread_id ?? m.id, sender: m.from_address,\n destination: m.email_address, destinationAddress: m.email_address, destinationKind: 'mailbox', text: m.body,\n time: m.created_at ?? p.timestamp, subject: m.subject,\n senderVerificationStatus: 'unverified',\n historyOnly: m.body_state !== 'complete' || m.body_truncated === true, transport: 'email' })\n }\n return unsupported()\n }\n if (input.provider === 'linq') {\n if (input.type !== `linq.${p.event_type}`) return invalid('Event type does not match the provider envelope')\n if (p.event_type !== 'message.received') return unsupported()\n if (p.webhook_version !== '2026-02-03' || data.direction !== 'inbound' || !record(data.chat)\n || !record(data.sender_handle) || !record(data.chat.owner_handle) || data.chat.owner_handle.is_me !== true || data.sender_handle.is_me === true) {\n return invalid('Linq requires v2026-02-03 incoming payloads with explicit sender and owner handles')\n }\n const transport = data.service === 'iMessage' ? 'imessage'\n : data.service === 'SMS' ? 'sms' : data.service === 'RCS' ? 'rcs' : null\n if (!transport) return invalid('Linq incoming message requires its actual service')\n if (!Array.isArray(data.parts) || data.parts.length > 50) return invalid('Invalid Linq parts')\n const texts: string[] = [], media: RecordValue[] = []\n for (const part of data.parts) {\n if (!record(part)) return invalid('Invalid Linq part')\n if (part.type === 'text' || part.type === 'link') {\n if (typeof part.value !== 'string') return invalid('Invalid Linq text')\n texts.push(part.value)\n } else if (part.type === 'media') media.push(part)\n else return unsupported()\n }\n return finish(input, { id: data.id, conversation: data.chat.id, sender: data.sender_handle.handle,\n destination: data.chat.id, destinationAddress: data.chat.owner_handle.handle,\n text: texts.join('\\n'), time: data.sent_at ?? p.created_at, media,\n parent: record(data.reply_to) ? data.reply_to.message_id : undefined,\n isGroup: data.chat.is_group === true, historyOnly: data.reconciled_at != null || data.zero_retention === true,\n transport })\n }\n if (input.provider === 'contiguity') {\n if (input.type !== `contiguity.${p.type}`) return invalid('Event type does not match the provider envelope')\n if (!['imessage.incoming', 'text.incoming.sms', 'text.incoming.mms'].includes(String(p.type))) return unsupported()\n if (!string(data.to, 320) || !string(data.from, 320)) return invalid('Missing Contiguity phone routing')\n // No native chat id in v2: use a collision-free tuple, not a bare sender across channels.\n return finish(input, { id: p.id, conversation: JSON.stringify([p.type === 'imessage.incoming' ? 'imessage' : 'text', data.to, data.from]),\n sender: data.from, destination: data.to, destinationAddress: data.to, text: data.body,\n time: data.timestamp ?? p.timestamp, media: data.attachments,\n transport: p.type === 'imessage.incoming' ? 'imessage' : 'sms' })\n }\n return { ok: false, code: 'unsupported_provider', message: 'Unsupported mobile provider' }\n}\n","import type { ConversationEvent, ConversationEventNormalizationResult, ProviderConversationEvent } from './index.js'\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\nfunction address(value: unknown): string | null {\n if (typeof value !== 'string' || value.length > 320) return null\n const match = /^(?:[^<>]*<)?([^<>\\s]+@[^<>\\s]+)(?:>)?$/.exec(value.trim())\n return match?.[1]?.toLowerCase() ?? null\n}\nconst invalid = (message: string): ConversationEventNormalizationResult => ({ ok: false, code: 'invalid_payload', message })\n\n/** The host adds the provider-read email after verifying the notification. */\nexport function normalizeResendConversation(input: ProviderConversationEvent): ConversationEventNormalizationResult {\n const payload = input.payload\n if (input.type !== 'resend.email.received' || !record(payload) || payload.type !== 'email.received'\n || !record(payload.data) || !record(payload.received)) return invalid('Resend requires a hydrated received-email notification')\n const data = payload.data, received = payload.received\n if (typeof data.email_id !== 'string' || received.id !== data.email_id\n || !Array.isArray(received.to) || received.to.length < 1 || received.to.length > 50\n || (received.cc !== undefined && (!Array.isArray(received.cc) || received.cc.length > 50))\n || !address(received.from)\n || (received.text != null && typeof received.text !== 'string')\n || typeof received.created_at !== 'string' || !Number.isFinite(Date.parse(received.created_at))) {\n return invalid('Resend email identity, sender, recipient, body or time is invalid')\n }\n const recipients = [...received.to, ...((received.cc ?? []) as unknown[])]\n .map(address)\n if (recipients.some(item => !item)) return invalid('Resend recipient address is invalid')\n const attachments = Array.isArray(received.attachments) ? received.attachments : []\n if (attachments.length > 50 || attachments.some(item => !record(item) || typeof item.id !== 'string')) {\n return invalid('Resend attachments require provider ids')\n }\n const sender = address(received.from)!\n const event: ConversationEvent = {\n version: 1, provider: 'resend', eventType: input.type, operation: 'created',\n eventId: data.email_id, conversationId: data.email_id, parentEventIds: [],\n sender: { id: sender, address: sender, displayName: null, verificationStatus: 'unverified' },\n destinations: recipients.map(destination => ({ kind: 'mailbox', id: destination, address: destination, displayName: null })),\n subject: typeof received.subject === 'string' ? received.subject.slice(0, 998) : null,\n text: typeof received.text === 'string' ? received.text : null,\n html: null,\n attachments: attachments.map(item => {\n const value = item as Record<string, unknown>\n return { id: value.id as string, name: typeof value.filename === 'string' ? value.filename : null,\n contentType: typeof value.content_type === 'string' ? value.content_type : null,\n size: null, contentBase64: null, url: null }\n }),\n occurredAt: Date.parse(received.created_at), transport: 'email',\n historyOnly: typeof received.text !== 'string' || recipients.length !== 1,\n }\n return { ok: true, event }\n}\n","import type { ConversationAttachment, ConversationEventNormalizationResult, ProviderConversationEvent } from './index.js'\n\nfunction object(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\nfunction integer(value: unknown, positive = true): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value) && (positive ? value > 0 : value !== 0)\n}\nconst invalid = (message: string): ConversationEventNormalizationResult => ({ ok: false, code: 'invalid_payload', message })\n\n/** Parse only new human messages. The verified webhook proves origin; the host\n * must still check live bot membership and the sender's authority before acting.\n * Addresses include chat, forum topic and sender to prevent session reuse across\n * groups, topics or people. Anonymous/channel senders cannot acquire user rights. */\nexport function normalizeTelegramConversation(input: ProviderConversationEvent): ConversationEventNormalizationResult {\n if (input.type !== 'telegram.message') return { ok: false, code: 'unsupported_event', message: 'Not a new Telegram message' }\n const envelope = input.payload\n if (!object(envelope) || !Number.isSafeInteger(envelope.update_id)\n || (envelope.update_id as number) < 0 || !object(envelope.message)) {\n return invalid('Telegram requires an update id and message')\n }\n const message = envelope.message\n const chat = message.chat\n const from = message.from\n if (!object(chat) || !object(from) || !integer(chat.id, false) || !integer(from.id)\n || from.is_bot !== false || message.sender_chat !== undefined || !integer(message.message_id)\n || !integer(message.date) || !Number.isSafeInteger(message.date * 1000)\n || !['private', 'group', 'supergroup'].includes(String(chat.type))\n || (chat.type === 'private' ? chat.id !== from.id : chat.id >= 0)) {\n return invalid('Telegram requires a human sender and supported chat identity')\n }\n const topic = message.message_thread_id\n if (topic !== undefined && (!integer(topic) || chat.type !== 'supergroup')) return invalid('Invalid Telegram topic')\n const text = message.text ?? message.caption ?? ''\n if (typeof text !== 'string' || text.length > 4096 || text.includes('\\0')) return invalid('Invalid Telegram message text')\n const media: unknown[] = []\n if (message.photo !== undefined) {\n if (!Array.isArray(message.photo) || message.photo.length === 0 || message.photo.length > 20) return invalid('Invalid Telegram photo')\n media.push(message.photo[message.photo.length - 1])\n }\n for (const kind of ['document', 'audio', 'voice', 'video', 'video_note', 'animation', 'sticker']) {\n if (message[kind] !== undefined) media.push(message[kind])\n }\n const attachments: ConversationAttachment[] = []\n for (const file of media) {\n if (!object(file) || typeof file.file_id !== 'string' || !/^[A-Za-z0-9_-]{1,512}$/.test(file.file_id)\n || (file.file_size !== undefined && (!Number.isSafeInteger(file.file_size) || (file.file_size as number) < 0))) {\n return invalid('Invalid Telegram attachment')\n }\n attachments.push({ id: file.file_id, name: typeof file.file_name === 'string' ? file.file_name.slice(0, 255) : null,\n contentType: typeof file.mime_type === 'string' ? file.mime_type.slice(0, 200) : null,\n size: typeof file.file_size === 'number' ? file.file_size : null, contentBase64: null, url: null })\n }\n if (!text.trim() && attachments.length === 0) return { ok: false, code: 'unsupported_event', message: 'No message content' }\n return { ok: true, event: {\n version: 1, provider: 'telegram', eventType: input.type, operation: 'created',\n eventId: `${chat.id}:${message.message_id}`, conversationId: String(chat.id),\n parentEventIds: object(message.reply_to_message) && integer(message.reply_to_message.message_id)\n ? [`${chat.id}:${message.reply_to_message.message_id}`] : [],\n sender: { id: String(from.id), address: `telegram:${chat.id}:${topic ?? 0}:${from.id}`,\n displayName: typeof from.first_name === 'string' ? from.first_name.slice(0, 100) : null },\n destinations: [{ kind: 'chat', id: String(chat.id), address: `telegram:${chat.id}`, displayName: null }],\n subject: null, text, html: null, attachments, occurredAt: message.date * 1000,\n transport: 'telegram', isGroup: chat.type !== 'private', historyOnly: false,\n } }\n}\n","import { normalizeConversationEvent, type ConversationEventNormalizationResult, type ProviderConversationEvent } from './index.js'\n\nexport interface ConversationReply {\n /** Qualified existing Hub action. The host supplies the bound connection. */\n action: string\n input: Record<string, unknown>\n /** Pass as the invocation's idempotency key, unchanged on every retry of this reply. */\n idempotencyKey: string\n}\n\nexport interface ConversationMediaReplyDescriptor {\n /** HTTPS location of one authorized media asset, using a DNS host rather than a direct IP. */\n url: string\n}\n\ntype Failure = Exclude<ConversationEventNormalizationResult, { ok: true }>\nfunction object(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : {}\n}\nconst fail = (message: string): Failure => ({ ok: false, code: 'invalid_payload', message })\nconst validOperationId = (value: unknown): value is string =>\n typeof value === 'string' && value.length > 0 && value.length <= 255 && /^[\\x21-\\x7e]+$/.test(value)\nfunction validMediaHost(host: string): boolean {\n if (host.length > 253 || host.endsWith('.local') || host.endsWith('.localhost')\n || host.startsWith('[') || /^\\d+(?:\\.\\d+){3}$/.test(host)) return false\n const labels = host.split('.')\n return labels.length >= 2 && labels.every((label) => label.length <= 63\n && /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(label))\n}\nfunction validMediaUrl(value: unknown): value is string {\n if (typeof value !== 'string' || !value.startsWith('https://') || value.length > 2048\n || /[\\u0000-\\u0020\\u007f]/.test(value)) return false\n try {\n const url = new URL(value)\n return validMediaHost(url.hostname.toLowerCase()) && !url.username && !url.password && !url.hash\n } catch {\n return false\n }\n}\n// Optional threading forwards only dot-atom IDs with DNS-style domains; other valid legacy forms are omitted.\nconst messageIdDotAtom = /^[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+)*$/\nconst messageIdDomainLabel = /^[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?$/\nfunction rfcMessageId(value: unknown): string | null {\n if (typeof value !== 'string' || value.length > 256 || !value.startsWith('<') || !value.endsWith('>')) return null\n const parts = value.slice(1, -1).split('@')\n if (parts.length !== 2 || !messageIdDotAtom.test(parts[0]!)) return null\n const labels = parts[1]!.split('.')\n return labels.every((label) => label.length <= 63 && messageIdDomainLabel.test(label)) ? value : null\n}\n\n/**\n * Derive a plain-text reply from a previously authenticated, stored event.\n * No model-selected recipient, sender, fallback channel or credential.\n * This is routing, not permission: recheck the bound connection and current\n * grant, persist the outbox key/body, then invoke through the existing Hub SDK.\n */\nexport function buildMessagingReply(\n input: ProviderConversationEvent,\n text: string,\n operationId: string,\n): { ok: true; reply: ConversationReply } | Failure {\n const normalized = normalizeConversationEvent(input)\n if (!normalized.ok) return normalized\n const event = normalized.event\n if (typeof text !== 'string' || !text.trim() || text.length > 10000 || text.includes('\\0')) return fail('Reply text is empty or exceeds its limit')\n if (!validOperationId(operationId)) return fail('A stable operation id is required')\n if (event.historyOnly || (event.isGroup && event.provider !== 'telegram')) return fail('This event requires review or complete input before a reply')\n if (event.provider === 'telegram') {\n if (text.length > 4096) return fail('Telegram text is limited to 4096 characters')\n const message = object(object(input.payload).message)\n return { ok: true, reply: { idempotencyKey: operationId, action: 'telegram.sendMessage', input: {\n chat_id: event.conversationId,\n text,\n reply_parameters: { message_id: message.message_id, allow_sending_without_reply: true },\n ...(message.message_thread_id === undefined ? {} : { message_thread_id: message.message_thread_id }),\n } } }\n }\n const data = object(object(input.payload).data)\n if (event.provider === 'inkbox') {\n if (event.eventType === 'inkbox.imessage.received') {\n return { ok: true, reply: { idempotencyKey: operationId, action: 'inkbox.imessage.reply', input: { conversation_id: event.conversationId, text } } }\n }\n if (event.eventType === 'inkbox.text.received') {\n const message = object(data.text_message)\n if (typeof message.phone_number_id !== 'string' || !message.phone_number_id || text.length > 1600) return fail('SMS requires its owned phone id and at most 1600 characters')\n return { ok: true, reply: { idempotencyKey: operationId, action: 'inkbox.sms.reply', input: { phone_number_id: message.phone_number_id, conversation_id: event.conversationId, text } } }\n }\n if (event.eventType === 'inkbox.message.received') {\n const message = object(data.message)\n if (!event.sender.address || typeof message.email_address !== 'string') return fail('Mail reply requires an explicit sender and mailbox')\n const subject = event.subject ?? ''\n const messageId = rfcMessageId(message.message_id)\n return { ok: true, reply: { idempotencyKey: operationId, action: 'inkbox.email.send', input: {\n email_address: message.email_address, to: [event.sender.address],\n subject: /^re:/i.test(subject) ? subject : `Re: ${subject}`.slice(0, 998), text,\n ...(messageId ? { in_reply_to_message_id: messageId } : {}),\n } } }\n }\n }\n if (event.provider === 'linq-whatsapp') {\n if (text.length > 4096) return fail('WhatsApp text is limited to 4096 characters')\n return { ok: true, reply: { idempotencyKey: operationId, action: 'linq-whatsapp.messages.reply', input: { chat_id: event.conversationId, text } } }\n }\n if (event.provider === 'linq') {\n return { ok: true, reply: { idempotencyKey: operationId, action: 'linq.messages.reply', input: { chat_id: event.conversationId, text, message_key: operationId } } }\n }\n if (event.provider === 'resend') {\n const received = object(object(input.payload).received)\n if (!event.sender.address || !event.destinations[0]?.address) {\n return fail('Resend reply requires the authenticated mailbox and sender')\n }\n const subject = event.subject ?? 'Message'\n if (/[\\u0000-\\u001f\\u007f]/.test(subject)) return fail('Email subject contains unsafe control characters')\n const parent = rfcMessageId(received.message_id)\n if (!parent) return fail('Resend reply requires a valid parent Message-ID')\n return { ok: true, reply: { idempotencyKey: operationId, action: 'resend.emails.reply', input: {\n from: event.destinations[0].address, to: [event.sender.address],\n subject: /^re:/i.test(subject) ? subject : `Re: ${subject}`.slice(0, 998), text,\n message_key: operationId, in_reply_to: parent,\n } } }\n }\n if (event.provider === 'contiguity') {\n return { ok: true, reply: { idempotencyKey: operationId, action: event.eventType === 'contiguity.imessage.incoming' ? 'contiguity.messages.send_imessage' : 'contiguity.sms.send',\n input: { to: event.sender.address, from: event.destinations[0]?.address, message: text } } }\n }\n if (event.provider === 'sendblue') {\n if (!event.sender.address || !event.destinations[0]?.address) return fail('Sendblue reply requires the contact and owned line')\n return { ok: true, reply: { idempotencyKey: operationId, action: 'sendblue.messages.send',\n input: { from_number: event.destinations[0].address, number: event.sender.address, content: text } } }\n }\n if (event.provider === 'twilio-sms') {\n if (text.length > 1600 || !event.sender.address || !event.destinations[0]?.address) {\n return fail('Twilio SMS reply requires two phone numbers and at most 1600 characters')\n }\n return { ok: true, reply: { idempotencyKey: operationId, action: 'twilio-sms.send_sms',\n input: { from: event.destinations[0].address, to: event.sender.address, body: text } } }\n }\n return { ok: false, code: 'unsupported_provider', message: 'Use the existing channel-specific reply tool for this provider' }\n}\n\n/**\n * Plan one Linq media reply from a previously authenticated, stored inbound event.\n * The caller must authorize the media asset, bind the existing connection and grant,\n * and retain the same outbox key and body before every Hub invocation or retry.\n */\nexport function buildMessagingMediaReply(\n input: ProviderConversationEvent,\n media: ConversationMediaReplyDescriptor,\n operationId: string,\n): { ok: true; reply: ConversationReply } | Failure {\n const normalized = normalizeConversationEvent(input)\n if (!normalized.ok) return normalized\n const event = normalized.event\n if (event.provider !== 'linq') {\n return { ok: false, code: 'unsupported_provider', message: 'Media replies require a Linq inbound event' }\n }\n if (event.eventType !== 'linq.message.received' || event.historyOnly || event.isGroup\n || !event.conversationId || event.conversationId.length > 256) {\n return fail('Media reply requires a current one-to-one Linq conversation')\n }\n if (!validOperationId(operationId)) return fail('A stable operation id is required')\n const descriptor = object(media)\n const url = descriptor.url\n if (Object.keys(descriptor).length !== 1 || !validMediaUrl(url)) {\n return fail('Media reply requires one HTTPS URL with a DNS host and no credentials or fragment')\n }\n return { ok: true, reply: {\n idempotencyKey: operationId,\n action: 'linq.messages.media.reply',\n input: { chat_id: event.conversationId, url, message_key: operationId },\n } }\n}\n","/** Protocol metadata, not a claim that a deployment or account is configured. */\nexport interface ConversationChannel {\n providerId: string\n eventType: string\n label: string\n transport: 'email' | 'imessage' | 'sms' | 'rcs' | 'whatsapp' | 'telegram'\n sourceKind: 'channel' | 'connection'\n replies: boolean\n inventoryAction?: string\n replyAction?: string\n reactionAction?: string\n typingAction?: string\n readReceiptAction?: string\n numberProvisioning?: 'provider-assigned'\n}\n\nconst channels: readonly ConversationChannel[] = [\n { providerId: 'telegram', eventType: 'telegram.message', label: 'Telegram', transport: 'telegram', sourceKind: 'connection', replies: true, replyAction: 'telegram.sendMessage' },\n { providerId: 'email', eventType: 'email.received', label: 'Tangle email', transport: 'email', sourceKind: 'channel', replies: false },\n { providerId: 'inkbox', eventType: 'inkbox.imessage.received', label: 'iMessage', transport: 'imessage', sourceKind: 'connection', replies: true, replyAction: 'inkbox.imessage.reply',\n reactionAction: 'inkbox.imessage.react', typingAction: 'inkbox.imessage.typing', readReceiptAction: 'inkbox.imessage.read_receipt' },\n { providerId: 'inkbox', eventType: 'inkbox.text.received', label: 'SMS', transport: 'sms', sourceKind: 'connection', replies: true, replyAction: 'inkbox.sms.reply' },\n { providerId: 'inkbox', eventType: 'inkbox.message.received', label: 'Email', transport: 'email', sourceKind: 'connection', replies: true, replyAction: 'inkbox.email.send' },\n { providerId: 'linq', eventType: 'linq.message.received', label: 'iMessage', transport: 'imessage', sourceKind: 'connection', replies: true, inventoryAction: 'linq.numbers.list', replyAction: 'linq.messages.reply',\n reactionAction: 'linq.messages.react', typingAction: 'linq.chats.typing', readReceiptAction: 'linq.chats.read_receipt', numberProvisioning: 'provider-assigned' },\n { providerId: 'linq', eventType: 'linq.message.received', label: 'SMS', transport: 'sms', sourceKind: 'connection', replies: true, inventoryAction: 'linq.numbers.list', replyAction: 'linq.messages.reply', numberProvisioning: 'provider-assigned' },\n { providerId: 'linq', eventType: 'linq.message.received', label: 'RCS', transport: 'rcs', sourceKind: 'connection', replies: true, inventoryAction: 'linq.numbers.list', replyAction: 'linq.messages.reply', numberProvisioning: 'provider-assigned' },\n { providerId: 'contiguity', eventType: 'contiguity.imessage.incoming', label: 'iMessage', transport: 'imessage', sourceKind: 'connection', replies: true, replyAction: 'contiguity.messages.send_imessage',\n typingAction: 'contiguity.imessage.typing', readReceiptAction: 'contiguity.imessage.read_receipt' },\n { providerId: 'contiguity', eventType: 'contiguity.text.incoming.sms', label: 'SMS', transport: 'sms', sourceKind: 'connection', replies: true, replyAction: 'contiguity.sms.send' },\n { providerId: 'linq-whatsapp', eventType: 'linq-whatsapp.message.received', label: 'WhatsApp', transport: 'whatsapp', sourceKind: 'connection', replies: true, inventoryAction: 'linq-whatsapp.numbers.list', replyAction: 'linq-whatsapp.messages.reply',\n reactionAction: 'linq-whatsapp.messages.react', readReceiptAction: 'linq-whatsapp.chats.read_receipt' },\n { providerId: 'resend', eventType: 'resend.email.received', label: 'Email', transport: 'email', sourceKind: 'connection', replies: true, replyAction: 'resend.emails.reply' },\n { providerId: 'sendblue', eventType: 'sendblue.message.received', label: 'iMessage', transport: 'imessage', sourceKind: 'connection', replies: true, inventoryAction: 'sendblue.lines.state', replyAction: 'sendblue.messages.send',\n reactionAction: 'sendblue.messages.react', typingAction: 'sendblue.typing.send', readReceiptAction: 'sendblue.read_receipts.send' },\n { providerId: 'sendblue', eventType: 'sendblue.message.received', label: 'SMS', transport: 'sms', sourceKind: 'connection', replies: true, inventoryAction: 'sendblue.lines.state', replyAction: 'sendblue.messages.send' },\n { providerId: 'sendblue', eventType: 'sendblue.message.received', label: 'RCS', transport: 'rcs', sourceKind: 'connection', replies: true, inventoryAction: 'sendblue.lines.state', replyAction: 'sendblue.messages.send' },\n { providerId: 'twilio-sms', eventType: 'twilio-sms.message.received', label: 'SMS / MMS', transport: 'sms', sourceKind: 'connection', replies: true, inventoryAction: 'twilio-sms.list_numbers', replyAction: 'twilio-sms.send_sms' },\n]\n\n/** Fresh copies let applications filter by their live Hub catalog without mutating ours. */\nexport function listConversationChannels(): ConversationChannel[] {\n return channels.map(channel => ({ ...channel }))\n}\n\nexport interface ConversationEndpointOption {\n id: string\n /** Provider display address. Use id, not a reformatted address, to select a resource. */\n address: string\n providerId: string\n channel: 'imessage' | 'sms' | 'whatsapp'\n health: 'healthy' | 'at-risk' | 'critical' | 'unknown'\n}\nfunction record(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\nfunction bounded(value: unknown, max: number): value is string {\n return typeof value === 'string' && value.trim().length > 0 && value.length <= max && !/[\\u0000-\\u001f\\u007f]/.test(value)\n}\n/** Project an authenticated provider-owned inventory response, not user input.\n * Protocol shapes stay with the adapters. Unknown provider health remains unknown;\n * configuration, customer eligibility and delivery readiness are separate facts. */\nexport function conversationEndpointOptions(providerId: string, result: unknown): ConversationEndpointOption[] {\n if (providerId === 'sendblue') {\n const rows = record(result) ? result.data : null\n if (!Array.isArray(rows) || rows.length > 1000) throw new Error('Invalid Sendblue line-state inventory')\n const seen = new Set<string>()\n return rows.map(row => {\n if (!record(row) || !bounded(row.sendblue_number, 16)\n || !/^\\+[1-9]\\d{6,14}$/.test(row.sendblue_number) || seen.has(row.sendblue_number)) {\n throw new Error('Invalid or ambiguous Sendblue line identity')\n }\n seen.add(row.sendblue_number)\n const health: ConversationEndpointOption['health'] = row.status === 'ONLINE' ? 'healthy'\n : row.status === 'DEGRADED' ? 'at-risk' : row.status === 'OFFLINE' ? 'critical' : 'unknown'\n return { id: row.sendblue_number, address: row.sendblue_number,\n providerId, channel: 'imessage' as const, health }\n })\n }\n if (providerId === 'twilio-sms') {\n const rows = record(result) ? result.numbers : null\n if (!Array.isArray(rows) || rows.length > 1000 || (record(result) && result.nextPageUri)) {\n throw new Error('Twilio phone inventory is missing or incomplete')\n }\n const ids = new Set<string>(), addresses = new Set<string>()\n return rows.filter(row => {\n if (!record(row) || !record(row.capabilities) || typeof row.capabilities.sms !== 'boolean') {\n throw new Error('Invalid Twilio phone capability row')\n }\n return row.capabilities.sms\n }).map(row => {\n if (!bounded(row.sid, 34) || !/^PN[a-f0-9]{32}$/i.test(row.sid)\n || !bounded(row.phone_number, 16) || !/^\\+[1-9]\\d{6,14}$/.test(row.phone_number)\n || ids.has(row.sid) || addresses.has(row.phone_number)) {\n throw new Error('Invalid or ambiguous Twilio SMS number identity')\n }\n ids.add(row.sid); addresses.add(row.phone_number)\n return { id: row.sid, address: row.phone_number,\n providerId, channel: 'sms' as const, health: 'unknown' as const }\n })\n }\n if (providerId !== 'linq' && providerId !== 'linq-whatsapp') throw new Error('Owned endpoint enumeration is not available for this provider')\n const whatsapp = providerId === 'linq-whatsapp'\n const values = record(result) ? result[whatsapp ? 'data' : 'phone_numbers'] : null\n if (!Array.isArray(values)) throw new Error('Provider did not return its owned phone-number inventory')\n if (values.length > 1000) throw new Error('Phone inventory exceeds the supported response limit')\n const ids = new Set<string>(), addresses = new Set<string>()\n return values.map(value => {\n if (!record(value)) throw new Error('Invalid phone inventory row')\n const { id, phone_number: address } = value\n if (!bounded(id, 256) || !bounded(address, 320) || ids.has(id) || addresses.has(address)) {\n throw new Error('Invalid or ambiguous owned phone-number identity')\n }\n if (!whatsapp && (!/^[a-f0-9]{8}-(?:[a-f0-9]{4}-){3}[a-f0-9]{12}$/i.test(id) || !/^\\+[1-9]\\d{6,14}$/.test(address))) {\n throw new Error('Invalid or ambiguous owned phone-number identity')\n }\n ids.add(id); addresses.add(address)\n const status = whatsapp ? value.quality_band : record(value.reputation) ? value.reputation.status : undefined\n // WhatsApp raw quality values evolve. Only its documented quality_band is classified.\n const health: ConversationEndpointOption['health'] = status === (whatsapp ? 'green' : 'HEALTHY') ? 'healthy'\n : status === (whatsapp ? 'yellow' : 'AT_RISK') ? 'at-risk'\n : status === (whatsapp ? 'red' : 'CRITICAL') ? 'critical' : 'unknown'\n return { id, address, providerId, channel: whatsapp ? 'whatsapp' as const : 'imessage' as const, health }\n })\n}\n","import { normalizeConversationEvent, type ConversationEventNormalizationResult, type ProviderConversationEvent } from './index.js'\nimport { listConversationChannels } from './channels.js'\n\nexport type ConversationReaction = 'like' | 'love' | 'laugh' | 'emphasize' | 'question' | 'dislike'\nconst whatsappEmoji: Record<ConversationReaction, string> = {\n like: '👍', love: '❤️', laugh: '😂', emphasize: '‼️', question: '❓', dislike: '👎',\n}\n\nexport interface ConversationPresenceCapabilities {\n reaction: boolean\n typing: boolean\n readReceipt: boolean\n}\n\n/** An action plan only. The host rechecks line and connection authority before invoking it. */\nexport interface ConversationPresenceAction {\n action: string\n input: Record<string, unknown>\n idempotencyKey: string\n}\n\ntype Failure = Exclude<ConversationEventNormalizationResult, { ok: true }>\ntype Result = { ok: true; plan: ConversationPresenceAction } | Failure\nconst unsupported = (message: string): Failure => ({ ok: false, code: 'unsupported_event', message })\nconst invalid = (message: string): Failure => ({ ok: false, code: 'invalid_payload', message })\nconst none = (): ConversationPresenceCapabilities => ({ reaction: false, typing: false, readReceipt: false })\n\nfunction eligible(input: ProviderConversationEvent) {\n const normalized = normalizeConversationEvent(input)\n if (!normalized.ok) return normalized\n const event = normalized.event\n if (event.historyOnly || event.isGroup || !event.transport) return unsupported('Presence requires a current one-to-one message with a known transport')\n const channel = listConversationChannels().find(row => row.providerId === event.provider\n && row.eventType === event.eventType && row.transport === event.transport)\n if (!channel) return unsupported('No presence actions are available for this channel')\n return { ok: true as const, event, channel }\n}\n\nfunction operation(value: string): boolean {\n return typeof value === 'string' && value.length > 0 && value.length <= 255 && /^[\\x21-\\x7e]+$/.test(value)\n}\nfunction target(value: string | null): value is string {\n return typeof value === 'string' && value.length > 0 && value.length <= 256 && !/[\\u0000-\\u001f\\u007f]/.test(value)\n}\nfunction phone(value: string | null): value is string {\n return typeof value === 'string' && /^\\+[1-9]\\d{6,14}$/.test(value)\n}\nfunction routedPhones(event: { sender: { address: string | null }; destinations: { address: string | null }[] }) {\n const to = event.sender.address, from = event.destinations[0]?.address ?? null\n return phone(to) && phone(from) && to !== from ? { to, from } : null\n}\n\n/** Protocol support for this authenticated, stored inbound event; account readiness is checked by the host. */\nexport function conversationPresenceCapabilities(input: ProviderConversationEvent): ConversationPresenceCapabilities {\n const matched = eligible(input)\n if (!matched.ok) return none()\n if ((matched.event.provider === 'sendblue' || matched.event.provider === 'contiguity')\n && !routedPhones(matched.event)) return none()\n return {\n reaction: Boolean(matched.channel.reactionAction && target(matched.event.eventId)),\n typing: Boolean(matched.channel.typingAction && target(matched.event.conversationId)),\n readReceipt: Boolean(matched.channel.readReceiptAction && target(matched.event.conversationId)),\n }\n}\n\nfunction plan(input: ProviderConversationEvent, operationId: string, kind: 'reaction' | 'typing' | 'readReceipt', reaction?: ConversationReaction): Result {\n const matched = eligible(input)\n if (!matched.ok) return matched\n if (!operation(operationId)) return invalid('A stable bounded operation id is required')\n const { event, channel } = matched\n const action = kind === 'reaction' ? channel.reactionAction : kind === 'typing' ? channel.typingAction : channel.readReceiptAction\n if (!action) return unsupported('This channel does not support the requested presence action')\n if (kind === 'reaction' && (!reaction || !(['like', 'love', 'laugh', 'emphasize', 'question', 'dislike'] as string[]).includes(reaction))) {\n return invalid('Unsupported reaction')\n }\n if (event.provider === 'sendblue' || event.provider === 'contiguity') {\n const route = routedPhones(event)\n if (!route) return invalid('Presence requires an exact owned line and contact phone number')\n if (event.provider === 'contiguity') {\n if (kind === 'reaction') return unsupported('Contiguity reactions need an explicit, unambiguous text target')\n return { ok: true, plan: { action, idempotencyKey: operationId,\n input: kind === 'typing' ? { to: route.to, from: route.from, action: 'start' }\n : { to: route.to, from: route.from } } }\n }\n const args = kind === 'reaction'\n ? { from_number: route.from, message_handle: event.eventId, reaction }\n : kind === 'typing'\n ? { from_number: route.from, number: route.to, state: 'start' }\n : { from_number: route.from, number: route.to }\n if (kind === 'reaction' && !target(event.eventId)) return invalid('Provider message handle is missing or invalid')\n return { ok: true, plan: { action, input: args, idempotencyKey: operationId } }\n }\n const inputKey = kind === 'reaction' ? 'message_id' : event.provider === 'inkbox' ? 'conversation_id' : 'chat_id'\n const id = kind === 'reaction' ? event.eventId : event.conversationId\n if (!target(id)) return invalid('Provider message or conversation id is missing or invalid')\n const args: Record<string, unknown> = { [inputKey]: id }\n if (kind === 'reaction' && event.provider === 'linq-whatsapp') {\n if (!target(event.conversationId)) return invalid('WhatsApp chat id is missing or invalid')\n args.chat_id = event.conversationId\n }\n if (kind === 'reaction') {\n if (!reaction) return invalid('Unsupported reaction')\n if (event.provider === 'linq-whatsapp') args.emoji = whatsappEmoji[reaction]\n else args.reaction = reaction\n }\n return { ok: true, plan: { action, input: args, idempotencyKey: operationId } }\n}\n\nexport function buildConversationReaction(input: ProviderConversationEvent, reaction: ConversationReaction, operationId: string): Result {\n return plan(input, operationId, 'reaction', reaction)\n}\nexport function buildConversationTyping(input: ProviderConversationEvent, operationId: string): Result {\n return plan(input, operationId, 'typing')\n}\nexport function buildConversationReadReceipt(input: ProviderConversationEvent, operationId: string): Result {\n return plan(input, operationId, 'readReceipt')\n}\n","import {\n normalizeConversationEvent as normalizeExistingConversationEvent,\n type ConversationEvent as ExistingConversationEvent,\n type ConversationEventNormalizationResult as ExistingNormalizationResult,\n} from './core.js'\nimport { normalizeLinqWhatsappConversation } from './linq-whatsapp.js'\nimport { normalizeMobileConversation } from './mobile.js'\nimport { normalizeResendConversation } from './resend.js'\nimport { normalizeTelegramConversation } from './telegram.js'\n\nexport * from './core.js'\nexport { buildMessagingReply, buildMessagingMediaReply, type ConversationReply, type ConversationMediaReplyDescriptor } from './reply.js'\nexport { listConversationChannels, conversationEndpointOptions, type ConversationChannel, type ConversationEndpointOption } from './channels.js'\nexport { conversationPresenceCapabilities, buildConversationReaction, buildConversationTyping, buildConversationReadReceipt,\n type ConversationReaction, type ConversationPresenceCapabilities, type ConversationPresenceAction } from './presence.js'\n\n/** Additive provider vocabulary. Neither sender identity nor group membership is authority. */\nexport interface ConversationEvent extends Omit<ExistingConversationEvent, 'provider'> {\n provider: ExistingConversationEvent['provider'] | 'inkbox' | 'linq' | 'contiguity' | 'linq-whatsapp' | 'resend' | 'sendblue' | 'twilio-sms' | 'telegram'\n /** Actual inbound protocol. Linq reports this per message, not per chat. */\n transport?: 'email' | 'imessage' | 'sms' | 'rcs' | 'whatsapp' | 'telegram'\n isGroup?: boolean\n /** Historical or incomplete input is not a new automatic command. */\n historyOnly?: boolean\n}\nexport type ConversationEventNormalizationResult =\n | { ok: true; event: ConversationEvent }\n | Exclude<ExistingNormalizationResult, { ok: true }>\n\nexport function normalizeConversationEvent(value: unknown): ConversationEventNormalizationResult {\n if (value && typeof value === 'object' && 'provider' in value\n && ['inkbox', 'linq', 'contiguity', 'linq-whatsapp', 'resend', 'sendblue', 'twilio-sms', 'telegram'].includes(String(value.provider))) {\n if (!('type' in value) || typeof value.type !== 'string' || !('payload' in value)) {\n return { ok: false, code: 'invalid_payload', message: 'Provider event requires type and payload' }\n }\n if (value.provider === 'telegram') return normalizeTelegramConversation({ provider: value.provider, type: value.type, payload: value.payload })\n if (value.provider === 'linq-whatsapp') return normalizeLinqWhatsappConversation({ provider: value.provider, type: value.type, payload: value.payload })\n if (value.provider === 'resend') return normalizeResendConversation({ provider: value.provider, type: value.type, payload: value.payload })\n return normalizeMobileConversation({ provider: String(value.provider), type: value.type, payload: value.payload })\n }\n return normalizeExistingConversationEvent(value)\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-integrations",
3
- "version": "0.67.0",
3
+ "version": "0.67.1",
4
4
  "description": "Vendor-neutral integration contracts and runtime helpers for sandbox and agent apps.",
5
5
  "homepage": "https://github.com/tangle-network/agent-integrations#readme",
6
6
  "repository": {