@canonmsg/backend-contracts 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) 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 +171 -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 +220 -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 -2
  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 +496 -0
  37. package/dist/restEndpoints.js +217 -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 +127 -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.schema.json +115 -0
  122. package/dist/schemas/rest-message.schema.json +252 -0
  123. package/dist/schemas/rest-ok-response.schema.json +11 -0
  124. package/dist/schemas/rest-session-selection.schema.json +40 -0
  125. package/dist/schemas/runtime-card-field-choice.schema.json +23 -0
  126. package/dist/schemas/runtime-card-field-type.schema.json +17 -0
  127. package/dist/schemas/runtime-card-field.schema.json +180 -0
  128. package/dist/schemas/runtime-card-line-item-column-type.schema.json +12 -0
  129. package/dist/schemas/runtime-card-line-item-column.schema.json +74 -0
  130. package/dist/schemas/send-contextual-deferred-response.schema.json +39 -0
  131. package/dist/schemas/send-contextual-messaged-response.schema.json +42 -0
  132. package/dist/schemas/send-contextual-request.schema.json +103 -0
  133. package/dist/schemas/send-contextual-response.schema.json +105 -0
  134. package/dist/schemas/send-contextual-self-context.schema.json +19 -0
  135. package/dist/schemas/send-contextual-state-response.schema.json +24 -0
  136. package/dist/schemas/send-message-request.schema.json +106 -0
  137. package/dist/schemas/send-message-response.schema.json +14 -0
  138. package/dist/schemas/sender-type.schema.json +9 -0
  139. package/dist/schemas/serialize-message-input.schema.json +29 -0
  140. package/dist/schemas/serialized-agent-client-type.schema.json +12 -0
  141. package/dist/schemas/serialized-contact-card.schema.json +65 -0
  142. package/dist/schemas/serialized-contact-request-status.schema.json +11 -0
  143. package/dist/schemas/serialized-contact-request.schema.json +157 -0
  144. package/dist/schemas/serialized-content-type.schema.json +13 -0
  145. package/dist/schemas/serialized-message.schema.json +249 -0
  146. package/dist/schemas/serialized-reactions.schema.json +14 -0
  147. package/dist/schemas/serialized-sender-type.schema.json +9 -0
  148. package/dist/schemas/set-streaming-request.schema.json +67 -0
  149. package/dist/schemas/set-typing-request.schema.json +25 -0
  150. package/dist/schemas/sse-access-policy.schema.json +10 -0
  151. package/dist/schemas/sse-agent-context-payload.schema.json +57 -0
  152. package/dist/schemas/sse-connected-payload.schema.json +18 -0
  153. package/dist/schemas/sse-contact-payload.schema.json +40 -0
  154. package/dist/schemas/sse-contact-removed-payload.schema.json +14 -0
  155. package/dist/schemas/sse-contact-request-payload.schema.json +157 -0
  156. package/dist/schemas/sse-conversation-updated-payload.schema.json +48 -0
  157. package/dist/schemas/sse-error-payload.schema.json +23 -0
  158. package/dist/schemas/sse-event-envelope.schema.json +42 -0
  159. package/dist/schemas/sse-event-family.schema.json +12 -0
  160. package/dist/schemas/sse-event-type.schema.json +28 -0
  161. package/dist/schemas/sse-heartbeat-payload.schema.json +14 -0
  162. package/dist/schemas/sse-membership-change.schema.json +28 -0
  163. package/dist/schemas/sse-message-created-payload.schema.json +414 -0
  164. package/dist/schemas/sse-message-deleted-payload.schema.json +18 -0
  165. package/dist/schemas/sse-message-updated-payload.schema.json +46 -0
  166. package/dist/schemas/sse-presence-payload.schema.json +21 -0
  167. package/dist/schemas/sse-provenance.schema.json +64 -0
  168. package/dist/schemas/sse-replay-expired-payload.schema.json +21 -0
  169. package/dist/schemas/sse-runtime-control-kind.schema.json +13 -0
  170. package/dist/schemas/sse-runtime-control-payload.schema.json +44 -0
  171. package/dist/schemas/sse-runtime-updated-payload.schema.json +78 -0
  172. package/dist/schemas/sse-self-context.schema.json +45 -0
  173. package/dist/schemas/sse-turn-dispatch.schema.json +29 -0
  174. package/dist/schemas/sse-turn-updated-payload.schema.json +33 -0
  175. package/dist/schemas/sse-typing-payload.schema.json +32 -0
  176. package/dist/schemas/sse-voice-session-event-payload.schema.json +170 -0
  177. package/dist/schemas/sse-voice-session.schema.json +157 -0
  178. package/dist/schemas/trigger-decision.schema.json +27 -0
  179. package/dist/schemas/turn-lifecycle-state.schema.json +14 -0
  180. package/dist/schemas/turn-message-semantics.schema.json +10 -0
  181. package/dist/schemas/turn-metadata.schema.json +56 -0
  182. package/dist/schemas/turn-state-like.schema.json +39 -0
  183. package/dist/schemas/update-disposition-request.schema.json +22 -0
  184. package/dist/schemas/upload-media-request.schema.json +25 -0
  185. package/dist/schemas/upload-media-response.schema.json +55 -0
  186. package/dist/sendContextual.d.ts +114 -0
  187. package/dist/sendContextual.js +89 -0
  188. package/dist/sseEvents.d.ts +494 -0
  189. package/dist/sseEvents.js +295 -0
  190. package/dist/turnProtocol.d.ts +91 -24
  191. package/dist/turnProtocol.js +40 -1
  192. package/package.json +8 -5
