@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,6 +1,36 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SerializedContactRequestSchema = exports.SerializedContactRequestStatusSchema = void 0;
3
4
  exports.serializeContactRequest = serializeContactRequest;
5
+ const zod_1 = require("zod");
6
+ exports.SerializedContactRequestStatusSchema = zod_1.z.enum([
7
+ 'pending',
8
+ 'approved',
9
+ 'rejected',
10
+ 'expired',
11
+ ]);
12
+ exports.SerializedContactRequestSchema = zod_1.z.object({
13
+ id: zod_1.z.string(),
14
+ requesterId: zod_1.z.string(),
15
+ requesterName: zod_1.z.string(),
16
+ requesterAvatarUrl: zod_1.z.string().nullable(),
17
+ targetId: zod_1.z.string(),
18
+ targetName: zod_1.z.string(),
19
+ targetAvatarUrl: zod_1.z.string().nullable(),
20
+ targetUserType: zod_1.z.enum(['human', 'ai_agent']),
21
+ targetOwnerId: zod_1.z.string().nullable().optional(),
22
+ approverId: zod_1.z.string(),
23
+ message: zod_1.z.string().nullable(),
24
+ status: exports.SerializedContactRequestStatusSchema,
25
+ kind: zod_1.z.enum(['dm', 'group_invite']),
26
+ groupContext: zod_1.z.object({
27
+ conversationId: zod_1.z.string(),
28
+ groupName: zod_1.z.string().nullable(),
29
+ }).optional(),
30
+ createdAt: zod_1.z.string().nullable(),
31
+ resolvedAt: zod_1.z.string().nullable().optional(),
32
+ expiresAt: zod_1.z.string().nullable().optional(),
33
+ });
4
34
  function isRecord(value) {
5
35
  return typeof value === 'object' && value !== null && !Array.isArray(value);
6
36
  }
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ControlPrimitiveEventSchema = exports.ControlSessionEventSchema = exports.ControlSignalEventSchema = exports.ControlPrimitiveMapSchema = exports.ControlSessionNodeSchema = exports.ControlSignalNodeSchema = exports.ControlChannelKeySchema = exports.ControlSignalTypeSchema = void 0;
4
+ // Wire contract v1 — RTDB control-channel signal + session-control records.
5
+ //
6
+ // Grounded in @canonmsg/core's ControlChannelPoller (the consumer every host
7
+ // uses for `/control/{conversationId}/{agentId}` reads) and stream-service's
8
+ // `runtime.control` mirror. Three channel keys, read in order:
9
+ // session — human changed a runtime control (model/effort/permission …)
10
+ // signal — interrupt / stop_and_drop / new_session
11
+ // primitive — keyed request map (requestId → value)
12
+ const zod_1 = require("zod");
13
+ exports.ControlSignalTypeSchema = zod_1.z.enum(['interrupt', 'stop_and_drop', 'new_session']);
14
+ exports.ControlChannelKeySchema = zod_1.z.enum(['session', 'signal', 'primitive']);
15
+ // ── RTDB node records (what is written at /control/{convo}/{agent}/…) ──
16
+ /** `/control/{convo}/{agent}/signal` node. Consumed by writing null. */
17
+ exports.ControlSignalNodeSchema = zod_1.z.looseObject({
18
+ type: exports.ControlSignalTypeSchema,
19
+ updatedAt: zod_1.z.number().optional(),
20
+ });
21
+ /** `/control/{convo}/{agent}/session` node — the session-control primitive record. */
22
+ exports.ControlSessionNodeSchema = zod_1.z.looseObject({
23
+ updatedAt: zod_1.z.number().optional(),
24
+ });
25
+ /** `/control/{convo}/{agent}/primitive` — map of requestId → request value. */
26
+ exports.ControlPrimitiveMapSchema = zod_1.z.record(zod_1.z.string(), zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()));
27
+ // ── Dispatched events (what a runtime's handler receives) ──────────────
28
+ exports.ControlSignalEventSchema = zod_1.z.object({
29
+ conversationId: zod_1.z.string(),
30
+ type: exports.ControlSignalTypeSchema,
31
+ updatedAt: zod_1.z.number(),
32
+ raw: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()),
33
+ });
34
+ exports.ControlSessionEventSchema = zod_1.z.object({
35
+ conversationId: zod_1.z.string(),
36
+ updatedAt: zod_1.z.number(),
37
+ control: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()),
38
+ });
39
+ exports.ControlPrimitiveEventSchema = zod_1.z.object({
40
+ conversationId: zod_1.z.string(),
41
+ requestId: zod_1.z.string(),
42
+ updatedAt: zod_1.z.number(),
43
+ value: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()),
44
+ });
@@ -0,0 +1,264 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CANON_MEDIA_UPLOAD_ENDPOINT = exports.CANON_REST_ENDPOINTS = void 0;
4
+ const restEndpoints_js_1 = require("./restEndpoints.js");
5
+ const sendContextual_js_1 = require("./sendContextual.js");
6
+ exports.CANON_REST_ENDPOINTS = [
7
+ // ── Identity ─────────────────────────────────────────────────────────
8
+ {
9
+ method: 'POST',
10
+ path: '/agents/register',
11
+ section: 'identity',
12
+ note: 'Public registration request. No API key required.',
13
+ },
14
+ {
15
+ method: 'GET',
16
+ path: '/agents/status/:requestId',
17
+ section: 'identity',
18
+ note: 'Poll approval status. Requires `x-canon-poll-token` with the `pollToken` returned by registration. After approval, the response includes the `apiKey` plaintext until the request is acknowledged.',
19
+ },
20
+ {
21
+ method: 'POST',
22
+ path: '/agents/status/:requestId/ack',
23
+ section: 'identity',
24
+ note: 'Acknowledge delivery. Requires `x-canon-poll-token`; clears the plaintext key from the registration request record so subsequent GET reads return `apiKeyDelivered: true`. Unacked plaintext keys are also auto-scrubbed 48 hours after approval; subsequent GET reads then return `apiKeyExpired: true` and the registrant must re-register (or the owner re-issues via key rotation).',
25
+ },
26
+ {
27
+ method: 'GET',
28
+ path: '/agents/me',
29
+ section: 'identity',
30
+ note: 'Authenticated agent identity and context.',
31
+ },
32
+ {
33
+ method: 'PATCH',
34
+ path: '/agents/profile',
35
+ section: 'identity',
36
+ note: 'Update agent profile fields.',
37
+ },
38
+ {
39
+ method: 'POST',
40
+ path: '/agents/auth-token',
41
+ section: 'identity',
42
+ note: 'Exchange API key for live agent-channel access when needed.',
43
+ },
44
+ {
45
+ method: 'POST',
46
+ path: '/agents/keys/rotate',
47
+ section: 'identity',
48
+ note: 'Agent-initiated key rotation. Returns the new plaintext key once.',
49
+ },
50
+ // ── Messaging ────────────────────────────────────────────────────────
51
+ {
52
+ method: 'POST',
53
+ path: '/messages/send',
54
+ section: 'messaging',
55
+ note: 'Send a durable message into a conversation.',
56
+ request: restEndpoints_js_1.SendMessageRequestSchema,
57
+ response: restEndpoints_js_1.SendMessageResponseSchema,
58
+ },
59
+ {
60
+ method: 'POST',
61
+ path: '/messages/send-contextual',
62
+ section: 'messaging',
63
+ note: 'Cross-conversation message with private agent self-context.',
64
+ request: sendContextual_js_1.SendContextualRequestSchema,
65
+ response: sendContextual_js_1.SendContextualResponseSchema,
66
+ },
67
+ {
68
+ method: 'POST',
69
+ path: '/messages/react',
70
+ section: 'messaging',
71
+ note: 'Toggle an emoji reaction.',
72
+ request: restEndpoints_js_1.ReactRequestSchema,
73
+ response: restEndpoints_js_1.ReactResponseSchema,
74
+ },
75
+ {
76
+ method: 'POST',
77
+ path: '/messages/forward',
78
+ section: 'messaging',
79
+ note: 'Forward an existing message.',
80
+ request: restEndpoints_js_1.ForwardMessageRequestSchema,
81
+ response: restEndpoints_js_1.ForwardMessageResponseSchema,
82
+ },
83
+ {
84
+ method: 'DELETE',
85
+ path: '/conversations/:conversationId/messages/:messageId',
86
+ section: 'messaging',
87
+ note: "Soft-delete the agent's own message.",
88
+ },
89
+ {
90
+ method: 'PATCH',
91
+ path: '/conversations/:conversationId/messages/:messageId/disposition',
92
+ section: 'messaging',
93
+ note: 'Update message disposition metadata.',
94
+ request: restEndpoints_js_1.UpdateDispositionRequestSchema,
95
+ },
96
+ {
97
+ method: 'POST',
98
+ path: '/typing',
99
+ section: 'messaging',
100
+ note: 'Publish typing state.',
101
+ request: restEndpoints_js_1.SetTypingRequestSchema,
102
+ },
103
+ {
104
+ method: 'POST',
105
+ path: '/streaming',
106
+ section: 'messaging',
107
+ note: 'Publish live streaming/progress state through REST. Most current runtimes prefer shared live-state helpers.',
108
+ request: restEndpoints_js_1.SetStreamingRequestSchema,
109
+ },
110
+ // ── Conversations ────────────────────────────────────────────────────
111
+ {
112
+ method: 'GET',
113
+ path: '/conversations',
114
+ section: 'conversations',
115
+ note: 'List conversations the agent participates in.',
116
+ response: restEndpoints_js_1.ConversationsResponseSchema,
117
+ },
118
+ {
119
+ method: 'GET',
120
+ path: '/conversations/:conversationId/messages',
121
+ section: 'conversations',
122
+ note: 'Fetch recent messages.',
123
+ request: restEndpoints_js_1.GetMessagesQuerySchema,
124
+ response: restEndpoints_js_1.MessagesPageResponseSchema,
125
+ },
126
+ {
127
+ method: 'POST',
128
+ path: '/conversations/create',
129
+ section: 'conversations',
130
+ note: 'Create or find a direct/group conversation when allowed.',
131
+ request: restEndpoints_js_1.CreateConversationRequestSchema,
132
+ response: restEndpoints_js_1.CreateConversationResponseSchema,
133
+ },
134
+ {
135
+ method: 'PATCH',
136
+ path: '/conversations/:conversationId/topic',
137
+ section: 'conversations',
138
+ note: 'Update the topic.',
139
+ },
140
+ {
141
+ method: 'PATCH',
142
+ path: '/conversations/:conversationId/name',
143
+ section: 'conversations',
144
+ note: 'Update group name when allowed.',
145
+ },
146
+ {
147
+ method: 'PATCH',
148
+ path: '/conversations/:conversationId/avatar',
149
+ section: 'conversations',
150
+ note: 'Update group avatar when allowed.',
151
+ },
152
+ {
153
+ method: 'POST',
154
+ path: '/conversations/:conversationId/read',
155
+ section: 'conversations',
156
+ note: 'Mark read.',
157
+ },
158
+ {
159
+ method: 'POST',
160
+ path: '/conversations/:conversationId/mute',
161
+ section: 'conversations',
162
+ note: 'Mute for the agent.',
163
+ },
164
+ {
165
+ method: 'POST',
166
+ path: '/conversations/:conversationId/unmute',
167
+ section: 'conversations',
168
+ note: 'Unmute for the agent.',
169
+ },
170
+ {
171
+ method: 'POST',
172
+ path: '/conversations/:conversationId/hide',
173
+ section: 'conversations',
174
+ note: 'Hide until new inbound activity.',
175
+ },
176
+ {
177
+ method: 'POST',
178
+ path: '/conversations/:conversationId/leave',
179
+ section: 'conversations',
180
+ note: 'Leave a group.',
181
+ },
182
+ {
183
+ method: 'POST',
184
+ path: '/conversations/:conversationId/members',
185
+ section: 'conversations',
186
+ note: 'Add a member when allowed.',
187
+ },
188
+ {
189
+ method: 'DELETE',
190
+ path: '/conversations/:conversationId/members/:userId',
191
+ section: 'conversations',
192
+ note: 'Remove a member when allowed.',
193
+ },
194
+ // ── Contacts and access ──────────────────────────────────────────────
195
+ {
196
+ method: 'POST',
197
+ path: '/contacts/request',
198
+ section: 'contacts',
199
+ note: 'Agent-side request for access.',
200
+ request: restEndpoints_js_1.CreateContactRequestRequestSchema,
201
+ response: restEndpoints_js_1.CreateContactRequestResponseSchema,
202
+ },
203
+ {
204
+ method: 'GET',
205
+ path: '/contacts/requests',
206
+ section: 'contacts',
207
+ note: 'Read-only awareness surface for requests involving the agent.',
208
+ },
209
+ {
210
+ method: 'GET',
211
+ path: '/contacts',
212
+ section: 'contacts',
213
+ note: "List the authenticated agent's contacts.",
214
+ response: restEndpoints_js_1.ContactsResponseSchema,
215
+ },
216
+ {
217
+ method: 'GET',
218
+ path: '/contacts/:contactId',
219
+ section: 'contacts',
220
+ note: 'Fetch a single contact entry; 404 if missing.',
221
+ response: restEndpoints_js_1.RestContactSchema,
222
+ },
223
+ {
224
+ method: 'DELETE',
225
+ path: '/contacts/:contactId',
226
+ section: 'contacts',
227
+ note: 'Remove a contact.',
228
+ },
229
+ {
230
+ method: 'POST',
231
+ path: '/users/block',
232
+ section: 'contacts',
233
+ note: 'Block a user.',
234
+ },
235
+ {
236
+ method: 'POST',
237
+ path: '/users/unblock',
238
+ section: 'contacts',
239
+ note: 'Unblock a user.',
240
+ },
241
+ {
242
+ method: 'POST',
243
+ path: '/admission/resolve',
244
+ section: 'contacts',
245
+ note: 'Resolve live admission state for a target user (used by `agent.reachOut` and contact-card CTAs to avoid acting on stale snapshots).',
246
+ request: restEndpoints_js_1.ResolveAdmissionRequestSchema,
247
+ response: restEndpoints_js_1.ResolveAdmissionResponseSchema,
248
+ },
249
+ {
250
+ method: 'POST',
251
+ path: '/admission/resolve-group',
252
+ section: 'contacts',
253
+ note: 'Resolve live group-join admission state (reads `groupJoinPolicy`).',
254
+ },
255
+ ];
256
+ // Referenced for completeness of the registry import surface.
257
+ exports.CANON_MEDIA_UPLOAD_ENDPOINT = {
258
+ method: 'POST',
259
+ path: '/media/upload',
260
+ section: 'messaging',
261
+ note: 'Upload media; returns a Storage URL plus a normalized attachment.',
262
+ request: restEndpoints_js_1.UploadMediaRequestSchema,
263
+ response: restEndpoints_js_1.UploadMediaResponseSchema,
264
+ };
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HitlPendingSchema = exports.HitlResolutionSchema = exports.HitlRequestAcceptedSchema = exports.HitlCardOutcomeRecordSchema = exports.HitlCardReplyRecordSchema = exports.HitlCardRequestRecordSchema = exports.HitlInputOutcomeRecordSchema = exports.HitlInputReplyRecordSchema = exports.HitlInputRequestRecordSchema = exports.HitlInputAnswersSchema = exports.HitlInputQuestionSchema = exports.HitlInputKindSchema = exports.HitlApprovalOutcomeRecordSchema = exports.HitlApprovalReplyRecordSchema = exports.HitlApprovalRequestRecordSchema = exports.HitlSessionRuleSchema = exports.HitlApprovalDetailSchema = exports.HitlApprovalCategorySchema = exports.HitlApprovalRiskSchema = exports.HitlResolutionStatusSchema = exports.HitlRequestKindSchema = void 0;
4
+ // Wire contract v1 — HITL (human-in-the-loop) request / resolution records.
5
+ //
6
+ // HITL is durable state, not a held request (bridge-local-api.md): the pending
7
+ // request is a persisted record (message metadata + RTDB node with expiresAt),
8
+ // and the resolution arrives later. These schemas ground the three record
9
+ // families as core's hosts publish/consume them today:
10
+ // approval — approval_request / approval_reply / approval_outcome
11
+ // input — runtime_input_request / runtime_input_reply / runtime_input_outcome
12
+ // card — runtime_card_request / runtime_card_reply / runtime_card_outcome
13
+ // plus the unified bridge-level resolution record (§C6 onHitlResolved).
14
+ const zod_1 = require("zod");
15
+ const runtimeCardFields_js_1 = require("./runtimeCardFields.js");
16
+ exports.HitlRequestKindSchema = zod_1.z.enum(['approval', 'input', 'card']);
17
+ exports.HitlResolutionStatusSchema = zod_1.z.enum(['submitted', 'cancelled', 'timeout']);
18
+ // ── Approval records ───────────────────────────────────────────────────
19
+ exports.HitlApprovalRiskSchema = zod_1.z.enum(['low', 'normal', 'high', 'destructive']);
20
+ exports.HitlApprovalCategorySchema = zod_1.z.enum([
21
+ 'command',
22
+ 'file',
23
+ 'network',
24
+ 'browser',
25
+ 'mcp',
26
+ 'plugin',
27
+ 'canon',
28
+ 'tool',
29
+ ]);
30
+ exports.HitlApprovalDetailSchema = zod_1.z.object({
31
+ label: zod_1.z.string(),
32
+ value: zod_1.z.string(),
33
+ monospace: zod_1.z.boolean().optional(),
34
+ });
35
+ exports.HitlSessionRuleSchema = zod_1.z.object({
36
+ type: zod_1.z.enum(['approve-all', 'approve-tool', 'deny-tool']),
37
+ toolPattern: zod_1.z.string().optional(),
38
+ expiresAt: zod_1.z.string().nullable().optional(),
39
+ });
40
+ exports.HitlApprovalRequestRecordSchema = zod_1.z.looseObject({
41
+ type: zod_1.z.literal('approval_request'),
42
+ approvalId: zod_1.z.string(),
43
+ responseUserId: zod_1.z.string().optional(),
44
+ toolName: zod_1.z.string(),
45
+ /** Pre-computed, redacted summary — raw tool input is never stored. */
46
+ toolSummary: zod_1.z.string(),
47
+ category: exports.HitlApprovalCategorySchema.optional(),
48
+ risk: exports.HitlApprovalRiskSchema.optional(),
49
+ riskLevel: zod_1.z.enum(['normal', 'destructive']).optional(),
50
+ runtimeId: zod_1.z.string().optional(),
51
+ turnId: zod_1.z.string().optional(),
52
+ /** Native runtime correlation handles — opaque pass-through. */
53
+ native: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).optional(),
54
+ details: zod_1.z.array(exports.HitlApprovalDetailSchema).optional(),
55
+ /** File-change preview (CanonUnifiedDiff) — opaque pass-through. */
56
+ diff: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).optional(),
57
+ expiresAt: zod_1.z.string(),
58
+ });
59
+ exports.HitlApprovalReplyRecordSchema = zod_1.z.looseObject({
60
+ type: zod_1.z.literal('approval_reply'),
61
+ approvalId: zod_1.z.string(),
62
+ decision: zod_1.z.enum(['allow', 'deny']),
63
+ sessionRule: exports.HitlSessionRuleSchema.optional(),
64
+ });
65
+ exports.HitlApprovalOutcomeRecordSchema = zod_1.z.looseObject({
66
+ type: zod_1.z.literal('approval_outcome'),
67
+ approvalId: zod_1.z.string().optional(),
68
+ decision: zod_1.z.enum(['allow', 'deny']).optional(),
69
+ reason: zod_1.z.enum(['replied', 'timeout', 'session-rule']).optional(),
70
+ });
71
+ // ── Input records ──────────────────────────────────────────────────────
72
+ exports.HitlInputKindSchema = zod_1.z.enum(['clarify', 'sudo', 'secret']);
73
+ exports.HitlInputQuestionSchema = zod_1.z.object({
74
+ id: zod_1.z.string(),
75
+ question: zod_1.z.string(),
76
+ header: zod_1.z.string().optional(),
77
+ choices: zod_1.z.array(runtimeCardFields_js_1.RuntimeCardFieldChoiceSchema).optional(),
78
+ allowOther: zod_1.z.boolean().optional(),
79
+ isSecret: zod_1.z.boolean().optional(),
80
+ multiSelect: zod_1.z.boolean().optional(),
81
+ });
82
+ /** questionId → selected/typed answers. */
83
+ exports.HitlInputAnswersSchema = zod_1.z.record(zod_1.z.string(), zod_1.z.object({ answers: zod_1.z.array(zod_1.z.string()) }));
84
+ exports.HitlInputRequestRecordSchema = zod_1.z.looseObject({
85
+ type: zod_1.z.literal('runtime_input_request'),
86
+ inputId: zod_1.z.string(),
87
+ responseUserId: zod_1.z.string().optional(),
88
+ kind: exports.HitlInputKindSchema,
89
+ prompt: zod_1.z.string(),
90
+ title: zod_1.z.string().optional(),
91
+ choices: zod_1.z.array(runtimeCardFields_js_1.RuntimeCardFieldChoiceSchema).optional(),
92
+ questions: zod_1.z.array(exports.HitlInputQuestionSchema).optional(),
93
+ secretName: zod_1.z.string().optional(),
94
+ native: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).optional(),
95
+ expiresAt: zod_1.z.string(),
96
+ sensitive: zod_1.z.boolean().optional(),
97
+ });
98
+ exports.HitlInputReplyRecordSchema = zod_1.z.looseObject({
99
+ type: zod_1.z.literal('runtime_input_reply'),
100
+ inputId: zod_1.z.string(),
101
+ kind: exports.HitlInputKindSchema.optional(),
102
+ status: zod_1.z.enum(['submitted', 'cancelled']),
103
+ answerSummary: zod_1.z.string().optional(),
104
+ answersSummary: zod_1.z.string().optional(),
105
+ sensitive: zod_1.z.boolean().optional(),
106
+ });
107
+ exports.HitlInputOutcomeRecordSchema = zod_1.z.looseObject({
108
+ type: zod_1.z.literal('runtime_input_outcome'),
109
+ inputId: zod_1.z.string(),
110
+ kind: exports.HitlInputKindSchema.optional(),
111
+ status: exports.HitlResolutionStatusSchema,
112
+ reason: zod_1.z.enum(['submitted', 'cancelled', 'timeout', 'expired', 'interrupted']).optional(),
113
+ });
114
+ // ── Card records ───────────────────────────────────────────────────────
115
+ exports.HitlCardRequestRecordSchema = zod_1.z.looseObject({
116
+ type: zod_1.z.literal('runtime_card_request'),
117
+ cardId: zod_1.z.string(),
118
+ cardKind: zod_1.z.string(),
119
+ schemaVersion: zod_1.z.literal('canon.card.v1'),
120
+ fallbackText: zod_1.z.string(),
121
+ responseUserId: zod_1.z.string().optional(),
122
+ expiresAt: zod_1.z.string(),
123
+ runtimeId: zod_1.z.string().optional(),
124
+ turnId: zod_1.z.string().optional(),
125
+ native: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).optional(),
126
+ /** True when the card carries an actions block (agent waits for a response). */
127
+ interactive: zod_1.z.boolean().optional(),
128
+ /** RuntimeCardPreview — opaque pass-through. */
129
+ cardPreview: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()),
130
+ turnSemantics: zod_1.z.literal('control'),
131
+ replyBehavior: zod_1.z.literal('suppress_auto_reply'),
132
+ });
133
+ exports.HitlCardReplyRecordSchema = zod_1.z.looseObject({
134
+ type: zod_1.z.literal('runtime_card_reply'),
135
+ cardId: zod_1.z.string(),
136
+ status: zod_1.z.enum(['submitted', 'cancelled']),
137
+ actionId: zod_1.z.string().optional(),
138
+ answerSummary: zod_1.z.string().optional(),
139
+ sensitive: zod_1.z.boolean().optional(),
140
+ turnSemantics: zod_1.z.literal('control'),
141
+ replyBehavior: zod_1.z.literal('suppress_auto_reply'),
142
+ });
143
+ exports.HitlCardOutcomeRecordSchema = zod_1.z.looseObject({
144
+ type: zod_1.z.literal('runtime_card_outcome'),
145
+ cardId: zod_1.z.string(),
146
+ status: exports.HitlResolutionStatusSchema,
147
+ reason: zod_1.z.enum(['submitted', 'cancelled', 'timeout', 'expired', 'interrupted']).optional(),
148
+ turnSemantics: zod_1.z.literal('control'),
149
+ replyBehavior: zod_1.z.literal('suppress_auto_reply'),
150
+ });
151
+ // ── Unified bridge-level records (bridge-local-api §B7/§C6) ────────────
152
+ /** Immediate result of requestApproval/requestInput/requestCard. */
153
+ exports.HitlRequestAcceptedSchema = zod_1.z.object({
154
+ requestId: zod_1.z.string(),
155
+ expiresAt: zod_1.z.string(),
156
+ });
157
+ /** `onHitlResolved` — matches an earlier requestId. */
158
+ exports.HitlResolutionSchema = zod_1.z.object({
159
+ requestId: zod_1.z.string(),
160
+ kind: exports.HitlRequestKindSchema.optional(),
161
+ status: exports.HitlResolutionStatusSchema,
162
+ /** Kind-specific answer payload (decision / answers / card action values). */
163
+ answer: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).optional(),
164
+ });
165
+ /** `onHitlPending` — replayed on reconnect for still-open requests. */
166
+ exports.HitlPendingSchema = zod_1.z.object({
167
+ requestId: zod_1.z.string(),
168
+ kind: exports.HitlRequestKindSchema,
169
+ conversationId: zod_1.z.string(),
170
+ expiresAt: zod_1.z.string(),
171
+ });
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InboundFrameV1Schema = exports.InboundFrameGroupContextV1Schema = exports.InboundFrameReplyContextV1Schema = exports.InboundFrameContactCardV1Schema = exports.InboundFrameAttachmentV1Schema = exports.InboundFrameShapeV1Schema = exports.INBOUND_FRAME_SCHEMA_V1 = void 0;
4
+ // Wire contract v1 — the canon.inbound_frame.v1 schema.
5
+ //
6
+ // Mirrors @canonmsg/core's CanonInboundFrameV1 (core/src/inbound-frame.ts),
7
+ // the structured projection every host/adapter renders its inbound prompt
8
+ // from. core keeps building the frame; a follow-up (post-P2 merge) flips core
9
+ // to infer its type from this schema. A compile-time assignability guard
10
+ // between core's type and this schema lives in @canonmsg/test-fixtures.
11
+ const zod_1 = require("zod");
12
+ const message_js_1 = require("./message.js");
13
+ const sseEvents_js_1 = require("./sseEvents.js");
14
+ exports.INBOUND_FRAME_SCHEMA_V1 = 'canon.inbound_frame.v1';
15
+ exports.InboundFrameShapeV1Schema = zod_1.z.enum([
16
+ 'direct_owner',
17
+ 'direct_human',
18
+ 'direct_agent',
19
+ 'group',
20
+ 'unknown',
21
+ ]);
22
+ exports.InboundFrameAttachmentV1Schema = zod_1.z.object({
23
+ index: zod_1.z.number(),
24
+ kind: zod_1.z.enum(['image', 'audio', 'video', 'file']),
25
+ placeholder: zod_1.z.string(),
26
+ fileName: zod_1.z.string().nullable(),
27
+ mimeType: zod_1.z.string().nullable(),
28
+ sizeBytes: zod_1.z.number().nullable(),
29
+ width: zod_1.z.number().nullable(),
30
+ height: zod_1.z.number().nullable(),
31
+ durationMs: zod_1.z.number().nullable(),
32
+ });
33
+ exports.InboundFrameContactCardV1Schema = zod_1.z.object({
34
+ userId: zod_1.z.string(),
35
+ canonContactId: zod_1.z.string().nullable(),
36
+ displayName: zod_1.z.string(),
37
+ userType: zod_1.z.enum(['human', 'ai_agent']),
38
+ ownerName: zod_1.z.string().nullable(),
39
+ about: zod_1.z.string().nullable(),
40
+ });
41
+ /** CanonTurnContextReplyContextV2 — the reply-to summary carried by the frame. */
42
+ exports.InboundFrameReplyContextV1Schema = zod_1.z.object({
43
+ messageId: zod_1.z.string(),
44
+ found: zod_1.z.boolean(),
45
+ senderId: zod_1.z.string().nullable(),
46
+ senderName: zod_1.z.string().nullable(),
47
+ senderType: zod_1.z.enum(['human', 'ai_agent']).nullable(),
48
+ contentType: message_js_1.SerializedContentTypeSchema.nullable(),
49
+ text: zod_1.z.string().nullable(),
50
+ body: zod_1.z.string(),
51
+ replyToPosition: zod_1.z.number().nullable(),
52
+ attachments: zod_1.z.array(exports.InboundFrameAttachmentV1Schema),
53
+ contactCard: exports.InboundFrameContactCardV1Schema.nullable(),
54
+ });
55
+ exports.InboundFrameGroupContextV1Schema = zod_1.z.object({
56
+ memberCount: zod_1.z.number(),
57
+ memberIds: zod_1.z.array(zod_1.z.string()),
58
+ ownerId: zod_1.z.string(),
59
+ ownerName: zod_1.z.string(),
60
+ ownerPresent: zod_1.z.boolean(),
61
+ knownRecentParticipants: zod_1.z.array(zod_1.z.object({
62
+ id: zod_1.z.string(),
63
+ name: zod_1.z.string(),
64
+ userType: zod_1.z.enum(['human', 'ai_agent', 'unknown']),
65
+ isOwner: zod_1.z.boolean(),
66
+ isSelf: zod_1.z.boolean(),
67
+ })),
68
+ membershipChange: sseEvents_js_1.SseMembershipChangeSchema.optional(),
69
+ });
70
+ exports.InboundFrameV1Schema = zod_1.z.object({
71
+ schema: zod_1.z.literal(exports.INBOUND_FRAME_SCHEMA_V1),
72
+ shape: exports.InboundFrameShapeV1Schema,
73
+ sender: zod_1.z.object({
74
+ name: zod_1.z.string(),
75
+ type: zod_1.z.enum(['human', 'ai_agent']),
76
+ isOwner: zod_1.z.boolean(),
77
+ }),
78
+ conversation: zod_1.z.object({
79
+ type: zod_1.z.enum(['direct', 'group', 'unknown']),
80
+ memberCount: zod_1.z.number().nullable(),
81
+ }),
82
+ addressed: zod_1.z.boolean(),
83
+ message: zod_1.z.object({
84
+ text: zod_1.z.string(),
85
+ contentType: message_js_1.SerializedContentTypeSchema.nullable(),
86
+ }),
87
+ replyContext: exports.InboundFrameReplyContextV1Schema.nullable(),
88
+ groupContext: exports.InboundFrameGroupContextV1Schema.nullable(),
89
+ groupContextMode: zod_1.z.enum(['initial', 'membership_change']).optional(),
90
+ selfContexts: zod_1.z.array(zod_1.z.string()),
91
+ behaviorInstructions: zod_1.z.array(zod_1.z.string()),
92
+ });
package/dist/cjs/index.js CHANGED
@@ -21,3 +21,11 @@ __exportStar(require("./runtimeCardStorage.js"), exports);
21
21
  __exportStar(require("./turnProtocol.js"), exports);
