@canonmsg/agent-sdk 11.2.1 → 12.0.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 (188) hide show
  1. package/README.md +171 -536
  2. package/dist/chunks/chunk-6VK4UZHJ.js +2806 -0
  3. package/dist/chunks/chunk-FPQFTTND.js +4899 -0
  4. package/dist/chunks/chunk-OLJ7H4E2.js +14705 -0
  5. package/dist/chunks/mls-crypto-NZDNSPAO.js +10 -0
  6. package/dist/cli.js +198 -0
  7. package/dist/drivers/claude.d.ts +36 -0
  8. package/dist/drivers/code.d.ts +18 -0
  9. package/dist/drivers/codex.d.ts +37 -0
  10. package/dist/index.d.ts +12 -25
  11. package/dist/index.js +69 -13
  12. package/dist/internal/backend-contracts/agentBehaviorPolicy.d.ts +122 -0
  13. package/dist/internal/backend-contracts/agentDirectory.d.ts +32 -0
  14. package/dist/internal/backend-contracts/agentOrigin.d.ts +23 -0
  15. package/dist/internal/backend-contracts/agentSearch.d.ts +17 -0
  16. package/dist/internal/backend-contracts/api-origins.generated.d.ts +4 -0
  17. package/dist/internal/backend-contracts/apiErrors.d.ts +1 -0
  18. package/dist/internal/backend-contracts/artifactActions.d.ts +159 -0
  19. package/dist/internal/backend-contracts/artifacts.d.ts +386 -0
  20. package/dist/internal/backend-contracts/communication.d.ts +131 -0
  21. package/dist/internal/backend-contracts/conversationMembership.d.ts +28 -0
  22. package/dist/internal/backend-contracts/deliveryObservation.d.ts +23 -0
  23. package/dist/internal/backend-contracts/diffRedaction.d.ts +6 -0
  24. package/dist/internal/backend-contracts/endpoint-unread.d.ts +4 -0
  25. package/dist/internal/backend-contracts/endpoint.d.ts +103 -0
  26. package/dist/internal/backend-contracts/endpointContentPolicy.d.ts +37 -0
  27. package/dist/internal/backend-contracts/environment.d.ts +20 -0
  28. package/dist/internal/backend-contracts/externalInbound.d.ts +24 -0
  29. package/dist/internal/backend-contracts/firestoreValues.d.ts +9 -0
  30. package/dist/internal/backend-contracts/index.d.ts +48 -0
  31. package/dist/internal/backend-contracts/media-url.d.ts +6 -0
  32. package/dist/internal/backend-contracts/media.d.ts +51 -0
  33. package/dist/internal/backend-contracts/mediaDelivery.d.ts +46 -0
  34. package/dist/internal/backend-contracts/mediaTransferProtocol.d.ts +17 -0
  35. package/dist/internal/backend-contracts/membershipChange.d.ts +21 -0
  36. package/dist/internal/backend-contracts/message.d.ts +86 -0
  37. package/dist/internal/backend-contracts/messageText.d.ts +6 -0
  38. package/dist/internal/backend-contracts/mlsDevApplication.d.ts +73 -0
  39. package/dist/internal/backend-contracts/mlsDevCredential.d.ts +75 -0
  40. package/dist/internal/backend-contracts/mlsDevCredentialReconciliation.d.ts +45 -0
  41. package/dist/internal/backend-contracts/mlsDevDeviceCustody.d.ts +51 -0
  42. package/dist/internal/backend-contracts/mlsDevEnrollment.d.ts +74 -0
  43. package/dist/internal/backend-contracts/mlsDevGroup.d.ts +197 -0
  44. package/dist/internal/backend-contracts/mlsDevGroupFeed.d.ts +47 -0
  45. package/dist/internal/backend-contracts/mlsDevKeyPackage.d.ts +42 -0
  46. package/dist/internal/backend-contracts/mlsDevKeyPackages.d.ts +55 -0
  47. package/dist/internal/backend-contracts/moderation.d.ts +7 -0
  48. package/dist/internal/backend-contracts/plaintextProcessors.d.ts +63 -0
  49. package/dist/internal/backend-contracts/preparedContent.d.ts +54 -0
  50. package/dist/internal/backend-contracts/replyAuthority.d.ts +14 -0
  51. package/dist/internal/backend-contracts/runtimeCardFields.d.ts +66 -0
  52. package/dist/internal/backend-contracts/runtimeCardStorage.d.ts +3 -0
  53. package/dist/internal/backend-contracts/runtimeDescriptor.d.ts +88 -0
  54. package/dist/internal/backend-contracts/selfContext.d.ts +9 -0
  55. package/dist/internal/backend-contracts/turnProtocol.d.ts +43 -0
  56. package/dist/internal/backend-contracts/verbContract.d.ts +848 -0
  57. package/dist/internal/backend-contracts/verbSchemas.d.ts +1707 -0
  58. package/dist/internal/backend-contracts/verbWire.d.ts +493 -0
  59. package/dist/internal/backend-contracts/webAuth.d.ts +8 -0
  60. package/dist/internal/backend-contracts/workSessions.d.ts +205 -0
  61. package/dist/internal/core/agent-profiles.d.ts +69 -0
  62. package/dist/internal/core/agent-resolver.d.ts +49 -0
  63. package/dist/internal/core/agent-session.d.ts +12 -0
  64. package/dist/internal/core/approval-format.d.ts +26 -0
  65. package/dist/internal/core/approval-manager.d.ts +43 -0
  66. package/dist/internal/core/approval-types.d.ts +74 -0
  67. package/dist/internal/core/artifacts.d.ts +262 -0
  68. package/dist/internal/core/attached-native-session.d.ts +174 -0
  69. package/dist/internal/core/attached-session-file-store.d.ts +3 -0
  70. package/dist/internal/core/base-url.d.ts +1 -0
  71. package/dist/internal/core/cli-metadata.d.ts +13 -0
  72. package/dist/internal/core/client.d.ts +486 -0
  73. package/dist/internal/core/completed-output-journal.d.ts +39 -0
  74. package/dist/internal/core/constants.d.ts +4 -0
  75. package/dist/internal/core/control-poller.d.ts +221 -0
  76. package/dist/internal/core/endpoint-client.d.ts +43 -0
  77. package/dist/internal/core/exclusive-json-file-store.d.ts +7 -0
  78. package/dist/internal/core/execution-environment-mode.d.ts +8 -0
  79. package/dist/internal/core/execution-environment.d.ts +55 -0
  80. package/dist/internal/core/gifs.d.ts +35 -0
  81. package/dist/internal/core/group-context.d.ts +25 -0
  82. package/dist/internal/core/host-runtime.d.ts +257 -0
  83. package/dist/internal/core/inbound-frame.d.ts +64 -0
  84. package/dist/internal/core/index.d.ts +107 -0
  85. package/dist/internal/core/local-runtime-catalog.d.ts +131 -0
  86. package/dist/internal/core/message-format.d.ts +13 -0
  87. package/dist/internal/core/native-session-interaction.d.ts +44 -0
  88. package/dist/internal/core/node-media.d.ts +6 -0
  89. package/dist/internal/core/policy.d.ts +2 -0
  90. package/dist/internal/core/provenance.d.ts +31 -0
  91. package/dist/internal/core/registration-cli.d.ts +40 -0
  92. package/dist/internal/core/registration-profile.d.ts +10 -0
  93. package/dist/internal/core/registration-session.d.ts +55 -0
  94. package/dist/internal/core/registration.d.ts +21 -0
  95. package/dist/internal/core/retry.d.ts +122 -0
  96. package/dist/internal/core/rtdb-rest.d.ts +145 -0
  97. package/dist/internal/core/runtime-cards.d.ts +331 -0
  98. package/dist/internal/core/runtime-descriptor.d.ts +75 -0
  99. package/dist/internal/core/runtime-endpoints.d.ts +26 -0
  100. package/dist/internal/core/runtime-heartbeat.d.ts +29 -0
  101. package/dist/internal/core/runtime-presentation.d.ts +35 -0
  102. package/dist/internal/core/runtime-request-manager.d.ts +284 -0
  103. package/dist/internal/core/runtime-state-publisher.d.ts +42 -0
  104. package/dist/internal/core/self-context.d.ts +61 -0
  105. package/dist/internal/core/silent-turn.d.ts +86 -0
  106. package/dist/internal/core/stream.d.ts +77 -0
  107. package/dist/internal/core/turn-output-controller.d.ts +69 -0
  108. package/dist/internal/core/turn-protocol.d.ts +33 -0
  109. package/dist/internal/core/turn-verbosity.d.ts +97 -0
  110. package/dist/internal/core/types.d.ts +1075 -0
  111. package/dist/internal/core/typing-status-publisher.d.ts +14 -0
  112. package/dist/internal/core/unified-diff.d.ts +35 -0
  113. package/dist/internal/core/work-session-provider.d.ts +29 -0
  114. package/dist/internal/core/workspace-discovery.d.ts +17 -0
  115. package/dist/internal/endpoint/artifact-images.d.ts +60 -0
  116. package/dist/internal/endpoint/artifact-reducer.d.ts +35 -0
  117. package/dist/internal/endpoint/artifact-views.d.ts +113 -0
  118. package/dist/internal/endpoint/artifacts.d.ts +75 -0
  119. package/dist/internal/endpoint/delivery.d.ts +47 -0
  120. package/dist/internal/endpoint/engine.d.ts +219 -0
  121. package/dist/internal/endpoint/ephemeral.d.ts +8 -0
  122. package/dist/internal/endpoint/events.d.ts +32 -0
  123. package/dist/internal/endpoint/external-inbound.d.ts +36 -0
  124. package/dist/internal/endpoint/handoff.d.ts +50 -0
  125. package/dist/internal/endpoint/history.d.ts +22 -0
  126. package/dist/internal/endpoint/image-generation-errors.d.ts +2 -0
  127. package/dist/internal/endpoint/inbound.d.ts +29 -0
  128. package/dist/internal/endpoint/index.d.ts +32 -0
  129. package/dist/internal/endpoint/media.d.ts +172 -0
  130. package/dist/internal/endpoint/migration.d.ts +50 -0
  131. package/dist/internal/endpoint/mls-crypto.d.ts +25 -0
  132. package/dist/internal/endpoint/mls-dev-client.d.ts +44 -0
  133. package/dist/internal/endpoint/mls-dev-device.d.ts +67 -0
  134. package/dist/internal/endpoint/mls-dev-groups.d.ts +114 -0
  135. package/dist/internal/endpoint/mls-dev-key-package-service.d.ts +33 -0
  136. package/dist/internal/endpoint/mls-dev-key-packages.d.ts +42 -0
  137. package/dist/internal/endpoint/mls-dev-transport.d.ts +37 -0
  138. package/dist/internal/endpoint/node-mls-custody-protocol.d.ts +24 -0
  139. package/dist/internal/endpoint/node-mls-custody.d.ts +15 -0
  140. package/dist/internal/endpoint/node.d.ts +7 -0
  141. package/dist/internal/endpoint/observe-query.d.ts +17 -0
  142. package/dist/internal/endpoint/portable-node-mls-custody.d.ts +23 -0
  143. package/dist/internal/endpoint/queue.d.ts +22 -0
  144. package/dist/internal/endpoint/recovery.d.ts +27 -0
  145. package/dist/internal/endpoint/retention.d.ts +7 -0
  146. package/dist/internal/endpoint/store.d.ts +22 -0
  147. package/dist/internal/endpoint/sync.d.ts +33 -0
  148. package/dist/internal/endpoint/transient-publisher.d.ts +8 -0
  149. package/dist/internal/endpoint/transport.d.ts +58 -0
  150. package/dist/media.d.ts +1 -1
  151. package/dist/media.js +42 -541
  152. package/dist/runner/runner.d.ts +37 -0
  153. package/dist/runner/types.d.ts +168 -0
  154. package/package.json +18 -5
  155. package/dist/attached-session.d.ts +0 -58
  156. package/dist/attached-session.js +0 -638
  157. package/dist/bounded-file-read.d.ts +0 -14
  158. package/dist/bounded-file-read.js +0 -34
  159. package/dist/canon-agent.d.ts +0 -236
  160. package/dist/canon-agent.js +0 -2531
  161. package/dist/debouncer.d.ts +0 -18
  162. package/dist/debouncer.js +0 -133
  163. package/dist/inbound-handoff.d.ts +0 -6
  164. package/dist/inbound-handoff.js +0 -17
  165. package/dist/managed-session-host.d.ts +0 -27
  166. package/dist/managed-session-host.js +0 -195
  167. package/dist/managed-session-setup.d.ts +0 -99
  168. package/dist/managed-session-setup.js +0 -234
  169. package/dist/realtime.d.ts +0 -62
  170. package/dist/realtime.js +0 -193
  171. package/dist/runtime-card.d.ts +0 -48
  172. package/dist/runtime-card.js +0 -64
  173. package/dist/session-manager.d.ts +0 -77
  174. package/dist/session-manager.js +0 -285
  175. package/dist/turn-streaming-request.d.ts +0 -17
  176. package/dist/turn-streaming-request.js +0 -22
  177. package/dist/turn-verbosity-option.d.ts +0 -33
  178. package/dist/turn-verbosity-option.js +0 -23
  179. package/dist/types.d.ts +0 -387
  180. package/dist/types.js +0 -1
  181. package/dist/work-session-coordination.d.ts +0 -21
  182. package/dist/work-session-coordination.js +0 -53
  183. package/dist/work-session-host.d.ts +0 -31
  184. package/dist/work-session-host.js +0 -617
  185. package/dist/work-session-interactions.d.ts +0 -12
  186. package/dist/work-session-interactions.js +0 -173
  187. package/dist/work-session-state.d.ts +0 -36
  188. package/dist/work-session-state.js +0 -62
