@canonmsg/backend-contracts 1.7.1 → 1.8.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.
Files changed (193) hide show
  1. package/dist/agentBehaviorPolicy.d.ts +86 -45
  2. package/dist/agentBehaviorPolicy.js +53 -0
  3. package/dist/bridgeLocal.d.ts +1729 -0
  4. package/dist/bridgeLocal.js +673 -0
  5. package/dist/cjs/agentBehaviorPolicy.js +54 -1
  6. package/dist/cjs/bridgeLocal.js +676 -0
  7. package/dist/cjs/contactRequest.js +30 -0
  8. package/dist/cjs/controlSignals.js +44 -0
  9. package/dist/cjs/endpointRegistry.js +264 -0
  10. package/dist/cjs/hitl.js +0 -0
  11. package/dist/cjs/inboundFrame.js +92 -0
  12. package/dist/cjs/index.js +8 -0
  13. package/dist/cjs/media.js +13 -0
  14. package/dist/cjs/message.js +64 -0
  15. package/dist/cjs/restEndpoints.js +237 -0
  16. package/dist/cjs/runtimeCardFields.js +58 -1
  17. package/dist/cjs/sendContextual.js +92 -0
  18. package/dist/cjs/sseEvents.js +298 -0
  19. package/dist/cjs/turnProtocol.js +41 -1
  20. package/dist/contactRequest.d.ts +42 -23
  21. package/dist/contactRequest.js +29 -0
  22. package/dist/controlSignals.d.ts +55 -0
  23. package/dist/controlSignals.js +41 -0
  24. package/dist/endpointRegistry.d.ts +13 -0
  25. package/dist/endpointRegistry.js +261 -0
  26. package/dist/hitl.d.ts +303 -0
  27. package/dist/hitl.js +168 -0
  28. package/dist/inboundFrame.d.ts +229 -0
  29. package/dist/inboundFrame.js +89 -0
  30. package/dist/index.d.ts +8 -0
  31. package/dist/index.js +8 -0
  32. package/dist/media.d.ts +24 -11
  33. package/dist/media.js +12 -0
  34. package/dist/message.d.ts +133 -50
  35. package/dist/message.js +64 -1
  36. package/dist/restEndpoints.d.ts +531 -0
  37. package/dist/restEndpoints.js +234 -0
  38. package/dist/runtimeCardFields.d.ts +112 -39
  39. package/dist/runtimeCardFields.js +57 -0
  40. package/dist/schemas/agent-behavior-settings-record.schema.json +48 -0
  41. package/dist/schemas/bridge-connection-state-notification.schema.json +19 -0
  42. package/dist/schemas/bridge-get-attachment-params.schema.json +24 -0
  43. package/dist/schemas/bridge-get-attachment-result.schema.json +20 -0
  44. package/dist/schemas/bridge-hello-params.schema.json +42 -0
  45. package/dist/schemas/bridge-hello-result.schema.json +105 -0
  46. package/dist/schemas/bridge-hitl-state.schema.json +38 -0
  47. package/dist/schemas/bridge-ok-result.schema.json +15 -0
  48. package/dist/schemas/bridge-ready-notification.schema.json +79 -0
  49. package/dist/schemas/bridge-resync-reason.schema.json +9 -0
  50. package/dist/schemas/bridge-resync.schema.json +18 -0
  51. package/dist/schemas/bridge-rpc-error.schema.json +19 -0
  52. package/dist/schemas/bridge-rpc-id.schema.json +12 -0
  53. package/dist/schemas/bridge-rpc-notification.schema.json +20 -0
  54. package/dist/schemas/bridge-rpc-request.schema.json +31 -0
  55. package/dist/schemas/bridge-rpc-response.schema.json +81 -0
  56. package/dist/schemas/bridge-status-result.schema.json +76 -0
  57. package/dist/schemas/bridge-upload-media-params.schema.json +28 -0
  58. package/dist/schemas/bridge-upstream-state.schema.json +10 -0
  59. package/dist/schemas/contacts-response.schema.json +52 -0
  60. package/dist/schemas/control-channel-key.schema.json +10 -0
  61. package/dist/schemas/control-primitive-event.schema.json +30 -0
  62. package/dist/schemas/control-primitive-map.schema.json +15 -0
  63. package/dist/schemas/control-session-event.schema.json +26 -0
  64. package/dist/schemas/control-session-node.schema.json +11 -0
  65. package/dist/schemas/control-signal-event.schema.json +35 -0
  66. package/dist/schemas/control-signal-node.schema.json +22 -0
  67. package/dist/schemas/control-signal-type.schema.json +10 -0
  68. package/dist/schemas/conversations-response.schema.json +167 -0
  69. package/dist/schemas/create-contact-request-request.schema.json +17 -0
  70. package/dist/schemas/create-contact-request-response.schema.json +51 -0
  71. package/dist/schemas/create-conversation-request.schema.json +82 -0
  72. package/dist/schemas/create-conversation-response.schema.json +29 -0
  73. package/dist/schemas/delete-message-response.schema.json +11 -0
  74. package/dist/schemas/delivery-intent.schema.json +11 -0
  75. package/dist/schemas/forward-message-request.schema.json +25 -0
  76. package/dist/schemas/forward-message-response.schema.json +35 -0
  77. package/dist/schemas/forwarded-from.schema.json +18 -0
  78. package/dist/schemas/get-messages-query.schema.json +17 -0
  79. package/dist/schemas/hitl-approval-category.schema.json +15 -0
  80. package/dist/schemas/hitl-approval-detail.schema.json +21 -0
  81. package/dist/schemas/hitl-approval-outcome-record.schema.json +33 -0
  82. package/dist/schemas/hitl-approval-reply-record.schema.json +57 -0
  83. package/dist/schemas/hitl-approval-request-record.schema.json +105 -0
  84. package/dist/schemas/hitl-approval-risk.schema.json +11 -0
  85. package/dist/schemas/hitl-card-outcome-record.schema.json +48 -0
  86. package/dist/schemas/hitl-card-reply-record.schema.json +46 -0
  87. package/dist/schemas/hitl-card-request-record.schema.json +73 -0
  88. package/dist/schemas/hitl-input-answers.schema.json +23 -0
  89. package/dist/schemas/hitl-input-kind.schema.json +10 -0
  90. package/dist/schemas/hitl-input-outcome-record.schema.json +46 -0
  91. package/dist/schemas/hitl-input-question.schema.json +54 -0
  92. package/dist/schemas/hitl-input-reply-record.schema.json +44 -0
  93. package/dist/schemas/hitl-input-request-record.schema.json +134 -0
  94. package/dist/schemas/hitl-pending.schema.json +31 -0
  95. package/dist/schemas/hitl-request-accepted.schema.json +18 -0
  96. package/dist/schemas/hitl-request-kind.schema.json +10 -0
  97. package/dist/schemas/hitl-resolution-status.schema.json +10 -0
  98. package/dist/schemas/hitl-resolution.schema.json +38 -0
  99. package/dist/schemas/hitl-session-rule.schema.json +32 -0
  100. package/dist/schemas/inbound-disposition.schema.json +13 -0
  101. package/dist/schemas/inbound-frame-attachment-v1.schema.json +94 -0
  102. package/dist/schemas/inbound-frame-contact-card-v1.schema.json +59 -0
  103. package/dist/schemas/inbound-frame-group-context-v1.schema.json +96 -0
  104. package/dist/schemas/inbound-frame-reply-context-v1.schema.json +261 -0
  105. package/dist/schemas/inbound-frame-shape-v1.schema.json +12 -0
  106. package/dist/schemas/inbound-frame-v1.schema.json +506 -0
  107. package/dist/schemas/mark-read-response.schema.json +11 -0
  108. package/dist/schemas/media-attachment-kind.schema.json +11 -0
  109. package/dist/schemas/media-attachment.schema.json +42 -0
  110. package/dist/schemas/messages-page-response.schema.json +290 -0
  111. package/dist/schemas/participation-decision-input.schema.json +44 -0
  112. package/dist/schemas/participation-history-message.schema.json +23 -0
  113. package/dist/schemas/participation-history-snapshot.schema.json +37 -0
  114. package/dist/schemas/participation-style.schema.json +13 -0
  115. package/dist/schemas/react-request.schema.json +22 -0
  116. package/dist/schemas/react-response.schema.json +35 -0
  117. package/dist/schemas/resolve-admission-request.schema.json +30 -0
  118. package/dist/schemas/resolve-admission-response.schema.json +129 -0
  119. package/dist/schemas/resolved-agent-behavior-policy-record.schema.json +81 -0
  120. package/dist/schemas/rest-contact.schema.json +40 -0
  121. package/dist/schemas/rest-conversation-last-message.schema.json +77 -0
  122. package/dist/schemas/rest-conversation.schema.json +155 -0
  123. package/dist/schemas/rest-message.schema.json +252 -0
  124. package/dist/schemas/rest-ok-response.schema.json +11 -0
  125. package/dist/schemas/rest-session-selection.schema.json +40 -0
  126. package/dist/schemas/runtime-card-field-choice.schema.json +23 -0
  127. package/dist/schemas/runtime-card-field-type.schema.json +17 -0
  128. package/dist/schemas/runtime-card-field.schema.json +180 -0
  129. package/dist/schemas/runtime-card-line-item-column-type.schema.json +12 -0
  130. package/dist/schemas/runtime-card-line-item-column.schema.json +74 -0
  131. package/dist/schemas/send-contextual-deferred-response.schema.json +39 -0
  132. package/dist/schemas/send-contextual-messaged-response.schema.json +42 -0
  133. package/dist/schemas/send-contextual-request.schema.json +103 -0
  134. package/dist/schemas/send-contextual-response.schema.json +105 -0
  135. package/dist/schemas/send-contextual-self-context.schema.json +19 -0
  136. package/dist/schemas/send-contextual-state-response.schema.json +24 -0
  137. package/dist/schemas/send-message-request.schema.json +106 -0
  138. package/dist/schemas/send-message-response.schema.json +14 -0
  139. package/dist/schemas/sender-type.schema.json +9 -0
  140. package/dist/schemas/serialize-message-input.schema.json +29 -0
  141. package/dist/schemas/serialized-agent-client-type.schema.json +12 -0
  142. package/dist/schemas/serialized-contact-card.schema.json +65 -0
  143. package/dist/schemas/serialized-contact-request-status.schema.json +11 -0
  144. package/dist/schemas/serialized-contact-request.schema.json +157 -0
  145. package/dist/schemas/serialized-content-type.schema.json +13 -0
  146. package/dist/schemas/serialized-message.schema.json +249 -0
  147. package/dist/schemas/serialized-reactions.schema.json +14 -0
  148. package/dist/schemas/serialized-sender-type.schema.json +9 -0
  149. package/dist/schemas/set-streaming-request.schema.json +67 -0
  150. package/dist/schemas/set-typing-request.schema.json +25 -0
  151. package/dist/schemas/sse-access-policy.schema.json +10 -0
  152. package/dist/schemas/sse-agent-context-payload.schema.json +57 -0
  153. package/dist/schemas/sse-connected-payload.schema.json +18 -0
  154. package/dist/schemas/sse-contact-payload.schema.json +40 -0
  155. package/dist/schemas/sse-contact-removed-payload.schema.json +14 -0
  156. package/dist/schemas/sse-contact-request-payload.schema.json +157 -0
  157. package/dist/schemas/sse-conversation-updated-payload.schema.json +48 -0
  158. package/dist/schemas/sse-error-payload.schema.json +23 -0
  159. package/dist/schemas/sse-event-envelope.schema.json +42 -0
  160. package/dist/schemas/sse-event-family.schema.json +12 -0
  161. package/dist/schemas/sse-event-type.schema.json +28 -0
  162. package/dist/schemas/sse-heartbeat-payload.schema.json +14 -0
  163. package/dist/schemas/sse-membership-change.schema.json +28 -0
  164. package/dist/schemas/sse-message-created-payload.schema.json +414 -0
  165. package/dist/schemas/sse-message-deleted-payload.schema.json +18 -0
  166. package/dist/schemas/sse-message-updated-payload.schema.json +46 -0
  167. package/dist/schemas/sse-presence-payload.schema.json +21 -0
  168. package/dist/schemas/sse-provenance.schema.json +64 -0
  169. package/dist/schemas/sse-replay-expired-payload.schema.json +21 -0
  170. package/dist/schemas/sse-runtime-control-kind.schema.json +13 -0
  171. package/dist/schemas/sse-runtime-control-payload.schema.json +44 -0
  172. package/dist/schemas/sse-runtime-updated-payload.schema.json +78 -0
  173. package/dist/schemas/sse-self-context.schema.json +45 -0
  174. package/dist/schemas/sse-turn-dispatch.schema.json +29 -0
  175. package/dist/schemas/sse-turn-updated-payload.schema.json +33 -0
  176. package/dist/schemas/sse-typing-payload.schema.json +32 -0
  177. package/dist/schemas/sse-voice-session-event-payload.schema.json +170 -0
  178. package/dist/schemas/sse-voice-session.schema.json +157 -0
  179. package/dist/schemas/trigger-decision.schema.json +27 -0
  180. package/dist/schemas/turn-lifecycle-state.schema.json +14 -0
  181. package/dist/schemas/turn-message-semantics.schema.json +10 -0
  182. package/dist/schemas/turn-metadata.schema.json +56 -0
  183. package/dist/schemas/turn-state-like.schema.json +39 -0
  184. package/dist/schemas/update-disposition-request.schema.json +22 -0
  185. package/dist/schemas/upload-media-request.schema.json +25 -0
  186. package/dist/schemas/upload-media-response.schema.json +55 -0
  187. package/dist/sendContextual.d.ts +114 -0
  188. package/dist/sendContextual.js +89 -0
  189. package/dist/sseEvents.d.ts +494 -0
  190. package/dist/sseEvents.js +295 -0
  191. package/dist/turnProtocol.d.ts +91 -24
  192. package/dist/turnProtocol.js +40 -0
  193. package/package.json +8 -5