22
22
  __exportStar(require("./agentBehaviorPolicy.js"), exports);
23
23
  __exportStar(require("./contactRequest.js"), exports);
24
+ __exportStar(require("./sseEvents.js"), exports);
25
+ __exportStar(require("./controlSignals.js"), exports);
26
+ __exportStar(require("./hitl.js"), exports);
27
+ __exportStar(require("./inboundFrame.js"), exports);
28
+ __exportStar(require("./restEndpoints.js"), exports);
29
+ __exportStar(require("./sendContextual.js"), exports);
30
+ __exportStar(require("./bridgeLocal.js"), exports);
31
+ __exportStar(require("./endpointRegistry.js"), exports);
package/dist/cjs/media.js CHANGED
@@ -1,11 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MediaAttachmentSchema = exports.MediaAttachmentKindSchema = void 0;
3
4
  exports.inferMediaAttachmentKind = inferMediaAttachmentKind;
4
5
  exports.getStoredFileExtension = getStoredFileExtension;
5
6
  exports.normalizeStoredAttachments = normalizeStoredAttachments;
6
7
  exports.getMessageAttachments = getMessageAttachments;
7
8
  exports.getPrimaryAttachment = getPrimaryAttachment;
8
9
  exports.describeAttachment = describeAttachment;
10
+ const zod_1 = require("zod");
11
+ exports.MediaAttachmentKindSchema = zod_1.z.enum(['image', 'audio', 'video', 'file']);
12
+ exports.MediaAttachmentSchema = zod_1.z.object({
13
+ kind: exports.MediaAttachmentKindSchema,
14
+ url: zod_1.z.string(),
15
+ mimeType: zod_1.z.string().optional(),
16
+ fileName: zod_1.z.string().optional(),
17
+ sizeBytes: zod_1.z.number().optional(),
18
+ width: zod_1.z.number().optional(),
19
+ height: zod_1.z.number().optional(),
20
+ durationMs: zod_1.z.number().optional(),
21
+ });
9
22
  function inferMediaAttachmentKind(mimeType) {
10
23
  if (mimeType.startsWith('image/'))
11
24
  return 'image';