crewly 1.20.149 → 1.20.150

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 (129) hide show
  1. package/dist/backend/backend/src/constants.d.ts +76 -0
  2. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  3. package/dist/backend/backend/src/constants.js +77 -0
  4. package/dist/backend/backend/src/constants.js.map +1 -1
  5. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts +1 -0
  6. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts.map +1 -1
  7. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js +22 -0
  8. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js.map +1 -1
  9. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.d.ts +1 -0
  10. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.d.ts.map +1 -1
  11. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.js +2 -0
  12. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.js.map +1 -1
  13. package/dist/backend/backend/src/controllers/messaging/messenger.routes.d.ts.map +1 -1
  14. package/dist/backend/backend/src/controllers/messaging/messenger.routes.js +42 -1
  15. package/dist/backend/backend/src/controllers/messaging/messenger.routes.js.map +1 -1
  16. package/dist/backend/backend/src/index.d.ts +8 -0
  17. package/dist/backend/backend/src/index.d.ts.map +1 -1
  18. package/dist/backend/backend/src/index.js +62 -0
  19. package/dist/backend/backend/src/index.js.map +1 -1
  20. package/dist/backend/backend/src/services/chat-v2/chat-v2.relay-adapter.service.d.ts.map +1 -1
  21. package/dist/backend/backend/src/services/chat-v2/chat-v2.relay-adapter.service.js +3 -0
  22. package/dist/backend/backend/src/services/chat-v2/chat-v2.relay-adapter.service.js.map +1 -1
  23. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts +94 -2
  24. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -1
  25. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js +183 -2
  26. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js.map +1 -1
  27. package/dist/backend/backend/src/services/chat-v2/owner-inbound.utils.d.ts +70 -0
  28. package/dist/backend/backend/src/services/chat-v2/owner-inbound.utils.d.ts.map +1 -1
  29. package/dist/backend/backend/src/services/chat-v2/owner-inbound.utils.js +78 -0
  30. package/dist/backend/backend/src/services/chat-v2/owner-inbound.utils.js.map +1 -1
  31. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.d.ts.map +1 -1
  32. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.js +9 -0
  33. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.js.map +1 -1
  34. package/dist/backend/backend/src/services/chat-v2/sqlite/cloud-outbox.store.d.ts +136 -0
  35. package/dist/backend/backend/src/services/chat-v2/sqlite/cloud-outbox.store.d.ts.map +1 -0
  36. package/dist/backend/backend/src/services/chat-v2/sqlite/cloud-outbox.store.js +207 -0
  37. package/dist/backend/backend/src/services/chat-v2/sqlite/cloud-outbox.store.js.map +1 -0
  38. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts +62 -1
  39. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts.map +1 -1
  40. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js +111 -4
  41. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js.map +1 -1
  42. package/dist/backend/backend/src/services/chat-v2/sqlite/unified-log.d.ts +206 -0
  43. package/dist/backend/backend/src/services/chat-v2/sqlite/unified-log.d.ts.map +1 -0
  44. package/dist/backend/backend/src/services/chat-v2/sqlite/unified-log.js +442 -0
  45. package/dist/backend/backend/src/services/chat-v2/sqlite/unified-log.js.map +1 -0
  46. package/dist/backend/backend/src/services/chat-v2/types.d.ts +29 -0
  47. package/dist/backend/backend/src/services/chat-v2/types.d.ts.map +1 -1
  48. package/dist/backend/backend/src/services/chat-v2/types.js.map +1 -1
  49. package/dist/backend/backend/src/services/cloud/conversation-cloud-sync.service.d.ts +209 -0
  50. package/dist/backend/backend/src/services/cloud/conversation-cloud-sync.service.d.ts.map +1 -0
  51. package/dist/backend/backend/src/services/cloud/conversation-cloud-sync.service.js +607 -0
  52. package/dist/backend/backend/src/services/cloud/conversation-cloud-sync.service.js.map +1 -0
  53. package/dist/backend/backend/src/services/cloud/conversation-ingest.contract.d.ts +167 -0
  54. package/dist/backend/backend/src/services/cloud/conversation-ingest.contract.d.ts.map +1 -0
  55. package/dist/backend/backend/src/services/cloud/conversation-ingest.contract.js +127 -0
  56. package/dist/backend/backend/src/services/cloud/conversation-ingest.contract.js.map +1 -0
  57. package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.d.ts.map +1 -1
  58. package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js +4 -0
  59. package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js.map +1 -1
  60. package/dist/backend/backend/src/services/messaging/google-chat-initializer.d.ts.map +1 -1
  61. package/dist/backend/backend/src/services/messaging/google-chat-initializer.js +11 -1
  62. package/dist/backend/backend/src/services/messaging/google-chat-initializer.js.map +1 -1
  63. package/dist/backend/backend/src/services/slack/slack-agent-dm.service.d.ts +1 -1
  64. package/dist/backend/backend/src/services/slack/slack-agent-dm.service.d.ts.map +1 -1
  65. package/dist/backend/backend/src/services/slack/slack-agent-dm.service.js +13 -0
  66. package/dist/backend/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
  67. package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
  68. package/dist/backend/backend/src/services/slack/slack-initializer.js +13 -0
  69. package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
  70. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +14 -1
  71. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  72. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +34 -2
  73. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  74. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  75. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +1 -0
  76. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  77. package/dist/backend/backend/src/services/telegram/telegram-orchestrator-bridge.d.ts +10 -0
  78. package/dist/backend/backend/src/services/telegram/telegram-orchestrator-bridge.d.ts.map +1 -1
  79. package/dist/backend/backend/src/services/telegram/telegram-orchestrator-bridge.js +27 -2
  80. package/dist/backend/backend/src/services/telegram/telegram-orchestrator-bridge.js.map +1 -1
  81. package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.d.ts +10 -0
  82. package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.d.ts.map +1 -1
  83. package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.js +27 -4
  84. package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.js.map +1 -1
  85. package/dist/backend/backend/src/types/slack.types.d.ts +12 -0
  86. package/dist/backend/backend/src/types/slack.types.d.ts.map +1 -1
  87. package/dist/backend/backend/src/types/slack.types.js.map +1 -1
  88. package/dist/backend/build-info.json +2 -2
  89. package/dist/cli/backend/src/constants.d.ts +76 -0
  90. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  91. package/dist/cli/backend/src/constants.js +77 -0
  92. package/dist/cli/backend/src/constants.js.map +1 -1
  93. package/dist/cli/backend/src/services/chat-v2/chat-v2.service.d.ts +94 -2
  94. package/dist/cli/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -1
  95. package/dist/cli/backend/src/services/chat-v2/chat-v2.service.js +183 -2
  96. package/dist/cli/backend/src/services/chat-v2/chat-v2.service.js.map +1 -1
  97. package/dist/cli/backend/src/services/chat-v2/sqlite/chat-db.d.ts.map +1 -1
  98. package/dist/cli/backend/src/services/chat-v2/sqlite/chat-db.js +9 -0
  99. package/dist/cli/backend/src/services/chat-v2/sqlite/chat-db.js.map +1 -1
  100. package/dist/cli/backend/src/services/chat-v2/sqlite/cloud-outbox.store.d.ts +136 -0
  101. package/dist/cli/backend/src/services/chat-v2/sqlite/cloud-outbox.store.d.ts.map +1 -0
  102. package/dist/cli/backend/src/services/chat-v2/sqlite/cloud-outbox.store.js +207 -0
  103. package/dist/cli/backend/src/services/chat-v2/sqlite/cloud-outbox.store.js.map +1 -0
  104. package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.d.ts +62 -1
  105. package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.d.ts.map +1 -1
  106. package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.js +111 -4
  107. package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.js.map +1 -1
  108. package/dist/cli/backend/src/services/chat-v2/sqlite/unified-log.d.ts +206 -0
  109. package/dist/cli/backend/src/services/chat-v2/sqlite/unified-log.d.ts.map +1 -0
  110. package/dist/cli/backend/src/services/chat-v2/sqlite/unified-log.js +442 -0
  111. package/dist/cli/backend/src/services/chat-v2/sqlite/unified-log.js.map +1 -0
  112. package/dist/cli/backend/src/services/chat-v2/types.d.ts +29 -0
  113. package/dist/cli/backend/src/services/chat-v2/types.d.ts.map +1 -1
  114. package/dist/cli/backend/src/services/chat-v2/types.js.map +1 -1
  115. package/dist/cli/backend/src/services/slack/slack-agent-dm.service.d.ts +1 -1
  116. package/dist/cli/backend/src/services/slack/slack-agent-dm.service.d.ts.map +1 -1
  117. package/dist/cli/backend/src/services/slack/slack-agent-dm.service.js +13 -0
  118. package/dist/cli/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
  119. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts +14 -1
  120. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  121. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js +34 -2
  122. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  123. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  124. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +1 -0
  125. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  126. package/dist/cli/backend/src/types/slack.types.d.ts +12 -0
  127. package/dist/cli/backend/src/types/slack.types.d.ts.map +1 -1
  128. package/dist/cli/backend/src/types/slack.types.js.map +1 -1
  129. package/package.json +1 -1