@@ -1,77 +0,0 @@
1
- import type { CanonMessage } from '@canonmsg/core';
2
- import { type InboundHandoffs } from './inbound-handoff.js';
3
- export interface SessionConfig {
4
- /** Max messages to retain per session (default: 50) */
5
- contextLimit?: number;
6
- /** Max sessions processing concurrently (default: 10) */
7
- concurrency?: number;
8
- /** Evict idle sessions after this many ms (default: 1h) */
9
- idleTimeoutMs?: number;
10
- }
11
- export interface Session {
12
- /** Session ID (= conversationId) */
13
- id: string;
14
- /** Accumulated messages for this conversation, oldest first */
15
- messages: CanonMessage[];
16
- /** Arbitrary per-session state managed by the agent */
17
- metadata: Record<string, unknown>;
18
- /** When this session last processed a message */
19
- lastActiveAt: number;
20
- }
21
- type SessionHandler = (session: Session, newMessages: CanonMessage[], handoffs: InboundHandoffs) => Promise<void>;
22
- export interface EnqueueOptions {
23
- /** Place this batch ahead of other not-yet-running batches. */
24
- toFront?: boolean;
25
- /** Execution receipts carried with this batch, independent of retained history. */
26
- handoffs?: InboundHandoffs;
27
- }
28
- /**
29
- * Manages per-conversation sessions with:
30
- * - In-memory message buffer per session
31
- * - Serialized processing within a session (queue)
32
- * - Parallel processing across sessions (bounded concurrency)
33
- * - Idle session eviction
34
- */
35
- export declare class SessionManager {
36
- private sessions;
37
- private queues;
38
- private activeCount;
39
- private destroyed;
40
- private pending;
41
- private processing;
42
- private seenMessages;
43
- private seededSessions;
44
- private sweepTimer;
45
- private contextLimit;
46
- private concurrency;
47
- private idleTimeoutMs;
48
- constructor(config?: SessionConfig);
49
- /** Get or create a session for a conversation */
50
- getSession(conversationId: string): Session;
51
- private appendMessagesToSession;
52
- private removeMessagesFromSession;
53
- /**
54
- * Enqueue messages for processing in a specific session.
55
- * Returns a promise that resolves when the handler completes for these messages.
56
- *
57
- * - Messages within the same session are serialized (queued).
58
- * - Messages across different sessions run concurrently up to the concurrency limit.
59
- */
60
- enqueue(conversationId: string, messages: CanonMessage[], handler: SessionHandler, options?: EnqueueOptions): Promise<void>;
61
- private drainSession;
62
- /** Seed a session with historical messages (e.g. fetched from API) */
63
- seedHistory(conversationId: string, history: CanonMessage[]): void;
64
- /** Remove idle sessions */
65
- private sweep;
66
- /** Number of queued batches waiting behind the active turn for this conversation. */
67
- getQueueDepth(conversationId: string): number;
68
- /** Drop one not-yet-running queued message for a conversation. */
69
- dropQueuedMessage(conversationId: string, messageId: string): CanonMessage[];
70
- /** Drop queued, not-yet-running batches for a conversation. */
71
- dropQueued(conversationId: string): CanonMessage[];
72
- /** Drop queued work and clear retained context for a conversation. */
73
- resetSession(conversationId: string): CanonMessage[];
74
- /** Clean up all state */
75
- destroy(): void;
76
- }
77
- export {};
@@ -1,285 +0,0 @@
1
- import { disposeInboundHandoffs, selectInboundHandoffs } from './inbound-handoff.js';
2
- const DEFAULT_CONTEXT_LIMIT = 50;
3
- const DEFAULT_CONCURRENCY = 10;
4
- const DEFAULT_IDLE_TIMEOUT_MS = 60 * 60 * 1000; // 1 hour
5
- const SWEEP_INTERVAL_MS = 60 * 1000; // 1 minute
6
- /**
7
- * Manages per-conversation sessions with:
8
- * - In-memory message buffer per session
9
- * - Serialized processing within a session (queue)
10
- * - Parallel processing across sessions (bounded concurrency)
11
- * - Idle session eviction
12
- */
13
- export class SessionManager {
14
- sessions = new Map();
15
- queues = new Map();
16
- activeCount = 0;
17
- destroyed = false;
18
- // Use Set<string> instead of Array for O(1) dedup and correct pop semantics (#1, #2)
19
- pending = new Set();
20
- processing = new Set();
21
- // Per-session seen message ID sets for O(1) dedup (#9)
22
- seenMessages = new Map();
23
- // Track seeded sessions so seedHistory is idempotent (#7)
24
- seededSessions = new Set();
25
- sweepTimer = null;
26
- contextLimit;
27
- concurrency;
28
- idleTimeoutMs;
29
- constructor(config = {}) {
30
- this.contextLimit = config.contextLimit ?? DEFAULT_CONTEXT_LIMIT;
31
- this.concurrency = config.concurrency ?? DEFAULT_CONCURRENCY;
32
- this.idleTimeoutMs = config.idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT_MS;
33
- this.sweepTimer = setInterval(() => this.sweep(), SWEEP_INTERVAL_MS);
34
- // Don't hold the process open for the sweeper
35
- if (this.sweepTimer.unref)
36
- this.sweepTimer.unref();
37
- }
38
- /** Get or create a session for a conversation */
39
- getSession(conversationId) {
40
- let session = this.sessions.get(conversationId);
41
- if (!session) {
42
- session = {
43
- id: conversationId,
44
- messages: [],
45
- metadata: {},
46
- lastActiveAt: Date.now(),
47
- };
48
- this.sessions.set(conversationId, session);
49
- this.seenMessages.set(conversationId, new Set());
50
- }
51
- // Refresh lastActiveAt on every access to prevent premature eviction (#8)
52
- session.lastActiveAt = Date.now();
53
- return session;
54
- }
55
- appendMessagesToSession(conversationId, messages) {
56
- const session = this.getSession(conversationId);
57
- const seen = this.seenMessages.get(conversationId);
58
- for (const msg of messages) {
59
- if (!seen.has(msg.id)) {
60
- seen.add(msg.id);
61
- session.messages.push(msg);
62
- }
63
- }
64
- if (session.messages.length > this.contextLimit) {
65
- session.messages = session.messages.slice(-this.contextLimit);
66
- const retainedIds = new Set(session.messages.map((message) => message.id));
67
- for (const id of Array.from(seen)) {
68
- if (!retainedIds.has(id)) {
69
- seen.delete(id);
70
- }
71
- }
72
- }
73
- session.lastActiveAt = Date.now();
74
- return session;
75
- }
76
- removeMessagesFromSession(conversationId, messages) {
77
- if (messages.length === 0)
78
- return;
79
- const session = this.sessions.get(conversationId);
80
- const seen = this.seenMessages.get(conversationId);
81
- if (!session && !seen)
82
- return;
83
- const droppedIds = new Set(messages.map((message) => message.id));
84
- if (session) {
85
- session.messages = session.messages.filter((message) => !droppedIds.has(message.id));
86
- }
87
- if (seen) {
88
- for (const id of droppedIds) {
89
- seen.delete(id);
90
- }
91
- }
92
- }
93
- /**
94
- * Enqueue messages for processing in a specific session.
95
- * Returns a promise that resolves when the handler completes for these messages.
96
- *
97
- * - Messages within the same session are serialized (queued).
98
- * - Messages across different sessions run concurrently up to the concurrency limit.
99
- */
100
- async enqueue(conversationId, messages, handler, options = {}) {
101
- if (this.destroyed) {
102
- await disposeInboundHandoffs(options.handoffs ?? new Map(), 'release', 'session-manager-closed');
103
- return;
104
- }
105
- const session = this.getSession(conversationId);
106
- session.lastActiveAt = Date.now();
107
- return new Promise((resolve, reject) => {
108
- // Add to this session's queue
109
- let queue = this.queues.get(conversationId);
110
- if (!queue) {
111
- queue = [];
112
- this.queues.set(conversationId, queue);
113
- }
114
- const batch = { messages, handler, resolve, reject, handoffs: options.handoffs ?? new Map() };
115
- if (options.toFront) {
116
- queue.unshift(batch);
117
- }
118
- else {
119
- queue.push(batch);
120
- }
121
- // Try to drain
122
- this.drainSession(conversationId);
123
- });
124
- }
125
- drainSession(conversationId) {
126
- // Already processing this session — the current run will pick up queued items
127
- if (this.destroyed || this.processing.has(conversationId))
128
- return;
129
- const queue = this.queues.get(conversationId);
130
- if (!queue || queue.length === 0)
131
- return;
132
- // Check concurrency limit
133
- if (this.activeCount >= this.concurrency) {
134
- // Park this session — Set.add() is atomic and idempotent, eliminating
135
- // the race between check and insert (#1)
136
- this.pending.add(conversationId);
137
- return;
138
- }
139
- // Take the next item
140
- const item = queue.shift();
141
- if (queue.length === 0)
142
- this.queues.delete(conversationId);
143
- this.activeCount++;
144
- this.processing.add(conversationId);
145
- const session = this.appendMessagesToSession(conversationId, item.messages);
146
- item.handler(session, item.messages, item.handoffs)
147
- .then(() => item.resolve())
148
- .catch((err) => item.reject(err))
149
- .finally(() => {
150
- this.processing.delete(conversationId);
151
- this.activeCount--;
152
- // Continue draining this session if more items queued
153
- const remaining = this.queues.get(conversationId);
154
- if (remaining && remaining.length > 0) {
155
- this.drainSession(conversationId);
156
- }
157
- // Unpark the next pending session.
158
- // Use Set iteration + explicit delete to get the correct conversation ID
159
- // rather than shift() which could dequeue the wrong entry (#2)
160
- if (this.pending.size > 0) {
161
- const nextId = this.pending.values().next().value;
162
- this.pending.delete(nextId);
163
- this.drainSession(nextId);
164
- }
165
- });
166
- }
167
- /** Seed a session with historical messages (e.g. fetched from API) */
168
- seedHistory(conversationId, history) {
169
- // Idempotent: only seed once per session, preventing races between
170
- // concurrent batches that both observe an empty session (#7)
171
- if (this.seededSessions.has(conversationId))
172
- return;
173
- const session = this.getSession(conversationId);
174
- // Only seed if session is empty (first time)
175
- if (session.messages.length > 0)
176
- return;
177
- this.seededSessions.add(conversationId);
178
- const seen = this.seenMessages.get(conversationId);
179
- const sliced = history.slice(-this.contextLimit);
180
- session.messages = sliced;
181
- for (const msg of sliced) {
182
- seen.add(msg.id);
183
- }
184
- }
185
- /** Remove idle sessions */
186
- sweep() {
187
- const now = Date.now();
188
- for (const [id, session] of this.sessions) {
189
- if (now - session.lastActiveAt > this.idleTimeoutMs &&
190
- !this.processing.has(id) &&
191
- !this.queues.has(id) &&
192
- !this.pending.has(id) // also skip sessions waiting for a concurrency slot (#8)
193
- ) {
194
- this.sessions.delete(id);
195
- this.seenMessages.delete(id);
196
- this.seededSessions.delete(id);
197
- }
198
- }
199
- }
200
- /** Number of queued batches waiting behind the active turn for this conversation. */
201
- getQueueDepth(conversationId) {
202
- return this.queues.get(conversationId)?.length ?? 0;
203
- }
204
- /** Drop one not-yet-running queued message for a conversation. */
205
- dropQueuedMessage(conversationId, messageId) {
206
- const queue = this.queues.get(conversationId);
207
- if (!queue || queue.length === 0)
208
- return [];
209
- const droppedMessages = [];
210
- const nextQueue = [];
211
- for (const item of queue) {
212
- const keptMessages = item.messages.filter((message) => {
213
- const drop = message.id === messageId;
214
- if (drop) {
215
- droppedMessages.push(message);
216
- void disposeInboundHandoffs(selectInboundHandoffs(item.handoffs, [message.id]), 'cancel', 'message-deleted');
217
- }
218
- return !drop;
219
- });
220
- if (keptMessages.length === 0) {
221
- item.resolve();
222
- }
223
- else if (keptMessages.length !== item.messages.length) {
224
- nextQueue.push({ ...item, messages: keptMessages, handoffs: selectInboundHandoffs(item.handoffs, keptMessages.map((message) => message.id)) });
225
- }
226
- else {
227
- nextQueue.push(item);
228
- }
229
- }
230
- if (droppedMessages.length === 0)
231
- return [];
232
- if (nextQueue.length === 0) {
233
- this.queues.delete(conversationId);
234
- this.pending.delete(conversationId);
235
- }
236
- else {
237
- this.queues.set(conversationId, nextQueue);
238
- }
239
- this.removeMessagesFromSession(conversationId, droppedMessages);
240
- return droppedMessages;
241
- }
242
- /** Drop queued, not-yet-running batches for a conversation. */
243
- dropQueued(conversationId) {
244
- const queue = this.queues.get(conversationId);
245
- if (!queue || queue.length === 0)
246
- return [];
247
- this.queues.delete(conversationId);
248
- this.pending.delete(conversationId);
249
- const droppedMessages = queue.flatMap((item) => item.messages);
250
- this.removeMessagesFromSession(conversationId, droppedMessages);
251
- for (const item of queue) {
252
- void disposeInboundHandoffs(item.handoffs, 'cancel', 'queue-dropped');
253
- item.resolve();
254
- }
255
- return droppedMessages;
256
- }
257
- /** Drop queued work and clear retained context for a conversation. */
258
- resetSession(conversationId) {
259
- const droppedMessages = this.dropQueued(conversationId);
260
- this.sessions.delete(conversationId);
261
- this.seenMessages.delete(conversationId);
262
- this.seededSessions.delete(conversationId);
263
- return droppedMessages;
264
- }
265
- /** Clean up all state */
266
- destroy() {
267
- this.destroyed = true;
268
- for (const queue of this.queues.values()) {
269
- for (const item of queue) {
270
- void disposeInboundHandoffs(item.handoffs, 'release', 'session-manager-closed');
271
- item.resolve();
272
- }
273
- }
274
- if (this.sweepTimer) {
275
- clearInterval(this.sweepTimer);
276
- this.sweepTimer = null;
277
- }
278
- this.sessions.clear();
279
- this.queues.clear();
280
- this.pending.clear();
281
- this.processing.clear();
282
- this.seenMessages.clear();
283
- this.seededSessions.clear();
284
- }
285
- }
@@ -1,17 +0,0 @@
1
- import type { CanonClient, TurnOutputSnapshot } from '@canonmsg/core';
2
- export type TurnStreamingRequest = Parameters<CanonClient['setStreaming']>[0];
3
- /**
4
- * Builds the `POST /streaming` body for one turn-output snapshot.
5
- *
6
- * Extracted from the turn loop for one reason: `blocks` must be forwarded
7
- * VERBATIM, empty array included. `POST /streaming` merges into the RTDB node,
8
- * so an absent `blocks` key leaves the previous trail in place — and the
9
- * `onStreamingCleared` trigger rebuilds salvage text out of block titles. A
10
- * silent turn blanks the node with `text: ''` and `blocks: []`; drop the empty
11
- * array on the way out and the turn the model declined to send comes back as a
12
- * durable bubble made of its own tool-trail headings.
13
- */
14
- export declare function buildTurnStreamingRequest(input: {
15
- conversationId: string;
16
- snapshot: TurnOutputSnapshot;
17
- }): TurnStreamingRequest;
@@ -1,22 +0,0 @@
1
- /**
2
- * Builds the `POST /streaming` body for one turn-output snapshot.
3
- *
4
- * Extracted from the turn loop for one reason: `blocks` must be forwarded
5
- * VERBATIM, empty array included. `POST /streaming` merges into the RTDB node,
6
- * so an absent `blocks` key leaves the previous trail in place — and the
7
- * `onStreamingCleared` trigger rebuilds salvage text out of block titles. A
8
- * silent turn blanks the node with `text: ''` and `blocks: []`; drop the empty
9
- * array on the way out and the turn the model declined to send comes back as a
10
- * durable bubble made of its own tool-trail headings.
11
- */
12
- export function buildTurnStreamingRequest(input) {
13
- const { conversationId, snapshot } = input;
14
- return {
15
- conversationId,
16
- text: snapshot.text,
17
- status: snapshot.status,
18
- messageId: snapshot.messageId,
19
- turnId: snapshot.turnId,
20
- blocks: snapshot.blocks,
21
- };
22
- }
@@ -1,33 +0,0 @@
1
- import { type TurnVerbosityConfig, type TurnVerbosityConversationType } from '@canonmsg/core';
2
- /**
3
- * What a developer may write for `CanonAgentOptions.turnVerbosity`.
4
- *
5
- * The SDK is the one runtime where a per-conversation-type OBJECT is idiomatic:
6
- * it has no argv and no config file, so `{ group: 'verbose' }` costs a
7
- * developer nothing while the hosts would have to invent a flag grammar for the
8
- * same thing. Everything else — the vocabulary, the defaults, `'auto'` ≡ unset
9
- * — stays in core's `resolveTurnVerbosity`, which this folds into rather than
10
- * reimplements.
11
- *
12
- * Deliberately NOT promoted to `@canonmsg/core`: the Claude host, the Codex
13
- * host, OpenClaw and Hermes all take a scalar (a CLI flag, an env var or a
14
- * config-file string), so core would grow a shape with exactly one consumer.
15
- */
16
- export type CanonAgentTurnVerbosityOption = TurnVerbosityConfig | {
17
- /** Applies to direct chats — Hermes's `'dm'` spelling included. */
18
- direct?: TurnVerbosityConfig;
19
- group?: TurnVerbosityConfig;
20
- };
21
- /**
22
- * Picks the configured value this turn's conversation type is subject to, in
23
- * the shape `resolveTurnVerbosity` takes.
24
- *
25
- * `null` means "nothing configured for this type" and lets core's per-type
26
- * default decide — which is also what an `'auto'` entry and an unrecognized
27
- * string produce, so an object that names only `group` leaves DMs on the
28
- * default rather than forcing them anywhere. A conversation type that resolves
29
- * to `'unknown'` (the fetch failed, or provenance was absent) matches no key
30
- * and therefore falls through to the fail-open default too: an object form
31
- * cannot silence a turn whose shape Canon could not name.
32
- */
33
- export declare function selectConfiguredTurnVerbosity(option: CanonAgentTurnVerbosityOption | null | undefined, conversationType: TurnVerbosityConversationType | null | undefined): TurnVerbosityConfig | null;
@@ -1,23 +0,0 @@
1
- import { normalizeTurnVerbosityConversationType, parseTurnVerbosityConfig, } from '@canonmsg/core';
2
- /**
3
- * Picks the configured value this turn's conversation type is subject to, in
4
- * the shape `resolveTurnVerbosity` takes.
5
- *
6
- * `null` means "nothing configured for this type" and lets core's per-type
7
- * default decide — which is also what an `'auto'` entry and an unrecognized
8
- * string produce, so an object that names only `group` leaves DMs on the
9
- * default rather than forcing them anywhere. A conversation type that resolves
10
- * to `'unknown'` (the fetch failed, or provenance was absent) matches no key
11
- * and therefore falls through to the fail-open default too: an object form
12
- * cannot silence a turn whose shape Canon could not name.
13
- */
14
- export function selectConfiguredTurnVerbosity(option, conversationType) {
15
- if (option === null || option === undefined)
16
- return null;
17
- if (typeof option === 'string')
18
- return parseTurnVerbosityConfig(option);
19
- const key = normalizeTurnVerbosityConversationType(conversationType);
20
- if (key === 'unknown')
21
- return null;
22
- return parseTurnVerbosityConfig(option[key]);
23
- }