@@ -1,8 +1,72 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SerializeMessageInputSchema = exports.SerializedMessageSchema = exports.SerializedContactCardSchema = exports.SerializedReactionsSchema = exports.ForwardedFromSchema = exports.SerializedContentTypeSchema = exports.SerializedAgentClientTypeSchema = exports.SerializedSenderTypeSchema = void 0;
3
4
  exports.serializeStoredMessage = serializeStoredMessage;
5
+ const zod_1 = require("zod");
4
6
  const media_js_1 = require("./media.js");
5
7
  const runtimeCardStorage_js_1 = require("./runtimeCardStorage.js");
8
+ exports.SerializedSenderTypeSchema = zod_1.z.enum(['human', 'ai_agent']);
9
+ exports.SerializedAgentClientTypeSchema = zod_1.z.enum([
10
+ 'claude-code',
11
+ 'openclaw',
12
+ 'codex',
13
+ 'hermes',
14
+ 'generic',
15
+ ]);
16
+ exports.SerializedContentTypeSchema = zod_1.z.enum([
17
+ 'text',
18
+ 'image',
19
+ 'audio',
20
+ 'video',
21
+ 'file',
22
+ 'contact_card',
23
+ ]);
24
+ exports.ForwardedFromSchema = zod_1.z.object({
25
+ sourceConversationId: zod_1.z.string(),
26
+ messageId: zod_1.z.string(),
27
+ });
28
+ exports.SerializedReactionsSchema = zod_1.z.record(zod_1.z.string(), zod_1.z.array(zod_1.z.string()));
29
+ exports.SerializedContactCardSchema = zod_1.z.object({
30
+ userId: zod_1.z.string(),
31
+ canonContactId: zod_1.z.string().optional(),
32
+ displayName: zod_1.z.string(),
33
+ avatarUrl: zod_1.z.string().nullable(),
34
+ userType: exports.SerializedSenderTypeSchema,
35
+ clientType: exports.SerializedAgentClientTypeSchema.optional(),
36
+ about: zod_1.z.string().optional(),
37
+ isActive: zod_1.z.boolean().optional(),
38
+ ownerId: zod_1.z.string().optional(),
39
+ ownerName: zod_1.z.string().optional(),
40
+ lifecycleState: zod_1.z.string().optional(),
41
+ });
42
+ exports.SerializedMessageSchema = zod_1.z.object({
43
+ id: zod_1.z.string(),
44
+ senderId: zod_1.z.string(),
45
+ senderName: zod_1.z.string().optional(),
46
+ senderType: exports.SerializedSenderTypeSchema,
47
+ isOwner: zod_1.z.boolean(),
48
+ contentType: exports.SerializedContentTypeSchema,
49
+ text: zod_1.z.string().nullable(),
50
+ attachments: zod_1.z.array(media_js_1.MediaAttachmentSchema),
51
+ mentions: zod_1.z.array(zod_1.z.string()),
52
+ replyTo: zod_1.z.string().nullable(),
53
+ replyToPosition: zod_1.z.number().nullable(),
54
+ forwarded: zod_1.z.boolean().optional(),
55
+ forwardedFrom: exports.ForwardedFromSchema.optional(),
56
+ status: zod_1.z.enum(['sent', 'read']),
57
+ createdAt: zod_1.z.string(),
58
+ metadata: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).optional(),
59
+ contactCard: exports.SerializedContactCardSchema.optional(),
60
+ /** Durable canon.card.v1 runtime card content, passed through opaquely. */
61
+ runtimeCard: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).optional(),
62
+ reactions: exports.SerializedReactionsSchema.optional(),
63
+ });
64
+ exports.SerializeMessageInputSchema = zod_1.z.object({
65
+ id: zod_1.z.string(),
66
+ data: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()),
67
+ senderName: zod_1.z.string().optional(),
68
+ isOwner: zod_1.z.boolean(),
69
+ });
6
70
  function isRecord(value) {
7
71
  return typeof value === 'object' && value !== null && !Array.isArray(value);
8
72
  }
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UploadMediaResponseSchema = exports.UploadMediaRequestSchema = exports.SetStreamingRequestSchema = exports.SetTypingRequestSchema = exports.ResolveAdmissionResponseSchema = exports.ResolveAdmissionRequestSchema = exports.ContactsResponseSchema = exports.CreateContactRequestResponseSchema = exports.CreateContactRequestRequestSchema = exports.CreateConversationResponseSchema = exports.CreateConversationRequestSchema = exports.MessagesPageResponseSchema = exports.GetMessagesQuerySchema = exports.ConversationsResponseSchema = exports.UpdateDispositionRequestSchema = exports.MarkReadResponseSchema = exports.DeleteMessageResponseSchema = exports.ForwardMessageResponseSchema = exports.ForwardMessageRequestSchema = exports.ReactResponseSchema = exports.ReactRequestSchema = exports.SendMessageResponseSchema = exports.SendMessageRequestSchema = exports.RestSessionSelectionSchema = exports.RestContactSchema = exports.RestConversationSchema = exports.RestMessageSchema = exports.RestOkResponseSchema = void 0;
4
+ // Wire contract v1 — request/response schemas for the agent-facing "Canon op"
5
+ // REST surface the bridge proxies (bridge-local-api.md §B).
6
+ //
7
+ // Grounded in the Functions handlers (functions/src/api/*) and the canonical
8
+ // consumer (@canonmsg/core CanonClient) — request bodies mirror what clients
9
+ // send today, response schemas mirror what the handlers emit. This is a
10
+ // re-expression of current behavior, not a redesign.
11
+ const zod_1 = require("zod");
12
+ const media_js_1 = require("./media.js");
13
+ const message_js_1 = require("./message.js");
14
+ const turnProtocol_js_1 = require("./turnProtocol.js");
15
+ // ── Shared fragments ───────────────────────────────────────────────────
16
+ exports.RestOkResponseSchema = zod_1.z.looseObject({
17
+ success: zod_1.z.boolean().optional(),
18
+ });
19
+ /** GET …/messages items — the serialized message plus the soft-delete flag. */
20
+ exports.RestMessageSchema = message_js_1.SerializedMessageSchema.extend({
21
+ deleted: zod_1.z.boolean().optional(),
22
+ });
23
+ exports.RestConversationSchema = zod_1.z.looseObject({
24
+ id: zod_1.z.string(),
25
+ type: zod_1.z.enum(['direct', 'group']),
26
+ name: zod_1.z.string().nullable().optional(),
27
+ topic: zod_1.z.string().nullable().optional(),
28
+ memberIds: zod_1.z.array(zod_1.z.string()),
29
+ isAgentChat: zod_1.z.boolean().optional(),
30
+ /** Resolved agent behavior policy — opaque pass-through. */
31
+ behavior: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).optional(),
32
+ hasUnread: zod_1.z.boolean().optional(),
33
+ lastMessage: zod_1.z.looseObject({
34
+ text: zod_1.z.string(),
35
+ messageId: zod_1.z.string().optional(),
36
+ senderId: zod_1.z.string(),
37
+ senderType: zod_1.z.enum(['human', 'ai_agent']),
38
+ contentType: message_js_1.SerializedContentTypeSchema.optional(),
39
+ timestamp: zod_1.z.string(),
40
+ }).nullable(),
41
+ createdAt: zod_1.z.string().optional(),
42
+ });
43
+ exports.RestContactSchema = zod_1.z.object({
44
+ id: zod_1.z.string(),
45
+ source: zod_1.z.string(),
46
+ addedAt: zod_1.z.string().nullable(),
47
+ displayNameOverride: zod_1.z.string().nullable(),
48
+ });
49
+ exports.RestSessionSelectionSchema = zod_1.z.union([
50
+ zod_1.z.object({ mode: zod_1.z.enum(['new', 'continue_latest', 'continue_or_create']) }),
51
+ zod_1.z.object({ mode: zod_1.z.literal('specific'), conversationId: zod_1.z.string() }),
52
+ ]);
53
+ // ── POST /messages/send ────────────────────────────────────────────────
54
+ exports.SendMessageRequestSchema = zod_1.z.object({
55
+ conversationId: zod_1.z.string(),
56
+ text: zod_1.z.string().optional(),
57
+ /** Client-supplied idempotency id. */
58
+ messageId: zod_1.z.string().optional(),
59
+ contentType: message_js_1.SerializedContentTypeSchema.optional(),
60
+ replyTo: zod_1.z.string().optional(),
61
+ replyToPosition: zod_1.z.number().optional(),
62
+ attachments: zod_1.z.array(media_js_1.MediaAttachmentSchema).optional(),
63
+ contactCardUserId: zod_1.z.string().optional(),
64
+ mentions: zod_1.z.array(zod_1.z.string()).optional(),
65
+ selfContextId: zod_1.z.string().nullable().optional(),
66
+ /** Structured metadata (turn protocol, approval cards, …). */
67
+ metadata: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).optional(),
68
+ });
69
+ exports.SendMessageResponseSchema = zod_1.z.object({
70
+ messageId: zod_1.z.string(),
71
+ });
72
+ // ── POST /messages/react ───────────────────────────────────────────────
73
+ exports.ReactRequestSchema = zod_1.z.object({
74
+ conversationId: zod_1.z.string(),
75
+ messageId: zod_1.z.string(),
76
+ emoji: zod_1.z.string(),
77
+ });
78
+ exports.ReactResponseSchema = zod_1.z.object({
79
+ success: zod_1.z.boolean(),
80
+ action: zod_1.z.enum(['added', 'removed']),
81
+ reactions: message_js_1.SerializedReactionsSchema,
82
+ });
83
+ // ── POST /messages/forward ─────────────────────────────────────────────
84
+ exports.ForwardMessageRequestSchema = zod_1.z.object({
85
+ sourceConversationId: zod_1.z.string(),
86
+ targetConversationId: zod_1.z.string(),
87
+ messageId: zod_1.z.string(),
88
+ text: zod_1.z.string().optional(),
89
+ });
90
+ exports.ForwardMessageResponseSchema = zod_1.z.object({
91
+ messageId: zod_1.z.string(),
92
+ targetConversationId: zod_1.z.string(),
93
+ forwardedFrom: zod_1.z.object({
94
+ sourceConversationId: zod_1.z.string(),
95
+ messageId: zod_1.z.string(),
96
+ }),
97
+ });
98
+ // ── DELETE /conversations/:id/messages/:id, POST …/read, PATCH …/disposition ──
99
+ exports.DeleteMessageResponseSchema = exports.RestOkResponseSchema;
100
+ exports.MarkReadResponseSchema = exports.RestOkResponseSchema;
101
+ exports.UpdateDispositionRequestSchema = zod_1.z.object({
102
+ inboundDisposition: turnProtocol_js_1.InboundDispositionSchema,
103
+ });
104
+ // ── GET /conversations + GET …/messages ────────────────────────────────
105
+ exports.ConversationsResponseSchema = zod_1.z.object({
106
+ conversations: zod_1.z.array(exports.RestConversationSchema),
107
+ });
108
+ /** Query params: limit, before, includeBehavior. */
109
+ exports.GetMessagesQuerySchema = zod_1.z.object({
110
+ limit: zod_1.z.string().optional(),
111
+ before: zod_1.z.string().optional(),
112
+ includeBehavior: zod_1.z.string().optional(),
113
+ });
114
+ exports.MessagesPageResponseSchema = zod_1.z.looseObject({
115
+ messages: zod_1.z.array(exports.RestMessageSchema),
116
+ /** Present with includeBehavior=1. */
117
+ behavior: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).optional(),
118
+ activeSelfContextIdByMessageId: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional(),
119
+ selfContexts: zod_1.z.array(zod_1.z.record(zod_1.z.string(), zod_1.z.unknown())).optional(),
120
+ });
121
+ // ── POST /conversations/create ─────────────────────────────────────────
122
+ exports.CreateConversationRequestSchema = zod_1.z.object({
123
+ type: zod_1.z.enum(['direct', 'group']),
124
+ targetUserId: zod_1.z.string().optional(),
125
+ memberIds: zod_1.z.array(zod_1.z.string()).optional(),
126
+ name: zod_1.z.string().optional(),
127
+ /** Initial session config for first-party coding agents — opaque pass-through. */
128
+ sessionConfig: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).nullable().optional(),
129
+ sessionSelection: exports.RestSessionSelectionSchema.optional(),
130
+ });
131
+ exports.CreateConversationResponseSchema = zod_1.z.object({
132
+ conversationId: zod_1.z.string(),
133
+ created: zod_1.z.boolean().optional(),
134
+ reused: zod_1.z.boolean().optional(),
135
+ sessionSelection: zod_1.z.enum(['new', 'continue_latest', 'continue_or_create', 'specific']).optional(),
136
+ });
137
+ // ── Contacts / admission ───────────────────────────────────────────────
138
+ exports.CreateContactRequestRequestSchema = zod_1.z.object({
139
+ targetId: zod_1.z.string(),
140
+ message: zod_1.z.string().optional(),
141
+ });
142
+ exports.CreateContactRequestResponseSchema = zod_1.z.union([
143
+ zod_1.z.looseObject({ status: zod_1.z.literal('open') }),
144
+ zod_1.z.looseObject({ status: zod_1.z.enum(['created', 'duplicate']), requestId: zod_1.z.string() }),
145
+ /** Legacy "already a contact" body. */
146
+ zod_1.z.looseObject({ message: zod_1.z.string() }),
147
+ ]);
148
+ exports.ContactsResponseSchema = zod_1.z.object({
149
+ contacts: zod_1.z.array(exports.RestContactSchema),
150
+ });
151
+ exports.ResolveAdmissionRequestSchema = zod_1.z.union([
152
+ zod_1.z.object({ targetUserId: zod_1.z.string() }),
153
+ zod_1.z.object({ canonContactId: zod_1.z.string() }),
154
+ ]);
155
+ exports.ResolveAdmissionResponseSchema = zod_1.z.looseObject({
156
+ resolvedTargetUserId: zod_1.z.string().nullable().optional(),
157
+ target: zod_1.z.looseObject({
158
+ id: zod_1.z.string(),
159
+ canonContactId: zod_1.z.string().optional(),
160
+ displayName: zod_1.z.string().optional(),
161
+ avatarUrl: zod_1.z.string().nullable().optional(),
162
+ about: zod_1.z.string().optional(),
163
+ userType: zod_1.z.enum(['human', 'ai_agent']).optional(),
164
+ discoverable: zod_1.z.boolean().optional(),
165
+ inboundPolicy: zod_1.z.enum(['open', 'approval-required', 'owner-only']).optional(),
166
+ groupJoinPolicy: zod_1.z.enum(['open', 'approval-required', 'owner-only']).optional(),
167
+ }).nullable(),
168
+ admission: zod_1.z.looseObject({
169
+ state: zod_1.z.enum([
170
+ 'self',
171
+ 'not-found',
172
+ 'allowed',
173
+ 'request-required',
174
+ 'pending-outbound',
175
+ 'blocked',
176
+ 'inactive',
177
+ 'owner-only',
178
+ ]),
179
+ canMessage: zod_1.z.boolean(),
180
+ canRequestContact: zod_1.z.boolean(),
181
+ isContact: zod_1.z.boolean(),
182
+ pendingRequestId: zod_1.z.string().optional(),
183
+ blockedByViewer: zod_1.z.boolean().optional(),
184
+ blockedByTarget: zod_1.z.boolean().optional(),
185
+ }),
186
+ });
187
+ // ── Typing / streaming ─────────────────────────────────────────────────
188
+ exports.SetTypingRequestSchema = zod_1.z.object({
189
+ conversationId: zod_1.z.string(),
190
+ typing: zod_1.z.boolean(),
191
+ status: zod_1.z.enum(['thinking', 'typing']).optional(),
192
+ });
193
+ /** POST /streaming — the legacy REST facade over the RTDB streaming bubble. */
194
+ exports.SetStreamingRequestSchema = zod_1.z.union([
195
+ zod_1.z.object({
196
+ conversationId: zod_1.z.string(),
197
+ text: zod_1.z.string(),
198
+ status: zod_1.z.string(),
199
+ messageId: zod_1.z.string(),
200
+ turnId: zod_1.z.string().nullable().optional(),
201
+ /** TurnOutputBlock[] — opaque pass-through. */
202
+ blocks: zod_1.z.array(zod_1.z.record(zod_1.z.string(), zod_1.z.unknown())).optional(),
203
+ }),
204
+ zod_1.z.object({
205
+ conversationId: zod_1.z.string(),
206
+ streaming: zod_1.z.literal(false),
207
+ }),
208
+ ]);
209
+ // ── Media upload ───────────────────────────────────────────────────────
210
+ exports.UploadMediaRequestSchema = zod_1.z.object({
211
+ conversationId: zod_1.z.string(),
212
+ mimeType: zod_1.z.string(),
213
+ /** Base64-encoded file content. */
214
+ data: zod_1.z.string(),
215
+ fileName: zod_1.z.string().optional(),
216
+ });
217
+ exports.UploadMediaResponseSchema = zod_1.z.object({
218
+ url: zod_1.z.string(),
219
+ attachment: media_js_1.MediaAttachmentSchema,
220
+ });
@@ -1,7 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RUNTIME_CARD_LIMITS = void 0;
3
+ exports.RuntimeCardFieldSchema = exports.RuntimeCardLineItemColumnSchema = exports.RuntimeCardLineItemColumnTypeSchema = exports.RuntimeCardFieldChoiceSchema = exports.RUNTIME_CARD_LIMITS = exports.RuntimeCardFieldTypeSchema = void 0;
4
4
  exports.validateRuntimeCardFieldValues = validateRuntimeCardFieldValues;