@@ -0,0 +1,234 @@
1
+ // Wire contract v1 — request/response schemas for the agent-facing "Canon op"
2
+ // REST surface the bridge proxies (bridge-local-api.md §B).
3
+ //
4
+ // Grounded in the Functions handlers (functions/src/api/*) and the canonical
5
+ // consumer (@canonmsg/core CanonClient) — request bodies mirror what clients
6
+ // send today, response schemas mirror what the handlers emit. This is a
7
+ // re-expression of current behavior, not a redesign.
8
+ import { z } from 'zod';
9
+ import { MediaAttachmentSchema } from './media.js';
10
+ import { SerializedContentTypeSchema, SerializedMessageSchema, SerializedReactionsSchema, } from './message.js';
11
+ import { InboundDispositionSchema } from './turnProtocol.js';
12
+ // ── Shared fragments ───────────────────────────────────────────────────
13
+ export const RestOkResponseSchema = z.looseObject({
14
+ success: z.boolean().optional(),
15
+ });
16
+ /** GET …/messages items — the serialized message plus the soft-delete flag. */
17
+ export const RestMessageSchema = SerializedMessageSchema.extend({
18
+ deleted: z.boolean().optional(),
19
+ });
20
+ /**
21
+ * STRICT WRITES, TOLERANT READS: this is a READ schema over live production
22
+ * data, so it must describe what Firestore actually holds — not what today's
23
+ * writers produce. The GET /conversations serializer
24
+ * (functions/src/api/getConversations.ts) passes `lastMessage` fields through
25
+ * from the conversation doc, and legacy rows (pre-refactor writes,
26
+ * deleted-message repair) hold explicit nulls:
27
+ * - `text` is serialized `?? null` and `timestamp` as
28
+ * `?.toDate?.()?.toISOString() ?? null` — both emit null by construction.
29
+ * - `senderId` / `senderType` / `contentType` are raw pass-throughs; live
30
+ * rows exist with all three null (the getConversations "ghost fix" comment
31
+ * acknowledges null senderId).
32
+ * - conversation `createdAt` is also serialized `?? null`.
33
+ * Writers (onMessageCreated / deletedMessageRepair) stay strict — they always
34
+ * produce the full shape; only the read contract admits the legacy nulls.
35
+ */
36
+ export const RestConversationLastMessageSchema = z.looseObject({
37
+ text: z.string().nullable(),
38
+ messageId: z.string().optional(),
39
+ senderId: z.string().nullable().optional(),
40
+ senderType: z.enum(['human', 'ai_agent']).nullable().optional(),
41
+ contentType: SerializedContentTypeSchema.nullable().optional(),
42
+ timestamp: z.string().nullable(),
43
+ });
44
+ export const RestConversationSchema = z.looseObject({
45
+ id: z.string(),
46
+ type: z.enum(['direct', 'group']),
47
+ name: z.string().nullable().optional(),
48
+ topic: z.string().nullable().optional(),
49
+ memberIds: z.array(z.string()),
50
+ isAgentChat: z.boolean().optional(),
51
+ /** Resolved agent behavior policy — opaque pass-through. */
52
+ behavior: z.record(z.string(), z.unknown()).optional(),
53
+ hasUnread: z.boolean().optional(),
54
+ lastMessage: RestConversationLastMessageSchema.nullable(),
55
+ createdAt: z.string().nullable().optional(),
56
+ });
57
+ export const RestContactSchema = z.object({
58
+ id: z.string(),
59
+ source: z.string(),
60
+ addedAt: z.string().nullable(),
61
+ displayNameOverride: z.string().nullable(),
62
+ });
63
+ export const RestSessionSelectionSchema = z.union([
64
+ z.object({ mode: z.enum(['new', 'continue_latest', 'continue_or_create']) }),
65
+ z.object({ mode: z.literal('specific'), conversationId: z.string() }),
66
+ ]);
67
+ // ── POST /messages/send ────────────────────────────────────────────────
68
+ export const SendMessageRequestSchema = z.object({
69
+ conversationId: z.string(),
70
+ text: z.string().optional(),
71
+ /** Client-supplied idempotency id. */
72
+ messageId: z.string().optional(),
73
+ contentType: SerializedContentTypeSchema.optional(),
74
+ replyTo: z.string().optional(),
75
+ replyToPosition: z.number().optional(),
76
+ attachments: z.array(MediaAttachmentSchema).optional(),
77
+ contactCardUserId: z.string().optional(),
78
+ mentions: z.array(z.string()).optional(),
79
+ selfContextId: z.string().nullable().optional(),
80
+ /** Structured metadata (turn protocol, approval cards, …). */
81
+ metadata: z.record(z.string(), z.unknown()).optional(),
82
+ });
83
+ export const SendMessageResponseSchema = z.object({
84
+ messageId: z.string(),
85
+ });
86
+ // ── POST /messages/react ───────────────────────────────────────────────
87
+ export const ReactRequestSchema = z.object({
88
+ conversationId: z.string(),
89
+ messageId: z.string(),
90
+ emoji: z.string(),
91
+ });
92
+ export const ReactResponseSchema = z.object({
93
+ success: z.boolean(),
94
+ action: z.enum(['added', 'removed']),
95
+ reactions: SerializedReactionsSchema,
96
+ });
97
+ // ── POST /messages/forward ─────────────────────────────────────────────
98
+ export const ForwardMessageRequestSchema = z.object({
99
+ sourceConversationId: z.string(),
100
+ targetConversationId: z.string(),
101
+ messageId: z.string(),
102
+ text: z.string().optional(),
103
+ });
104
+ export const ForwardMessageResponseSchema = z.object({
105
+ messageId: z.string(),
106
+ targetConversationId: z.string(),
107
+ forwardedFrom: z.object({
108
+ sourceConversationId: z.string(),
109
+ messageId: z.string(),
110
+ }),
111
+ });
112
+ // ── DELETE /conversations/:id/messages/:id, POST …/read, PATCH …/disposition ──
113
+ export const DeleteMessageResponseSchema = RestOkResponseSchema;
114
+ export const MarkReadResponseSchema = RestOkResponseSchema;
115
+ export const UpdateDispositionRequestSchema = z.object({
116
+ inboundDisposition: InboundDispositionSchema,
117
+ });
118
+ // ── GET /conversations + GET …/messages ────────────────────────────────
119
+ export const ConversationsResponseSchema = z.object({
120
+ conversations: z.array(RestConversationSchema),
121
+ });
122
+ /** Query params: limit, before, includeBehavior. */
123
+ export const GetMessagesQuerySchema = z.object({
124
+ limit: z.string().optional(),
125
+ before: z.string().optional(),
126
+ includeBehavior: z.string().optional(),
127
+ });
128
+ export const MessagesPageResponseSchema = z.looseObject({
129
+ messages: z.array(RestMessageSchema),
130
+ /** Present with includeBehavior=1. */
131
+ behavior: z.record(z.string(), z.unknown()).optional(),
132
+ activeSelfContextIdByMessageId: z.record(z.string(), z.string()).optional(),
133
+ selfContexts: z.array(z.record(z.string(), z.unknown())).optional(),
134
+ });
135
+ // ── POST /conversations/create ─────────────────────────────────────────
136
+ export const CreateConversationRequestSchema = z.object({
137
+ type: z.enum(['direct', 'group']),
138
+ targetUserId: z.string().optional(),
139
+ memberIds: z.array(z.string()).optional(),
140
+ name: z.string().optional(),
141
+ /** Initial session config for first-party coding agents — opaque pass-through. */
142
+ sessionConfig: z.record(z.string(), z.unknown()).nullable().optional(),
143
+ sessionSelection: RestSessionSelectionSchema.optional(),
144
+ });
145
+ export const CreateConversationResponseSchema = z.object({
146
+ conversationId: z.string(),
147
+ created: z.boolean().optional(),
148
+ reused: z.boolean().optional(),
149
+ sessionSelection: z.enum(['new', 'continue_latest', 'continue_or_create', 'specific']).optional(),
150
+ });
151
+ // ── Contacts / admission ───────────────────────────────────────────────
152
+ export const CreateContactRequestRequestSchema = z.object({
153
+ targetId: z.string(),
154
+ message: z.string().optional(),
155
+ });
156
+ export const CreateContactRequestResponseSchema = z.union([
157
+ z.looseObject({ status: z.literal('open') }),
158
+ z.looseObject({ status: z.enum(['created', 'duplicate']), requestId: z.string() }),
159
+ /** Legacy "already a contact" body. */
160
+ z.looseObject({ message: z.string() }),
161
+ ]);
162
+ export const ContactsResponseSchema = z.object({
163
+ contacts: z.array(RestContactSchema),
164
+ });
165
+ export const ResolveAdmissionRequestSchema = z.union([
166
+ z.object({ targetUserId: z.string() }),
167
+ z.object({ canonContactId: z.string() }),
168
+ ]);
169
+ export const ResolveAdmissionResponseSchema = z.looseObject({
170
+ resolvedTargetUserId: z.string().nullable().optional(),
171
+ target: z.looseObject({
172
+ id: z.string(),
173
+ canonContactId: z.string().optional(),
174
+ displayName: z.string().optional(),
175
+ avatarUrl: z.string().nullable().optional(),
176
+ about: z.string().optional(),
177
+ userType: z.enum(['human', 'ai_agent']).optional(),
178
+ discoverable: z.boolean().optional(),
179
+ inboundPolicy: z.enum(['open', 'approval-required', 'owner-only']).optional(),
180
+ groupJoinPolicy: z.enum(['open', 'approval-required', 'owner-only']).optional(),
181
+ }).nullable(),
182
+ admission: z.looseObject({
183
+ state: z.enum([
184
+ 'self',
185
+ 'not-found',
186
+ 'allowed',
187
+ 'request-required',
188
+ 'pending-outbound',
189
+ 'blocked',
190
+ 'inactive',
191
+ 'owner-only',
192
+ ]),
193
+ canMessage: z.boolean(),
194
+ canRequestContact: z.boolean(),
195
+ isContact: z.boolean(),
196
+ pendingRequestId: z.string().optional(),
197
+ blockedByViewer: z.boolean().optional(),
198
+ blockedByTarget: z.boolean().optional(),
199
+ }),
200
+ });
201
+ // ── Typing / streaming ─────────────────────────────────────────────────
202
+ export const SetTypingRequestSchema = z.object({
203
+ conversationId: z.string(),
204
+ typing: z.boolean(),
205
+ status: z.enum(['thinking', 'typing']).optional(),
206
+ });
207
+ /** POST /streaming — the legacy REST facade over the RTDB streaming bubble. */
208
+ export const SetStreamingRequestSchema = z.union([
209
+ z.object({
210
+ conversationId: z.string(),
211
+ text: z.string(),
212
+ status: z.string(),
213
+ messageId: z.string(),
214
+ turnId: z.string().nullable().optional(),
215
+ /** TurnOutputBlock[] — opaque pass-through. */
216
+ blocks: z.array(z.record(z.string(), z.unknown())).optional(),
217
+ }),
218
+ z.object({
219
+ conversationId: z.string(),
220
+ streaming: z.literal(false),
221
+ }),
222
+ ]);
223
+ // ── Media upload ───────────────────────────────────────────────────────
224
+ export const UploadMediaRequestSchema = z.object({
225
+ conversationId: z.string(),
226
+ mimeType: z.string(),
227
+ /** Base64-encoded file content. */
228
+ data: z.string(),
229
+ fileName: z.string().optional(),
230
+ });
231
+ export const UploadMediaResponseSchema = z.object({
232
+ url: z.string(),
233
+ attachment: MediaAttachmentSchema,
234
+ });
@@ -1,4 +1,17 @@
1
- export type RuntimeCardFieldType = 'text' | 'textarea' | 'select' | 'multiSelect' | 'boolean' | 'date' | 'number' | 'currency' | 'searchSelect' | 'lineItems';
1
+ import { z } from 'zod';
2
+ export declare const RuntimeCardFieldTypeSchema: z.ZodEnum<{
3
+ number: "number";
4
+ boolean: "boolean";
5
+ date: "date";
6
+ text: "text";
7
+ textarea: "textarea";
8
+ select: "select";
9
+ multiSelect: "multiSelect";
10
+ currency: "currency";
11
+ searchSelect: "searchSelect";
12
+ lineItems: "lineItems";
13
+ }>;
14
+ export type RuntimeCardFieldType = z.infer<typeof RuntimeCardFieldTypeSchema>;
2
15
  /**
3
16
  * Caps shared across runtime-card normalizers, response validation, and
4
17
  * authoring tools. Keep these backend-safe so Functions can import them.
@@ -9,44 +22,104 @@ export declare const RUNTIME_CARD_LIMITS: {
9
22
  readonly lineItemColumns: 8;
10
23
  readonly searchSelectChoices: 100;
11
24
  };
12
- export interface RuntimeCardFieldChoice {
13
- label: string;
14
- value?: string;
15
- description?: string;
16
- preview?: string;
17
- }
18
- export type RuntimeCardLineItemColumnType = 'text' | 'number' | 'currency' | 'date' | 'select';
19
- export interface RuntimeCardLineItemColumn {
20
- id: string;
21
- label: string;
22
- type: RuntimeCardLineItemColumnType;
23
- required?: boolean;
24
- choices?: RuntimeCardFieldChoice[];
25
- min?: number;
26
- max?: number;
27
- step?: number;
28
- precision?: number;
29
- currencyCode?: string;
30
- allowOther?: boolean;
31
- }
32
- export interface RuntimeCardField {
33
- id: string;
34
- label: string;
35
- type: RuntimeCardFieldType;
36
- required?: boolean;
37
- placeholder?: string;
38
- choices?: RuntimeCardFieldChoice[];
39
- allowOther?: boolean;
40
- sensitive?: boolean;
41
- min?: number | string;
42
- max?: number | string;
43
- step?: number;
44
- precision?: number;
45
- currencyCode?: string;
46
- columns?: RuntimeCardLineItemColumn[];
47
- minRows?: number;
48
- maxRows?: number;
49
- }
25
+ export declare const RuntimeCardFieldChoiceSchema: z.ZodObject<{
26
+ label: z.ZodString;
27
+ value: z.ZodOptional<z.ZodString>;
28
+ description: z.ZodOptional<z.ZodString>;
29
+ preview: z.ZodOptional<z.ZodString>;
30
+ }, z.core.$strip>;
31
+ export type RuntimeCardFieldChoice = z.infer<typeof RuntimeCardFieldChoiceSchema>;
32
+ export declare const RuntimeCardLineItemColumnTypeSchema: z.ZodEnum<{
33
+ number: "number";
34
+ date: "date";
35
+ text: "text";
36
+ select: "select";
37
+ currency: "currency";
38
+ }>;
39
+ export type RuntimeCardLineItemColumnType = z.infer<typeof RuntimeCardLineItemColumnTypeSchema>;
40
+ export declare const RuntimeCardLineItemColumnSchema: z.ZodObject<{
41
+ id: z.ZodString;
42
+ label: z.ZodString;
43
+ type: z.ZodEnum<{
44
+ number: "number";
45
+ date: "date";
46
+ text: "text";
47
+ select: "select";
48
+ currency: "currency";
49
+ }>;
50
+ required: z.ZodOptional<z.ZodBoolean>;
51
+ choices: z.ZodOptional<z.ZodArray<z.ZodObject<{
52
+ label: z.ZodString;
53
+ value: z.ZodOptional<z.ZodString>;
54
+ description: z.ZodOptional<z.ZodString>;
55
+ preview: z.ZodOptional<z.ZodString>;
56
+ }, z.core.$strip>>>;
57
+ min: z.ZodOptional<z.ZodNumber>;
58
+ max: z.ZodOptional<z.ZodNumber>;
59
+ step: z.ZodOptional<z.ZodNumber>;
60
+ precision: z.ZodOptional<z.ZodNumber>;
61
+ currencyCode: z.ZodOptional<z.ZodString>;
62
+ allowOther: z.ZodOptional<z.ZodBoolean>;
63
+ }, z.core.$strip>;
64
+ export type RuntimeCardLineItemColumn = z.infer<typeof RuntimeCardLineItemColumnSchema>;
65
+ export declare const RuntimeCardFieldSchema: z.ZodObject<{
66
+ id: z.ZodString;
67
+ label: z.ZodString;
68
+ type: z.ZodEnum<{
69
+ number: "number";
70
+ boolean: "boolean";
71
+ date: "date";
72
+ text: "text";
73
+ textarea: "textarea";
74
+ select: "select";
75
+ multiSelect: "multiSelect";
76
+ currency: "currency";
77
+ searchSelect: "searchSelect";
78
+ lineItems: "lineItems";
79
+ }>;
80
+ required: z.ZodOptional<z.ZodBoolean>;
81
+ placeholder: z.ZodOptional<z.ZodString>;
82
+ choices: z.ZodOptional<z.ZodArray<z.ZodObject<{
83
+ label: z.ZodString;
84
+ value: z.ZodOptional<z.ZodString>;
85
+ description: z.ZodOptional<z.ZodString>;
86
+ preview: z.ZodOptional<z.ZodString>;
87
+ }, z.core.$strip>>>;
88
+ allowOther: z.ZodOptional<z.ZodBoolean>;
89
+ sensitive: z.ZodOptional<z.ZodBoolean>;
90
+ min: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>;
91
+ max: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>;
92
+ step: z.ZodOptional<z.ZodNumber>;
93
+ precision: z.ZodOptional<z.ZodNumber>;
94
+ currencyCode: z.ZodOptional<z.ZodString>;
95
+ columns: z.ZodOptional<z.ZodArray<z.ZodObject<{
96
+ id: z.ZodString;
97
+ label: z.ZodString;
98
+ type: z.ZodEnum<{
99
+ number: "number";
100
+ date: "date";
101
+ text: "text";
102
+ select: "select";
103
+ currency: "currency";
104
+ }>;
105
+ required: z.ZodOptional<z.ZodBoolean>;
106
+ choices: z.ZodOptional<z.ZodArray<z.ZodObject<{
107
+ label: z.ZodString;
108
+ value: z.ZodOptional<z.ZodString>;
109
+ description: z.ZodOptional<z.ZodString>;
110
+ preview: z.ZodOptional<z.ZodString>;
111
+ }, z.core.$strip>>>;
112
+ min: z.ZodOptional<z.ZodNumber>;
113
+ max: z.ZodOptional<z.ZodNumber>;
114
+ step: z.ZodOptional<z.ZodNumber>;
115
+ precision: z.ZodOptional<z.ZodNumber>;
116
+ currencyCode: z.ZodOptional<z.ZodString>;
117
+ allowOther: z.ZodOptional<z.ZodBoolean>;
118
+ }, z.core.$strip>>>;
119
+ minRows: z.ZodOptional<z.ZodNumber>;
120
+ maxRows: z.ZodOptional<z.ZodNumber>;
121
+ }, z.core.$strip>;
122
+ export type RuntimeCardField = z.infer<typeof RuntimeCardFieldSchema>;
50
123
  export declare function validateRuntimeCardFieldValues(input: {
51
124
  actionId: string | undefined;
52
125
  actionFields: ReadonlyArray<RuntimeCardField> | undefined;
@@ -1,3 +1,16 @@
1
+ import { z } from 'zod';
2
+ export const RuntimeCardFieldTypeSchema = z.enum([
3
+ 'text',
4
+ 'textarea',
5
+ 'select',
6
+ 'multiSelect',
7
+ 'boolean',
8
+ 'date',
9
+ 'number',
10
+ 'currency',
11
+ 'searchSelect',
12
+ 'lineItems',
13
+ ]);
1
14
  /**
2
15
  * Caps shared across runtime-card normalizers, response validation, and
3
16
  * authoring tools. Keep these backend-safe so Functions can import them.
@@ -8,6 +21,50 @@ export const RUNTIME_CARD_LIMITS = {
8
21
  lineItemColumns: 8,
9
22
  searchSelectChoices: 100,
10
23
  };
24
+ export const RuntimeCardFieldChoiceSchema = z.object({
25
+ label: z.string(),
26
+ value: z.string().optional(),
27
+ description: z.string().optional(),
28
+ preview: z.string().optional(),
29
+ });
30
+ export const RuntimeCardLineItemColumnTypeSchema = z.enum([
31
+ 'text',
32
+ 'number',
33
+ 'currency',
34
+ 'date',
35
+ 'select',
36
+ ]);
37
+ export const RuntimeCardLineItemColumnSchema = z.object({
38
+ id: z.string(),
39
+ label: z.string(),
40
+ type: RuntimeCardLineItemColumnTypeSchema,
41
+ required: z.boolean().optional(),
42
+ choices: z.array(RuntimeCardFieldChoiceSchema).optional(),
43
+ min: z.number().optional(),
44
+ max: z.number().optional(),
45
+ step: z.number().optional(),
46
+ precision: z.number().optional(),
47
+ currencyCode: z.string().optional(),
48
+ allowOther: z.boolean().optional(),
49
+ });
50
+ export const RuntimeCardFieldSchema = z.object({
51
+ id: z.string(),
52
+ label: z.string(),
53
+ type: RuntimeCardFieldTypeSchema,
54
+ required: z.boolean().optional(),
55
+ placeholder: z.string().optional(),
56
+ choices: z.array(RuntimeCardFieldChoiceSchema).optional(),
57
+ allowOther: z.boolean().optional(),
58
+ sensitive: z.boolean().optional(),
59
+ min: z.union([z.number(), z.string()]).optional(),
60
+ max: z.union([z.number(), z.string()]).optional(),
61
+ step: z.number().optional(),
62
+ precision: z.number().optional(),
63
+ currencyCode: z.string().optional(),
64
+ columns: z.array(RuntimeCardLineItemColumnSchema).optional(),
65
+ minRows: z.number().optional(),
66
+ maxRows: z.number().optional(),
67
+ });
11
68
  const ISO_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
12
69
  function isRecord(value) {
13
70
  return typeof value === 'object' && value !== null && !Array.isArray(value);
@@ -0,0 +1,48 @@
1
+ {
2
+ "$id": "canon:AgentBehaviorSettingsRecordSchema",
3
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
4
+ "type": "object",
5
+ "properties": {
6
+ "participationStyle": {
7
+ "type": "string",
8
+ "enum": [
9
+ "natural",
10
+ "collaborative",
11
+ "mention-first",
12
+ "approval-gated",
13
+ "handoff-only",
14
+ "observer"
15
+ ]
16
+ },
17
+ "allowAgentToAgent": {
18
+ "type": "boolean"
19
+ },
20
+ "allowLongRunningCollaboration": {
21
+ "type": "boolean"
22
+ },
23
+ "requireMentionForGroupReplies": {
24
+ "type": "boolean"
25
+ },
26
+ "maxConsecutiveAgentTurns": {
27
+ "anyOf": [
28
+ {
29
+ "type": "number"
30
+ },
31
+ {
32
+ "type": "null"
33
+ }
34
+ ]
35
+ },
36
+ "instructions": {
37
+ "anyOf": [
38
+ {
39
+ "type": "string"
40
+ },
41
+ {
42
+ "type": "null"
43
+ }
44
+ ]
45
+ }
46
+ },
47
+ "additionalProperties": false
48
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "$id": "canon:BridgeConnectionStateNotificationSchema",
3
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
4
+ "type": "object",
5
+ "properties": {
6
+ "upstream": {
7
+ "type": "string",
8
+ "enum": [
9
+ "connected",
10
+ "reconnecting",
11
+ "down"
12
+ ]
13
+ }
14
+ },
15
+ "required": [
16
+ "upstream"
17
+ ],
18
+ "additionalProperties": false
19
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "$id": "canon:BridgeGetAttachmentParamsSchema",
3
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
4
+ "type": "object",
5
+ "properties": {
6
+ "url": {
7
+ "type": "string"
8
+ },
9
+ "attachmentId": {
10
+ "type": "string"
11
+ },
12
+ "as": {
13
+ "type": "string",
14
+ "enum": [
15
+ "path",
16
+ "bytes"
17
+ ]
18
+ }
19
+ },
20
+ "required": [
21
+ "as"
22
+ ],
23
+ "additionalProperties": false
24
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "$id": "canon:BridgeGetAttachmentResultSchema",
3
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
4
+ "type": "object",
5
+ "properties": {
6
+ "path": {
7
+ "type": "string"
8
+ },
9
+ "bytes": {
10
+ "type": "string"
11
+ },
12
+ "mime": {
13
+ "type": "string"
14
+ }
15
+ },
16
+ "required": [
17
+ "mime"
18
+ ],
19
+ "additionalProperties": false
20
+ }
@@ -0,0 +1,42 @@
1
+ {
2
+ "$id": "canon:BridgeHelloParamsSchema",
3
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
4
+ "type": "object",
5
+ "properties": {
6
+ "protocolVersion": {
7
+ "type": "number"
8
+ },
9
+ "clientType": {
10
+ "type": "string"
11
+ },
12
+ "wantFamilies": {
13
+ "type": "array",
14
+ "items": {
15
+ "type": "string",
16
+ "enum": [
17
+ "messages",
18
+ "contacts",
19
+ "typing_presence",
20
+ "runtime_turn",
21
+ "voice"
22
+ ]
23
+ }
24
+ },
25
+ "resumeCursor": {
26
+ "type": "string"
27
+ },
28
+ "runtimeDescriptor": {
29
+ "type": "object",
30
+ "propertyNames": {
31
+ "type": "string"
32
+ },
33
+ "additionalProperties": {}
34
+ }
35
+ },
36
+ "required": [
37
+ "protocolVersion",
38
+ "clientType",
39
+ "wantFamilies"
40
+ ],
41
+ "additionalProperties": false
42
+ }