@@ -0,0 +1,607 @@
1
+ /**
2
+ * ConversationCloudSyncService — uploads this machine's conversation log to
3
+ * Crewly Cloud (specs/unified-conversations-cloud-store.md §B).
4
+ *
5
+ * - **Live:** drains `cloud_outbox` (filled by triggers on `chat_messages`)
6
+ * in `seq` order, one request in flight, batches of ≤ 50 messages /
7
+ * 256 KB, gzip. Wakes on every new chat message (after a 2 s gather) and
8
+ * on a 10 s tick. Rows leave the outbox only once Cloud acknowledged them.
9
+ * - **Backfill:** after first sign-in (or an account switch, or a plan
10
+ * upgrade that widens the window) it re-sends the history inside the
11
+ * plan's retention window, oldest first, at most one request a second,
12
+ * after the live queue.
13
+ * - **Disconnected / signed out:** the outbox stays on disk; it is only
14
+ * trimmed (older than 90 days, more than 200k rows — a history gap).
15
+ * - **Failures:** exponential backoff 1 s → 5 min. A 404 (Cloud has no
16
+ * conversation store yet), `403 sync_disabled`, `503` key missing or a
17
+ * `400` batch Cloud refuses pause sync for an hour, logged once.
18
+ * - **O1:** on by default for a signed-in machine; the owner gets one Slack
19
+ * DM the first time history reaches Cloud. `CREWLY_CONVERSATION_SYNC=0`
20
+ * (or `CREWLY_CLOUD_CONVERSATIONS=off`) turns uploading off; the outbox
21
+ * still fills.
22
+ * - **O4:** text only — attachments go as name / size / mime.
23
+ *
24
+ * The wire contract lives in `conversation-ingest.contract.ts`.
25
+ *
26
+ * @module services/cloud/conversation-cloud-sync.service
27
+ */
28
+ import { gzipSync } from 'zlib';
29
+ import { randomUUID } from 'crypto';
30
+ import { CONVERSATION_SYNC_CONSTANTS, ORCHESTRATOR_SESSION_NAME } from '../../constants.js';
31
+ import { LoggerService } from '../core/logger.service.js';
32
+ import { CONVERSATION_DIRECTIONS, CONVERSATION_INGEST_PATH, CONVERSATION_SOURCES, INGEST_ERROR_CODES, INGEST_LIMITS, INSTANCE_ID_PATTERN, SENDER_KINDS, isOneOf, parseIngestErrorCode, parseIngestResponse, } from './conversation-ingest.contract.js';
33
+ const C = CONVERSATION_SYNC_CONSTANTS;
34
+ const K = C.STATE_KEYS;
35
+ const DAY_MS = 24 * 60 * 60 * 1000;
36
+ /**
37
+ * Whether the kill switch is set.
38
+ *
39
+ * @param env - Environment
40
+ * @returns True when uploading is switched off
41
+ */
42
+ export function isConversationSyncDisabled(env) {
43
+ const off = (v) => typeof v === 'string' && ['0', 'off', 'false', 'no'].includes(v.trim().toLowerCase());
44
+ return off(env[C.ENV_SWITCH]) || off(env[C.ENV_SWITCH_ALT]);
45
+ }
46
+ /**
47
+ * The account a Cloud access token belongs to — the JWT `sub`, read without
48
+ * verifying. An opaque token yields a constant, so token refreshes are never
49
+ * mistaken for an account switch.
50
+ *
51
+ * @param token - Access token
52
+ * @returns The account id
53
+ */
54
+ export function accountIdOfToken(token) {
55
+ const parts = token.split('.');
56
+ if (parts.length === 3) {
57
+ try {
58
+ const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf8'));
59
+ if (typeof payload.sub === 'string' && payload.sub.length > 0)
60
+ return payload.sub;
61
+ }
62
+ catch {
63
+ // not a JWT
64
+ }
65
+ }
66
+ return 'opaque-token';
67
+ }
68
+ /**
69
+ * Parse a JSON column without throwing.
70
+ *
71
+ * @param raw - Column value
72
+ * @returns The value, or undefined
73
+ */
74
+ function parseJson(raw) {
75
+ if (!raw)
76
+ return undefined;
77
+ try {
78
+ return JSON.parse(raw);
79
+ }
80
+ catch {
81
+ return undefined;
82
+ }
83
+ }
84
+ /**
85
+ * Map one stored message to the wire shape.
86
+ *
87
+ * @param row - Message row with its channel and attachment metadata
88
+ * @param localSeq - Outbox seq (live) or 0 (backfill)
89
+ * @returns The upsert, or null when the row must not leave the machine
90
+ */
91
+ export function toIngestUpsert(row, localSeq) {
92
+ if (row.cloudSync === 0)
93
+ return null;
94
+ const mentionsRaw = parseJson(row.mentions);
95
+ const mentions = Array.isArray(mentionsRaw) ? mentionsRaw.filter((m) => typeof m === 'string' && m.length > 0) : [];
96
+ const metadata = parseJson(row.metadata);
97
+ const md = metadata && typeof metadata === 'object' && !Array.isArray(metadata) ? metadata : {};
98
+ const extRaw = parseJson(row.extRef);
99
+ const ext = extRaw && typeof extRaw === 'object' && !Array.isArray(extRaw) && Object.keys(extRaw).length > 0 ? extRaw : undefined;
100
+ const source = isOneOf(CONVERSATION_SOURCES, row.source) ? row.source : 'crewly-chat';
101
+ const direction = isOneOf(CONVERSATION_DIRECTIONS, row.direction)
102
+ ? row.direction
103
+ : row.senderType === 'agent'
104
+ ? 'out'
105
+ : row.senderType === 'system'
106
+ ? 'internal'
107
+ : 'in';
108
+ const senderKind = isOneOf(SENDER_KINDS, row.senderKind)
109
+ ? row.senderKind
110
+ : row.senderType === 'user'
111
+ ? 'owner'
112
+ : row.senderType;
113
+ const agentSession = row.agentSession || mentions[0] || row.leadMember || ORCHESTRATOR_SESSION_NAME;
114
+ // A Slack person is identified by their Slack id; the display name rides along.
115
+ const slackUserId = typeof ext?.slackUserId === 'string' ? ext.slackUserId : undefined;
116
+ const sender = row.senderType === 'user' && source === 'slack' && slackUserId && slackUserId !== row.senderId
117
+ ? { id: slackUserId, name: row.senderId }
118
+ : { id: row.senderId || row.senderType };
119
+ const clientMessageId = source === 'cloud-talk' && typeof md.clientMessageId === 'string' ? md.clientMessageId : undefined;
120
+ return {
121
+ localId: row.id,
122
+ op: 'upsert',
123
+ channel: { localId: row.channelId, kind: row.channelType, name: row.channelName },
124
+ agentSession,
125
+ ...(mentions.length > 0 ? { mentions } : {}),
126
+ source,
127
+ direction,
128
+ senderKind,
129
+ sender,
130
+ ...(ext ? { ext } : {}),
131
+ ...(row.threadId ? { threadLocalId: row.threadId } : {}),
132
+ text: row.content,
133
+ contentType: row.contentType,
134
+ attachments: row.attachments.map((a) => ({
135
+ kind: a.kind,
136
+ mime: a.mimeType,
137
+ size: a.sizeBytes,
138
+ ...(a.originalName ? { name: a.originalName } : {}),
139
+ })),
140
+ ...(clientMessageId ? { clientMessageId } : {}),
141
+ createdAt: row.createdAt,
142
+ localSeq,
143
+ };
144
+ }
145
+ /**
146
+ * Bytes one message adds to a request body (JSON, before gzip).
147
+ *
148
+ * @param message - Wire message
149
+ * @returns Approximate byte size
150
+ */
151
+ function sizeOf(message) {
152
+ return Buffer.byteLength(JSON.stringify(message), 'utf8') + 1;
153
+ }
154
+ // ---------------------------------------------------------------------------
155
+ // Service
156
+ // ---------------------------------------------------------------------------
157
+ /** Uploads the machine's conversation log to Crewly Cloud. */
158
+ export class ConversationCloudSyncService {
159
+ deps;
160
+ logger;
161
+ fetchImpl;
162
+ now;
163
+ setTimer;
164
+ clearTimer;
165
+ started = false;
166
+ running = false;
167
+ rerun = false;
168
+ tickTimer = null;
169
+ wakeTimer = null;
170
+ unsubscribe = null;
171
+ /** Consecutive failures; drives the exponential backoff. */
172
+ failures = 0;
173
+ /** No request before this time (backoff or an hour-long pause). */
174
+ pausedUntil = 0;
175
+ /** Reasons already logged, so a long pause logs once. */
176
+ loggedPauses = new Set();
177
+ /** Current live batch cap; halved on 413. */
178
+ batchLimit = C.BATCH_MAX_MESSAGES;
179
+ lastBackfillAt = 0;
180
+ lastNoticeAttemptAt = 0;
181
+ gapLogged = false;
182
+ constructor(deps) {
183
+ this.deps = deps;
184
+ this.logger = deps.logger ?? LoggerService.getInstance().createComponentLogger('ConversationCloudSync');
185
+ this.fetchImpl = deps.fetchImpl ?? ((input, init) => fetch(input, init));
186
+ this.now = deps.now ?? Date.now;
187
+ this.setTimer = deps.setTimeout ?? ((fn, ms) => setTimeout(fn, ms));
188
+ this.clearTimer = deps.clearTimeout ?? ((h) => clearTimeout(h));
189
+ }
190
+ /** Start the tick and the new-message wake-up. Idempotent; never throws. */
191
+ start() {
192
+ if (this.started)
193
+ return;
194
+ this.started = true;
195
+ if (isConversationSyncDisabled(this.deps.env ?? process.env)) {
196
+ this.logger.info('Conversation sync to Crewly Cloud is off (CREWLY_CONVERSATION_SYNC=0); the local log still fills');
197
+ }
198
+ try {
199
+ this.unsubscribe = this.deps.onNewMessage?.(() => this.wake()) ?? null;
200
+ }
201
+ catch {
202
+ this.unsubscribe = null;
203
+ }
204
+ this.scheduleTick();
205
+ this.wake(0);
206
+ }
207
+ /** Stop timers and the wake-up subscription. */
208
+ stop() {
209
+ this.started = false;
210
+ if (this.tickTimer)
211
+ this.clearTimer(this.tickTimer);
212
+ if (this.wakeTimer)
213
+ this.clearTimer(this.wakeTimer);
214
+ this.tickTimer = null;
215
+ this.wakeTimer = null;
216
+ try {
217
+ this.unsubscribe?.();
218
+ }
219
+ catch {
220
+ // ignore
221
+ }
222
+ this.unsubscribe = null;
223
+ }
224
+ /**
225
+ * Run one sync pass now (tests, and the timers). Never throws; a pass
226
+ * already in flight makes this one run again right after it.
227
+ */
228
+ async syncNow() {
229
+ if (this.running) {
230
+ this.rerun = true;
231
+ return;
232
+ }
233
+ this.running = true;
234
+ try {
235
+ do {
236
+ this.rerun = false;
237
+ await this.pass();
238
+ } while (this.rerun);
239
+ }
240
+ catch (error) {
241
+ this.logger.warn('Conversation sync pass failed', { error: error instanceof Error ? error.message : String(error) });
242
+ }
243
+ finally {
244
+ this.running = false;
245
+ }
246
+ }
247
+ /**
248
+ * Schedule a pass after a new message: immediately once a full batch is
249
+ * waiting, otherwise after the gather delay.
250
+ *
251
+ * @param delayMs - Override the delay
252
+ */
253
+ wake(delayMs) {
254
+ if (!this.started)
255
+ return;
256
+ let delay = delayMs;
257
+ if (delay === undefined) {
258
+ let waiting = 0;
259
+ try {
260
+ waiting = this.deps.outbox.count();
261
+ }
262
+ catch {
263
+ waiting = 0;
264
+ }
265
+ delay = waiting >= this.batchLimit ? 0 : C.BATCH_MAX_WAIT_MS;
266
+ }
267
+ if (this.wakeTimer)
268
+ return;
269
+ this.wakeTimer = this.setTimer(() => {
270
+ this.wakeTimer = null;
271
+ void this.syncNow();
272
+ }, delay);
273
+ }
274
+ /** Keep the periodic tick going. */
275
+ scheduleTick() {
276
+ if (!this.started)
277
+ return;
278
+ this.tickTimer = this.setTimer(() => {
279
+ this.tickTimer = null;
280
+ void this.syncNow().finally(() => this.scheduleTick());
281
+ }, C.TICK_INTERVAL_MS);
282
+ }
283
+ /** One pass: trim, check the session, drain live, then one backfill step. */
284
+ async pass() {
285
+ this.trimOutbox();
286
+ if (isConversationSyncDisabled(this.deps.env ?? process.env))
287
+ return;
288
+ const token = this.deps.cloud.getToken();
289
+ const base = this.deps.cloud.getCloudUrl();
290
+ if (!token || !base)
291
+ return;
292
+ if (this.now() < this.pausedUntil)
293
+ return;
294
+ this.checkAccount(token);
295
+ const { instanceId, deviceName } = await this.deps.identity();
296
+ if (!INSTANCE_ID_PATTERN.test(instanceId)) {
297
+ this.pause('invalid_batch', `instance id "${instanceId}" is not accepted by Cloud`);
298
+ return;
299
+ }
300
+ const version = (await this.deps.crewlyVersion?.().catch(() => undefined)) ?? undefined;
301
+ const envelope = { instanceId, deviceName, version };
302
+ // The plan window comes from an empty ingest (spec §B.4).
303
+ if (!this.deps.outbox.getState(K.RETENTION_DAYS)) {
304
+ const probe = await this.send(base, token, envelope, 'live', []);
305
+ if (!this.settle(probe))
306
+ return;
307
+ }
308
+ if (!(await this.drainLive(base, token, envelope)))
309
+ return;
310
+ await this.backfillStep(base, token, envelope);
311
+ }
312
+ /**
313
+ * Upload every waiting outbox row, oldest first.
314
+ *
315
+ * @returns False when a request failed (the pass stops)
316
+ */
317
+ async drainLive(base, token, envelope) {
318
+ for (;;) {
319
+ const entries = this.deps.outbox.peek(this.batchLimit);
320
+ if (entries.length === 0)
321
+ return true;
322
+ const rows = this.deps.outbox.getMessages(entries.filter((e) => e.op === 'upsert').map((e) => e.messageId));
323
+ const messages = [];
324
+ let bytes = 0;
325
+ let lastSeq = entries[0].seq - 1;
326
+ for (const entry of entries) {
327
+ let message;
328
+ if (entry.op === 'delete') {
329
+ message = { localId: entry.messageId, localSeq: entry.seq, op: 'delete' };
330
+ }
331
+ else {
332
+ const row = rows.get(entry.messageId);
333
+ // Deleted since, or not for Cloud: settled without sending.
334
+ message = row ? toIngestUpsert(row, entry.seq) : null;
335
+ }
336
+ if (message) {
337
+ const size = sizeOf(message);
338
+ if (messages.length > 0 && bytes + size > C.BATCH_MAX_BYTES)
339
+ break;
340
+ messages.push(message);
341
+ bytes += size;
342
+ }
343
+ lastSeq = entry.seq;
344
+ }
345
+ if (messages.length === 0) {
346
+ this.deps.outbox.ackThrough(lastSeq);
347
+ continue;
348
+ }
349
+ const outcome = await this.send(base, token, envelope, 'live', messages);
350
+ if (!outcome.ok && outcome.status === 413) {
351
+ if (messages.length > 1) {
352
+ this.batchLimit = Math.max(1, Math.floor(messages.length / 2));
353
+ continue;
354
+ }
355
+ // One message Cloud will never take: drop it rather than wedge the outbox.
356
+ this.logger.warn('Cloud refused a message as too large; skipping it', { localId: messages[0].localId });
357
+ this.deps.outbox.ackThrough(lastSeq);
358
+ continue;
359
+ }
360
+ if (!this.settle(outcome))
361
+ return false;
362
+ const acked = outcome.ok ? outcome.response.ackedThroughLocalSeq : null;
363
+ this.deps.outbox.ackThrough(acked === null ? lastSeq : Math.min(acked, lastSeq));
364
+ if (acked !== null && acked < lastSeq)
365
+ return true; // Cloud settled less; resume next pass.
366
+ }
367
+ }
368
+ /**
369
+ * Send one page of history when a backfill is owed (first sign-in, account
370
+ * switch, or a wider window after an upgrade). At most one request per
371
+ * second; live rows always go first.
372
+ */
373
+ async backfillStep(base, token, envelope) {
374
+ const retention = Number(this.deps.outbox.getState(K.RETENTION_DAYS)) || C.DEFAULT_RETENTION_DAYS;
375
+ const doneFor = Number(this.deps.outbox.getState(K.BACKFILL_RETENTION_DAYS)) || 0;
376
+ if (this.deps.outbox.getState(K.BACKFILL_DONE_AT) && doneFor >= retention)
377
+ return;
378
+ if (this.deps.outbox.getState(K.BACKFILL_DONE_AT) && doneFor < retention) {
379
+ // Plan upgrade: a wider window — send it again from the start.
380
+ this.deps.outbox.setState(K.BACKFILL_DONE_AT, null);
381
+ this.deps.outbox.setState(K.BACKFILL_CURSOR, null);
382
+ }
383
+ const sinceLast = this.now() - this.lastBackfillAt;
384
+ if (sinceLast < C.BACKFILL_MIN_INTERVAL_MS) {
385
+ this.wake(C.BACKFILL_MIN_INTERVAL_MS - sinceLast);
386
+ return;
387
+ }
388
+ if (!this.deps.outbox.getState(K.BACKFILL_CURSOR)) {
389
+ try {
390
+ this.deps.reclassifyOwnerRows?.();
391
+ }
392
+ catch {
393
+ // best effort
394
+ }
395
+ }
396
+ const cursorRaw = parseJson(this.deps.outbox.getState(K.BACKFILL_CURSOR));
397
+ const cursor = cursorRaw && typeof cursorRaw.createdAt === 'number' && typeof cursorRaw.rowid === 'number' ? cursorRaw : null;
398
+ const since = this.now() - retention * DAY_MS;
399
+ const page = this.deps.outbox.backfillPage(since, cursor, Math.min(C.BACKFILL_PAGE_SIZE, INGEST_LIMITS.MAX_MESSAGES));
400
+ if (page.length === 0) {
401
+ this.deps.outbox.setState(K.BACKFILL_DONE_AT, String(this.now()));
402
+ this.deps.outbox.setState(K.BACKFILL_RETENTION_DAYS, String(retention));
403
+ this.deps.outbox.setState(K.BACKFILL_CURSOR, null);
404
+ this.logger.info('Conversation history backfill to Crewly Cloud finished', { retentionDays: retention });
405
+ return;
406
+ }
407
+ const messages = [];
408
+ let bytes = 0;
409
+ let last = page[0];
410
+ for (const row of page) {
411
+ const message = toIngestUpsert(row, 0);
412
+ if (message) {
413
+ const size = sizeOf(message);
414
+ if (messages.length > 0 && bytes + size > C.BACKFILL_BATCH_MAX_BYTES)
415
+ break;
416
+ messages.push(message);
417
+ bytes += size;
418
+ }
419
+ last = row;
420
+ }
421
+ this.lastBackfillAt = this.now();
422
+ if (messages.length > 0) {
423
+ const outcome = await this.send(base, token, envelope, 'backfill', messages);
424
+ if (!this.settle(outcome))
425
+ return;
426
+ }
427
+ this.deps.outbox.setState(K.BACKFILL_CURSOR, JSON.stringify({ createdAt: last.createdAt, rowid: last.rowid }));
428
+ this.wake(C.BACKFILL_MIN_INTERVAL_MS);
429
+ }
430
+ /**
431
+ * POST one batch (gzip). Never throws.
432
+ *
433
+ * @returns The parsed outcome
434
+ */
435
+ async send(base, token, envelope, mode, messages) {
436
+ const body = {
437
+ instanceId: envelope.instanceId,
438
+ ...(this.deps.homeId ? { homeId: this.deps.homeId } : {}),
439
+ ...(envelope.version ? { crewlyVersion: envelope.version } : {}),
440
+ ...(envelope.deviceName ? { deviceName: envelope.deviceName } : {}),
441
+ batchId: randomUUID(),
442
+ mode,
443
+ messages,
444
+ };
445
+ const url = `${base.replace(/\/$/, '')}${CONVERSATION_INGEST_PATH}`;
446
+ let response;
447
+ try {
448
+ response = await this.fetchImpl(url, {
449
+ method: 'POST',
450
+ headers: {
451
+ Authorization: `Bearer ${token}`,
452
+ 'Content-Type': 'application/json',
453
+ 'Content-Encoding': 'gzip',
454
+ },
455
+ body: gzipSync(Buffer.from(JSON.stringify(body), 'utf8')),
456
+ signal: AbortSignal.timeout(C.REQUEST_TIMEOUT_MS),
457
+ });
458
+ }
459
+ catch (error) {
460
+ return { ok: false, status: 0, code: null, message: error instanceof Error ? error.message : String(error) };
461
+ }
462
+ const parsed = (await response.json().catch(() => null));
463
+ if (response.ok)
464
+ return { ok: true, response: parseIngestResponse(parsed) };
465
+ return {
466
+ ok: false,
467
+ status: response.status,
468
+ code: parseIngestErrorCode(parsed),
469
+ message: `HTTP ${response.status}`,
470
+ };
471
+ }
472
+ /**
473
+ * Book the result of a request: remember the retention window, reset or
474
+ * advance the backoff, pause on the hour-long conditions.
475
+ *
476
+ * @returns True on success
477
+ */
478
+ settle(outcome) {
479
+ if (outcome.ok) {
480
+ this.failures = 0;
481
+ this.pausedUntil = 0;
482
+ this.batchLimit = C.BATCH_MAX_MESSAGES;
483
+ if (this.loggedPauses.size > 0) {
484
+ this.logger.info('Crewly Cloud is taking conversation history again');
485
+ this.loggedPauses.clear();
486
+ }
487
+ const days = outcome.response.retentionDays;
488
+ if (days !== null && days > 0)
489
+ this.deps.outbox.setState(K.RETENTION_DAYS, String(days));
490
+ this.deps.outbox.setState(K.LAST_INGEST_AT, String(this.now()));
491
+ void this.maybeNotifyOwner();
492
+ return true;
493
+ }
494
+ const { status, code } = outcome;
495
+ if (status === 404) {
496
+ this.pause('not_deployed', 'Crewly Cloud has no conversation store yet; checking again in an hour');
497
+ }
498
+ else if (status === 403 && code === INGEST_ERROR_CODES.SYNC_DISABLED) {
499
+ this.pause('sync_disabled', 'Conversation sync is switched off for this Crewly Cloud account; checking again in an hour');
500
+ }
501
+ else if (status === 503 && code === INGEST_ERROR_CODES.KEY_MISSING) {
502
+ this.pause('key_missing', 'Crewly Cloud cannot store conversations right now (key missing); checking again in an hour');
503
+ }
504
+ else if (status === 400) {
505
+ this.pause('invalid_batch', `Crewly Cloud refused a conversation batch (${code ?? 'invalid_batch'}); checking again in an hour`);
506
+ }
507
+ else {
508
+ if (status === 401)
509
+ void this.deps.cloud.tryRefreshToken?.().catch(() => false);
510
+ this.failures += 1;
511
+ const delay = Math.min(C.BACKOFF_INITIAL_MS * 2 ** (this.failures - 1), C.BACKOFF_MAX_MS);
512
+ this.pausedUntil = this.now() + delay;
513
+ if (this.failures === 1 || delay === C.BACKOFF_MAX_MS) {
514
+ this.logger.warn('Conversation upload failed; will retry', { status, code, error: outcome.message, retryInMs: delay });
515
+ }
516
+ this.wake(delay);
517
+ }
518
+ return false;
519
+ }
520
+ /**
521
+ * Pause for an hour, logging the reason once.
522
+ *
523
+ * @param reason - Why
524
+ * @param message - Log line
525
+ */
526
+ pause(reason, message) {
527
+ this.pausedUntil = this.now() + C.UNAVAILABLE_RETRY_MS;
528
+ if (!this.loggedPauses.has(reason)) {
529
+ this.loggedPauses.add(reason);
530
+ this.logger.info(message);
531
+ }
532
+ }
533
+ /**
534
+ * On an account switch, start over: the new account gets this machine's
535
+ * history through a fresh backfill, never the old account's queue.
536
+ *
537
+ * @param token - Current access token
538
+ */
539
+ checkAccount(token) {
540
+ const account = accountIdOfToken(token);
541
+ const stored = this.deps.outbox.getState(K.ACCOUNT_ID);
542
+ if (stored === account)
543
+ return;
544
+ if (stored !== null) {
545
+ this.logger.info('Crewly Cloud account changed; conversation history will be sent again for the new account');
546
+ this.deps.outbox.clear();
547
+ this.deps.outbox.clearState([K.NOTICE_SENT_AT]);
548
+ }
549
+ this.deps.outbox.setState(K.ACCOUNT_ID, account);
550
+ }
551
+ /** Keep the outbox bounded; log a history gap once. */
552
+ trimOutbox() {
553
+ try {
554
+ const dropped = this.deps.outbox.trim({ maxRows: C.OUTBOX_MAX_ROWS, olderThanMs: this.now() - C.OUTBOX_MAX_AGE_MS });
555
+ if (dropped > 0) {
556
+ this.deps.outbox.setState(K.GAP_AT, String(this.now()));
557
+ if (!this.gapLogged) {
558
+ this.gapLogged = true;
559
+ this.logger.warn('Conversation outbox over its limit; oldest rows dropped (history gap on Crewly Cloud)', { dropped });
560
+ }
561
+ }
562
+ }
563
+ catch {
564
+ // trimming is housekeeping
565
+ }
566
+ }
567
+ /** O1: one DM to the owner the first time history reaches Cloud. */
568
+ async maybeNotifyOwner() {
569
+ if (!this.deps.notifyOwner)
570
+ return;
571
+ if (this.deps.outbox.getState(K.NOTICE_SENT_AT))
572
+ return;
573
+ if (this.now() - this.lastNoticeAttemptAt < C.UNAVAILABLE_RETRY_MS && this.lastNoticeAttemptAt > 0)
574
+ return;
575
+ this.lastNoticeAttemptAt = this.now();
576
+ // Claim it first so two quick successes cannot send two DMs.
577
+ this.deps.outbox.setState(K.NOTICE_SENT_AT, String(this.now()));
578
+ let posted = false;
579
+ try {
580
+ const { deviceName } = await this.deps.identity();
581
+ posted = await this.deps.notifyOwner(C.NOTICE_TEXT.replace('{device}', deviceName || 'this machine'));
582
+ }
583
+ catch (error) {
584
+ this.logger.debug('Conversation sync notice not sent', { error: error instanceof Error ? error.message : String(error) });
585
+ }
586
+ if (!posted)
587
+ this.deps.outbox.setState(K.NOTICE_SENT_AT, null);
588
+ }
589
+ }
590
+ let instance = null;
591
+ /**
592
+ * Install the process-wide instance (composition root).
593
+ *
594
+ * @param service - The service, or null
595
+ */
596
+ export function setConversationCloudSyncService(service) {
597
+ instance = service;
598
+ }
599
+ /**
600
+ * The process-wide instance, or null before wiring.
601
+ *
602
+ * @returns The service or null
603
+ */
604
+ export function getConversationCloudSyncService() {
605
+ return instance;
606
+ }
607
+ //# sourceMappingURL=conversation-cloud-sync.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation-cloud-sync.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/cloud/conversation-cloud-sync.service.ts"],"names":[],"mappings":"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"}