5
+ const zod_1 = require("zod");
6
+ exports.RuntimeCardFieldTypeSchema = zod_1.z.enum([
7
+ 'text',
8
+ 'textarea',
9
+ 'select',
10
+ 'multiSelect',
11
+ 'boolean',
12
+ 'date',
13
+ 'number',
14
+ 'currency',
15
+ 'searchSelect',
16
+ 'lineItems',
17
+ ]);
5
18
  /**
6
19
  * Caps shared across runtime-card normalizers, response validation, and
7
20
  * authoring tools. Keep these backend-safe so Functions can import them.
@@ -12,6 +25,50 @@ exports.RUNTIME_CARD_LIMITS = {
12
25
  lineItemColumns: 8,
13
26
  searchSelectChoices: 100,
14
27
  };
28
+ exports.RuntimeCardFieldChoiceSchema = zod_1.z.object({
29
+ label: zod_1.z.string(),
30
+ value: zod_1.z.string().optional(),
31
+ description: zod_1.z.string().optional(),
32
+ preview: zod_1.z.string().optional(),
33
+ });
34
+ exports.RuntimeCardLineItemColumnTypeSchema = zod_1.z.enum([
35
+ 'text',
36
+ 'number',
37
+ 'currency',
38
+ 'date',
39
+ 'select',
40
+ ]);
41
+ exports.RuntimeCardLineItemColumnSchema = zod_1.z.object({
42
+ id: zod_1.z.string(),
43
+ label: zod_1.z.string(),
44
+ type: exports.RuntimeCardLineItemColumnTypeSchema,
45
+ required: zod_1.z.boolean().optional(),
46
+ choices: zod_1.z.array(exports.RuntimeCardFieldChoiceSchema).optional(),
47
+ min: zod_1.z.number().optional(),
48
+ max: zod_1.z.number().optional(),
49
+ step: zod_1.z.number().optional(),
50
+ precision: zod_1.z.number().optional(),
51
+ currencyCode: zod_1.z.string().optional(),
52
+ allowOther: zod_1.z.boolean().optional(),
53
+ });
54
+ exports.RuntimeCardFieldSchema = zod_1.z.object({
55
+ id: zod_1.z.string(),
56
+ label: zod_1.z.string(),
57
+ type: exports.RuntimeCardFieldTypeSchema,
58
+ required: zod_1.z.boolean().optional(),
59
+ placeholder: zod_1.z.string().optional(),
60
+ choices: zod_1.z.array(exports.RuntimeCardFieldChoiceSchema).optional(),
61
+ allowOther: zod_1.z.boolean().optional(),
62
+ sensitive: zod_1.z.boolean().optional(),
63
+ min: zod_1.z.union([zod_1.z.number(), zod_1.z.string()]).optional(),
64
+ max: zod_1.z.union([zod_1.z.number(), zod_1.z.string()]).optional(),
65
+ step: zod_1.z.number().optional(),
66
+ precision: zod_1.z.number().optional(),
67
+ currencyCode: zod_1.z.string().optional(),
68
+ columns: zod_1.z.array(exports.RuntimeCardLineItemColumnSchema).optional(),
69
+ minRows: zod_1.z.number().optional(),
70
+ maxRows: zod_1.z.number().optional(),
71
+ });
15
72
  const ISO_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
16
73
  function isRecord(value) {
17
74
  return typeof value === 'object' && value !== null && !Array.isArray(value);
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SEND_CONTEXTUAL_HTTP_STATUS = exports.SendContextualResponseSchema = exports.SendContextualStateResponseSchema = exports.SendContextualDeferredResponseSchema = exports.SendContextualMessagedResponseSchema = exports.SendContextualRequestSchema = exports.SendContextualSelfContextSchema = void 0;
4
+ // Wire contract v1 — POST /messages/send-contextual as a FIRST-CLASS contract
5
+ // (bridge-execution-plan Phase 3; owner decision 2026-07-03: the re-spec rides
6
+ // contract v1, the transport stays as-is and the Bridge proxies it unchanged
7
+ // in Phase 4).
8
+ //
9
+ // Grounded in functions/src/api/sendContextualMessage.ts (the handler's actual
10
+ // parse + emissions) and @canonmsg/core's SendContextualMessageOptions/Result.
11
+ // This mirrors CURRENT behavior — a re-spec, not a redesign.
12
+ const zod_1 = require("zod");
13
+ const restEndpoints_js_1 = require("./restEndpoints.js");
14
+ exports.SendContextualSelfContextSchema = zod_1.z.object({
15
+ type: zod_1.z.literal('cross_session'),
16
+ /** Private agent self-context; server caps at 1000 chars. */
17
+ context: zod_1.z.string(),
18
+ });
19
+ /**
20
+ * Request body. Exactly ONE of targetConversationId (existing conversation) or
21
+ * targetUserId (open/reuse a direct conversation, contact-request fallback)
22
+ * must be present — the refinement enforces the handler's rule.
23
+ */
24
+ exports.SendContextualRequestSchema = zod_1.z.object({
25
+ sourceConversationId: zod_1.z.string(),
26
+ /** Target arm 1: send into an existing conversation. */
27
+ targetConversationId: zod_1.z.string().optional(),
28
+ /** Target arm 2: resolve/create a direct conversation with this user. */
29
+ targetUserId: zod_1.z.string().optional(),
30
+ text: zod_1.z.string().optional(),
31
+ selfContext: exports.SendContextualSelfContextSchema,
32
+ /** Initial agent session config (agent targets) — opaque pass-through. */
33
+ sessionConfig: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).nullable().optional(),
34
+ sessionSelection: restEndpoints_js_1.RestSessionSelectionSchema.optional(),
35
+ /** Contact-request message when admission requires approval. */
36
+ requestMessage: zod_1.z.string().optional(),
37
+ /**
38
+ * SendMessageOptions passthrough (attachments, replyTo, metadata, …).
39
+ * May NOT carry selfContextId/selfContext — the handler rejects overrides
40
+ * of the self-context linkage fields.
41
+ */
42
+ messageOptions: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).optional(),
43
+ }).refine((body) => (body.targetConversationId ? 1 : 0) + (body.targetUserId ? 1 : 0) === 1, { message: 'Provide exactly one targetConversationId or targetUserId' }).refine((body) => !body.messageOptions
44
+ || (!('selfContextId' in body.messageOptions) && !('selfContext' in body.messageOptions)), { message: 'messageOptions may not override self-context linkage fields' });
45
+ // ── Response arms (exactly what the handler emits today) ───────────────
46
+ /** HTTP 201 — message persisted (or idempotent replay) with self-context linked. */
47
+ exports.SendContextualMessagedResponseSchema = zod_1.z.object({
48
+ status: zod_1.z.literal('messaged'),
49
+ messageId: zod_1.z.string(),
50
+ conversationId: zod_1.z.string(),
51
+ selfContextId: zod_1.z.string(),
52
+ /** Present when the target conversation was opened by this call. */
53
+ created: zod_1.z.boolean().optional(),
54
+ reused: zod_1.z.boolean().optional(),
55
+ sessionSelection: zod_1.z.enum(['new', 'continue_latest', 'continue_or_create', 'specific']).optional(),
56
+ });
57
+ /**
58
+ * HTTP 202 — admission requires approval: a contact request was created
59
+ * (`requested`) or already pending (`pending`); the message is deferred as a
60
+ * contextual intent when a request id exists.
61
+ */
62
+ exports.SendContextualDeferredResponseSchema = zod_1.z.object({
63
+ status: zod_1.z.enum(['requested', 'pending']),
64
+ requestId: zod_1.z.string().nullable(),
65
+ deferredIntentId: zod_1.z.string().nullable().optional(),
66
+ });
67
+ /**
68
+ * Terminal / retryable states:
69
+ * - setup_required (HTTP 202) — agent session setup must complete first.
70
+ * - blocked (HTTP 200) — admission denied (block or policy).
71
+ * - unavailable (HTTP 200) — target cannot be reached right now.
72
+ * - no_session (HTTP 404) — session selection matched nothing.
73
+ */
74
+ exports.SendContextualStateResponseSchema = zod_1.z.object({
75
+ status: zod_1.z.enum(['setup_required', 'blocked', 'unavailable', 'no_session']),
76
+ reason: zod_1.z.string(),
77
+ });
78
+ exports.SendContextualResponseSchema = zod_1.z.union([
79
+ exports.SendContextualMessagedResponseSchema,
80
+ exports.SendContextualDeferredResponseSchema,
81
+ exports.SendContextualStateResponseSchema,
82
+ ]);
83
+ /** HTTP status the handler pairs with each response status. */
84
+ exports.SEND_CONTEXTUAL_HTTP_STATUS = {
85
+ messaged: 201,
86
+ requested: 202,
87
+ pending: 202,
88
+ setup_required: 202,
89
+ blocked: 200,
90
+ unavailable: 200,
91
+ no_session: 404,
92
+ };