agent-tower 0.6.0-beta.12 → 0.6.0-beta.13
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.
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +4 -0
- package/dist/app.js.map +1 -1
- package/dist/routes/conversations.d.ts.map +1 -1
- package/dist/routes/conversations.js +5 -1
- package/dist/routes/conversations.js.map +1 -1
- package/dist/runtime/__tests__/runtime-coordinator.test.js +21 -1
- package/dist/runtime/__tests__/runtime-coordinator.test.js.map +1 -1
- package/dist/runtime/runtime-coordinator.d.ts +2 -0
- package/dist/runtime/runtime-coordinator.d.ts.map +1 -1
- package/dist/runtime/runtime-coordinator.js +21 -0
- package/dist/runtime/runtime-coordinator.js.map +1 -1
- package/dist/services/__tests__/conversation.service.test.js +160 -0
- package/dist/services/__tests__/conversation.service.test.js.map +1 -1
- package/dist/services/conversation.service.d.ts.map +1 -1
- package/dist/services/conversation.service.js +21 -2
- package/dist/services/conversation.service.js.map +1 -1
- package/dist/services/session-manager.d.ts +24 -1
- package/dist/services/session-manager.d.ts.map +1 -1
- package/dist/services/session-manager.js +259 -37
- package/dist/services/session-manager.js.map +1 -1
- package/package.json +1 -1
- package/prisma/migrations/20260826000000_add_conversation_turn_queue/migration.sql +19 -0
- package/prisma/schema.prisma +22 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation.service.js","sourceRoot":"","sources":["../../src/services/conversation.service.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"conversation.service.js","sourceRoot":"","sources":["../../src/services/conversation.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,10 @@ import { type PersistedAcpProcessIdentity } from '../runtime/acp/process-manager
|
|
|
7
7
|
interface StopSessionOptions {
|
|
8
8
|
skipTeamRunReconcile?: boolean;
|
|
9
9
|
}
|
|
10
|
+
interface SendMessageOptions {
|
|
11
|
+
/** User message was already appended while claiming a queued turn. */
|
|
12
|
+
userEntryId?: string;
|
|
13
|
+
}
|
|
10
14
|
export declare class SessionManager {
|
|
11
15
|
private readonly eventBus;
|
|
12
16
|
private snapshotFlushTimers;
|
|
@@ -40,6 +44,9 @@ export declare class SessionManager {
|
|
|
40
44
|
private readonly pendingRuntimeEventExpiryTimers;
|
|
41
45
|
private readonly runtimePermissionStates;
|
|
42
46
|
private readonly externalSessionPersistence;
|
|
47
|
+
/** Durable conversation turns are consumed one at a time per Session. */
|
|
48
|
+
private readonly conversationQueueWorkers;
|
|
49
|
+
private conversationQueueStopping;
|
|
43
50
|
/** Admission boundary covering the short initial-start -> process-owning handoff. */
|
|
44
51
|
private readonly pendingInitialStarts;
|
|
45
52
|
private readonly initialStartResolvers;
|
|
@@ -121,6 +128,18 @@ export declare class SessionManager {
|
|
|
121
128
|
conversationId: string | null;
|
|
122
129
|
}) | null>;
|
|
123
130
|
getRuntimeState(sessionId: string, runtimeType?: RuntimeType): RuntimeStateDto;
|
|
131
|
+
/**
|
|
132
|
+
* Persist a conversation message and schedule its runtime turn. The caller
|
|
133
|
+
* only waits for the SQLite insert; ACP startup and prompt delivery happen
|
|
134
|
+
* in the per-session queue worker.
|
|
135
|
+
*/
|
|
136
|
+
enqueueConversationMessage(sessionId: string, message: string, providerId?: string): Promise<{
|
|
137
|
+
turnId: string;
|
|
138
|
+
}>;
|
|
139
|
+
/** Recover turns left in RUNNING state by an interrupted server process. */
|
|
140
|
+
startConversationQueue(): Promise<void>;
|
|
141
|
+
/** Stop scheduling new work during the Fastify shutdown phase. */
|
|
142
|
+
stopConversationQueue(): void;
|
|
124
143
|
/** Dispose a TeamRun-owned runtime after its invocation reaches a terminal state. */
|
|
125
144
|
disposeRuntimeSession(sessionId: string, expectedRuntimeInstanceId?: string): Promise<void>;
|
|
126
145
|
retryRuntimeProcessCleanup(input: PersistedAcpProcessIdentity & {
|
|
@@ -290,7 +309,7 @@ export declare class SessionManager {
|
|
|
290
309
|
workspaceId: string | null;
|
|
291
310
|
conversationId: string | null;
|
|
292
311
|
}) | null>;
|
|
293
|
-
sendMessage(id: string, message: string, providerId?: string, expectedTeamRunInvocationId?: string): Promise<({
|
|
312
|
+
sendMessage(id: string, message: string, providerId?: string, expectedTeamRunInvocationId?: string, options?: SendMessageOptions): Promise<({
|
|
294
313
|
workspace: ({
|
|
295
314
|
task: {
|
|
296
315
|
id: string;
|
|
@@ -393,6 +412,9 @@ export declare class SessionManager {
|
|
|
393
412
|
resize(sessionId: string, cols: number, rows: number): void;
|
|
394
413
|
/** Close all runtime driver sessions during graceful server shutdown. */
|
|
395
414
|
destroyAll(): Promise<void>;
|
|
415
|
+
private kickConversationQueue;
|
|
416
|
+
private processConversationQueue;
|
|
417
|
+
private requeueConversationTurn;
|
|
396
418
|
private resolveAgentSessionId;
|
|
397
419
|
private startRuntimeTurn;
|
|
398
420
|
private claimRuntimeLaunch;
|
|
@@ -429,6 +451,7 @@ export declare class SessionManager {
|
|
|
429
451
|
private releaseSnapshotPersistenceState;
|
|
430
452
|
private extractTokenUsageFromSnapshot;
|
|
431
453
|
private findSessionExecutionRecord;
|
|
454
|
+
private appendUserMessageEntry;
|
|
432
455
|
private isConversationSession;
|
|
433
456
|
private ensureExecutionRecordIsLive;
|
|
434
457
|
private getExecutionWorkingDir;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../src/services/session-manager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAA6D,MAAM,mBAAmB,CAAC;AAgBzG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAiBrE,OAAO,EAAE,WAAW,EAAwB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAI9F,OAAO,EAKL,KAAK,eAAe,EAKrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../src/services/session-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,7 +13,7 @@ import { ensureTaskNotDeleted } from './deleted-task-guard.js';
|
|
|
13
13
|
import { getWorkspaceWorkingDir, isMainDirectoryWorkspace, } from './workspace-kind.js';
|
|
14
14
|
import { writeErrorLog } from '../utils/error-log.js';
|
|
15
15
|
import { AGENT_API_CREDENTIAL_ENV, clearAgentApiCredentials, createAgentApiCredential, revokeAgentApiCredential, } from '../utils/agent-api-credential.js';
|
|
16
|
-
import { createHash } from 'node:crypto';
|
|
16
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
17
17
|
import { RuntimeType, supportsAgentRuntime } from '@agent-tower/shared';
|
|
18
18
|
import { getProviderRuntimeType } from '../executors/providers.js';
|
|
19
19
|
import { appendAgentOutputIntentInstructions } from '../prompts/agent-output-intents.js';
|
|
@@ -27,6 +27,10 @@ const PROCESS_CLEANUP_RETRY_DELAYS_MS = [1_000, 5_000, 30_000, 120_000, 300_000]
|
|
|
27
27
|
const PENDING_RUNTIME_EVENT_TTL_MS = 60_000;
|
|
28
28
|
const PENDING_RUNTIME_EVENTS_PER_KEY = 8;
|
|
29
29
|
const PENDING_RUNTIME_EVENTS_GLOBAL = 128;
|
|
30
|
+
const CONVERSATION_TURN_QUEUED = 'QUEUED';
|
|
31
|
+
const CONVERSATION_TURN_RUNNING = 'RUNNING';
|
|
32
|
+
const CONVERSATION_TURN_COMPLETED = 'COMPLETED';
|
|
33
|
+
const CONVERSATION_TURN_FAILED = 'FAILED';
|
|
30
34
|
function eventKey(sessionId, runtimeInstanceId, launchClaimNumber) {
|
|
31
35
|
return `${sessionId}:${runtimeInstanceId}:${launchClaimNumber}`;
|
|
32
36
|
}
|
|
@@ -107,6 +111,9 @@ export class SessionManager {
|
|
|
107
111
|
pendingRuntimeEventExpiryTimers = new Map();
|
|
108
112
|
runtimePermissionStates = new Map();
|
|
109
113
|
externalSessionPersistence = new Map();
|
|
114
|
+
/** Durable conversation turns are consumed one at a time per Session. */
|
|
115
|
+
conversationQueueWorkers = new Map();
|
|
116
|
+
conversationQueueStopping = false;
|
|
110
117
|
/** Admission boundary covering the short initial-start -> process-owning handoff. */
|
|
111
118
|
pendingInitialStarts = new Map();
|
|
112
119
|
initialStartResolvers = new Map();
|
|
@@ -197,6 +204,90 @@ export class SessionManager {
|
|
|
197
204
|
getRuntimeState(sessionId, runtimeType = RuntimeType.CLI) {
|
|
198
205
|
return this.runtimeCoordinator.getState(sessionId, runtimeType);
|
|
199
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* Persist a conversation message and schedule its runtime turn. The caller
|
|
209
|
+
* only waits for the SQLite insert; ACP startup and prompt delivery happen
|
|
210
|
+
* in the per-session queue worker.
|
|
211
|
+
*/
|
|
212
|
+
async enqueueConversationMessage(sessionId, message, providerId) {
|
|
213
|
+
const enqueueStartedAt = Date.now();
|
|
214
|
+
const session = await this.findSessionExecutionRecord(sessionId);
|
|
215
|
+
if (!session) {
|
|
216
|
+
throw new NotFoundError('Session', sessionId);
|
|
217
|
+
}
|
|
218
|
+
this.ensureExecutionRecordIsLive(session);
|
|
219
|
+
if (!this.isConversationSession(session)) {
|
|
220
|
+
throw new ValidationError('Only conversation sessions support queued messages');
|
|
221
|
+
}
|
|
222
|
+
const effectiveProviderId = providerId ?? session.providerId;
|
|
223
|
+
if (effectiveProviderId) {
|
|
224
|
+
const provider = getProviderById(effectiveProviderId);
|
|
225
|
+
if (!provider) {
|
|
226
|
+
throw new ValidationError(`Provider not found: ${effectiveProviderId}`);
|
|
227
|
+
}
|
|
228
|
+
if (String(provider.agentType) !== session.agentType) {
|
|
229
|
+
throw new ValidationError(`Cannot switch provider: agentType mismatch. Session uses '${session.agentType}', but provider '${provider.name}' is for '${provider.agentType}'`);
|
|
230
|
+
}
|
|
231
|
+
if (getProviderRuntimeType(provider) !== this.normalizeRuntimeType(session.runtimeType)) {
|
|
232
|
+
throw new ValidationError(`Cannot switch provider: runtimeType mismatch. Session uses '${session.runtimeType}', but provider '${provider.name}' uses '${getProviderRuntimeType(provider)}'`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// Generate both identifiers before the insert. The entry id is persisted
|
|
236
|
+
// with the queue row so a crash between applying the in-memory patch and
|
|
237
|
+
// updating the row remains replayable without creating a duplicate entry.
|
|
238
|
+
const turnId = randomUUID();
|
|
239
|
+
const userEntryId = `user:${turnId}`;
|
|
240
|
+
const turn = await prisma.conversationTurn.create({
|
|
241
|
+
data: {
|
|
242
|
+
id: turnId,
|
|
243
|
+
sessionId,
|
|
244
|
+
message,
|
|
245
|
+
userEntryId,
|
|
246
|
+
providerId: providerId ?? null,
|
|
247
|
+
status: CONVERSATION_TURN_QUEUED,
|
|
248
|
+
},
|
|
249
|
+
select: { id: true },
|
|
250
|
+
});
|
|
251
|
+
// Reflect the user message immediately. This is local, synchronous work;
|
|
252
|
+
// the expensive ACP startup/prompt remains exclusively in the worker. If
|
|
253
|
+
// the in-memory snapshot cannot be updated, leave the durable turn queued
|
|
254
|
+
// so the worker can retry the append instead of losing the message.
|
|
255
|
+
try {
|
|
256
|
+
this.appendUserMessageEntry(session, message, userEntryId);
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
this.logSessionError('conversation.queueUserEntry', error, {
|
|
260
|
+
sessionId,
|
|
261
|
+
turnId: turn.id,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
this.kickConversationQueue(sessionId);
|
|
265
|
+
console.log(`[ConversationQueue] enqueued session=${sessionId} turn=${turn.id} persistMs=${Date.now() - enqueueStartedAt}`);
|
|
266
|
+
return { turnId: turn.id };
|
|
267
|
+
}
|
|
268
|
+
/** Recover turns left in RUNNING state by an interrupted server process. */
|
|
269
|
+
async startConversationQueue() {
|
|
270
|
+
this.conversationQueueStopping = false;
|
|
271
|
+
await prisma.conversationTurn.updateMany({
|
|
272
|
+
where: { status: CONVERSATION_TURN_RUNNING },
|
|
273
|
+
data: {
|
|
274
|
+
status: CONVERSATION_TURN_QUEUED,
|
|
275
|
+
startedAt: null,
|
|
276
|
+
},
|
|
277
|
+
});
|
|
278
|
+
const pending = await prisma.conversationTurn.findMany({
|
|
279
|
+
where: { status: CONVERSATION_TURN_QUEUED },
|
|
280
|
+
select: { sessionId: true },
|
|
281
|
+
distinct: ['sessionId'],
|
|
282
|
+
});
|
|
283
|
+
for (const turn of pending) {
|
|
284
|
+
this.kickConversationQueue(turn.sessionId);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/** Stop scheduling new work during the Fastify shutdown phase. */
|
|
288
|
+
stopConversationQueue() {
|
|
289
|
+
this.conversationQueueStopping = true;
|
|
290
|
+
}
|
|
200
291
|
/** Dispose a TeamRun-owned runtime after its invocation reaches a terminal state. */
|
|
201
292
|
async disposeRuntimeSession(sessionId, expectedRuntimeInstanceId) {
|
|
202
293
|
await this.runtimeCoordinator.disposeSession(sessionId, expectedRuntimeInstanceId);
|
|
@@ -375,7 +466,7 @@ export class SessionManager {
|
|
|
375
466
|
initialStart.release();
|
|
376
467
|
}
|
|
377
468
|
}
|
|
378
|
-
async sendMessage(id, message, providerId, expectedTeamRunInvocationId) {
|
|
469
|
+
async sendMessage(id, message, providerId, expectedTeamRunInvocationId, options = {}) {
|
|
379
470
|
console.log('[SessionManager] 📨 Sending message to session:', id);
|
|
380
471
|
console.log('[SessionManager] Message summary:', summarizeTextForLog(message));
|
|
381
472
|
if (providerId) {
|
|
@@ -459,40 +550,7 @@ export class SessionManager {
|
|
|
459
550
|
}
|
|
460
551
|
}
|
|
461
552
|
await this.waitForPendingAutoCommit(id);
|
|
462
|
-
const
|
|
463
|
-
const msgStore = sessionMsgStoreManager.getOrCreate(id);
|
|
464
|
-
if (isNewStore && session.logSnapshot) {
|
|
465
|
-
try {
|
|
466
|
-
const snapshot = JSON.parse(session.logSnapshot);
|
|
467
|
-
msgStore.restoreFromSnapshot(snapshot);
|
|
468
|
-
}
|
|
469
|
-
catch (error) {
|
|
470
|
-
console.error(`[SessionManager] Failed to restore snapshot for session ${id}:`, error);
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
// Heal index drift caused by previously failed patches (e.g. invalid value).
|
|
474
|
-
// If entryIndex is ahead of snapshot length, subsequent add/replace paths
|
|
475
|
-
// become out-of-bounds and all later patches fail.
|
|
476
|
-
const preflightSnapshot = msgStore.getSnapshot();
|
|
477
|
-
const expectedIndex = preflightSnapshot.entries.length;
|
|
478
|
-
const currentIndex = msgStore.entryIndex.current();
|
|
479
|
-
if (currentIndex !== expectedIndex) {
|
|
480
|
-
if (DEBUG_SNAPSHOT) {
|
|
481
|
-
console.warn(`[SessionManager:snapshot] rebase entryIndex sessionId=${id} currentIndex=${currentIndex} expectedIndex=${expectedIndex}`);
|
|
482
|
-
}
|
|
483
|
-
msgStore.entryIndex.startFrom(expectedIndex);
|
|
484
|
-
}
|
|
485
|
-
const userEntry = createUserMessage(message);
|
|
486
|
-
const userIndex = msgStore.entryIndex.next();
|
|
487
|
-
const userPatch = addNormalizedEntry(userIndex, userEntry);
|
|
488
|
-
if (DEBUG_SNAPSHOT) {
|
|
489
|
-
console.log(`[SessionManager:snapshot] sendMessage userPatch sessionId=${id} index=${userIndex} currentIndex=${msgStore.entryIndex.current()}`);
|
|
490
|
-
}
|
|
491
|
-
const userPatchSeq = msgStore.pushPatch(userPatch);
|
|
492
|
-
// Emit directly to EventBus — the old pipeline was already destroyed so
|
|
493
|
-
// MsgStore's patchListeners are empty at this point. Without this line
|
|
494
|
-
// the user-message patch would never reach WebSocket subscribers.
|
|
495
|
-
this.eventBus.emit('session:patch', { sessionId: id, patch: userPatch, seq: userPatchSeq });
|
|
553
|
+
const userEntryId = options.userEntryId ?? this.appendUserMessageEntry(session, message);
|
|
496
554
|
const agentSessionId = session.externalSessionId
|
|
497
555
|
?? this.resolveAgentSessionId(id, session.logSnapshot);
|
|
498
556
|
if (providerId && providerId !== session.providerId) {
|
|
@@ -500,7 +558,7 @@ export class SessionManager {
|
|
|
500
558
|
}
|
|
501
559
|
const processStart = this.reserveProcessStart(id);
|
|
502
560
|
try {
|
|
503
|
-
await this.startRuntimeTurn(session, message, agentSessionId, effectiveProviderId, resumeMode,
|
|
561
|
+
await this.startRuntimeTurn(session, message, agentSessionId, effectiveProviderId, resumeMode, userEntryId, false, expectedTeamRunInvocationId);
|
|
504
562
|
return session;
|
|
505
563
|
}
|
|
506
564
|
finally {
|
|
@@ -643,6 +701,7 @@ export class SessionManager {
|
|
|
643
701
|
}
|
|
644
702
|
/** Close all runtime driver sessions during graceful server shutdown. */
|
|
645
703
|
async destroyAll() {
|
|
704
|
+
this.stopConversationQueue();
|
|
646
705
|
await this.runtimeCoordinator.destroyAll();
|
|
647
706
|
for (const resolve of this.initialStartResolvers.values())
|
|
648
707
|
resolve();
|
|
@@ -669,6 +728,127 @@ export class SessionManager {
|
|
|
669
728
|
this.followUpReservations.clear();
|
|
670
729
|
clearAgentApiCredentials();
|
|
671
730
|
}
|
|
731
|
+
kickConversationQueue(sessionId) {
|
|
732
|
+
if (this.conversationQueueStopping || this.conversationQueueWorkers.has(sessionId)) {
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
const worker = new Promise((resolve, reject) => {
|
|
736
|
+
setImmediate(() => {
|
|
737
|
+
this.processConversationQueue(sessionId).then(resolve, reject);
|
|
738
|
+
});
|
|
739
|
+
});
|
|
740
|
+
this.conversationQueueWorkers.set(sessionId, worker);
|
|
741
|
+
void worker
|
|
742
|
+
.catch((error) => {
|
|
743
|
+
this.logSessionError('conversation.queue', error, { sessionId });
|
|
744
|
+
})
|
|
745
|
+
.finally(() => {
|
|
746
|
+
if (this.conversationQueueWorkers.get(sessionId) === worker) {
|
|
747
|
+
this.conversationQueueWorkers.delete(sessionId);
|
|
748
|
+
}
|
|
749
|
+
// Cover an enqueue racing with the worker's final empty scan without
|
|
750
|
+
// creating a worker spin loop when the queue is actually empty.
|
|
751
|
+
if (!this.conversationQueueStopping) {
|
|
752
|
+
void prisma.conversationTurn.count({
|
|
753
|
+
where: { sessionId, status: CONVERSATION_TURN_QUEUED },
|
|
754
|
+
}).then((count) => {
|
|
755
|
+
if (count > 0)
|
|
756
|
+
this.kickConversationQueue(sessionId);
|
|
757
|
+
}).catch((error) => {
|
|
758
|
+
this.logSessionError('conversation.queueScan', error, { sessionId });
|
|
759
|
+
});
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
async processConversationQueue(sessionId) {
|
|
764
|
+
while (!this.conversationQueueStopping) {
|
|
765
|
+
const queued = await prisma.conversationTurn.findFirst({
|
|
766
|
+
where: { sessionId, status: CONVERSATION_TURN_QUEUED },
|
|
767
|
+
orderBy: [{ queuedAt: 'asc' }, { createdAt: 'asc' }, { id: 'asc' }],
|
|
768
|
+
});
|
|
769
|
+
if (!queued)
|
|
770
|
+
return;
|
|
771
|
+
const claimed = await prisma.conversationTurn.updateMany({
|
|
772
|
+
where: { id: queued.id, status: CONVERSATION_TURN_QUEUED },
|
|
773
|
+
data: {
|
|
774
|
+
status: CONVERSATION_TURN_RUNNING,
|
|
775
|
+
attempts: { increment: 1 },
|
|
776
|
+
startedAt: new Date(),
|
|
777
|
+
lastError: null,
|
|
778
|
+
},
|
|
779
|
+
});
|
|
780
|
+
if (claimed.count !== 1)
|
|
781
|
+
continue;
|
|
782
|
+
try {
|
|
783
|
+
console.log(`[ConversationQueue] claimed session=${sessionId} turn=${queued.id} queueWaitMs=${Math.max(0, Date.now() - queued.queuedAt.getTime())} attempt=${queued.attempts + 1}`);
|
|
784
|
+
// A conversation accepts one ACP prompt at a time. Waiting here keeps
|
|
785
|
+
// queued follow-ups from cancelling the previous turn (and hitting
|
|
786
|
+
// RuntimeCoordinator's ten-second abandon timeout).
|
|
787
|
+
const previousTurnWaitStartedAt = Date.now();
|
|
788
|
+
await this.runtimeCoordinator.waitForTurnCompletion(sessionId);
|
|
789
|
+
console.log(`[ConversationQueue] priorTurnReady session=${sessionId} turn=${queued.id} waitMs=${Date.now() - previousTurnWaitStartedAt}`);
|
|
790
|
+
if (this.conversationQueueStopping) {
|
|
791
|
+
await this.requeueConversationTurn(queued.id);
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
const session = await this.findSessionExecutionRecord(sessionId);
|
|
795
|
+
if (!session)
|
|
796
|
+
throw new NotFoundError('Session', sessionId);
|
|
797
|
+
this.ensureExecutionRecordIsLive(session);
|
|
798
|
+
const userEntryId = queued.userEntryId ?? `user:${queued.id}`;
|
|
799
|
+
this.appendUserMessageEntry(session, queued.message, userEntryId);
|
|
800
|
+
if (!queued.userEntryId) {
|
|
801
|
+
await prisma.conversationTurn.updateMany({
|
|
802
|
+
where: { id: queued.id, status: CONVERSATION_TURN_RUNNING },
|
|
803
|
+
data: { userEntryId },
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
const dispatchStartedAt = Date.now();
|
|
807
|
+
await this.sendMessage(sessionId, queued.message, queued.providerId ?? undefined, undefined, { userEntryId });
|
|
808
|
+
console.log(`[ConversationQueue] dispatched session=${sessionId} turn=${queued.id} dispatchMs=${Date.now() - dispatchStartedAt}`);
|
|
809
|
+
const turnWaitStartedAt = Date.now();
|
|
810
|
+
await this.runtimeCoordinator.waitForTurnCompletion(sessionId);
|
|
811
|
+
await prisma.conversationTurn.updateMany({
|
|
812
|
+
where: { id: queued.id, status: CONVERSATION_TURN_RUNNING },
|
|
813
|
+
data: {
|
|
814
|
+
status: CONVERSATION_TURN_COMPLETED,
|
|
815
|
+
completedAt: new Date(),
|
|
816
|
+
},
|
|
817
|
+
});
|
|
818
|
+
console.log(`[ConversationQueue] completed session=${sessionId} turn=${queued.id} runtimeWaitMs=${Date.now() - turnWaitStartedAt}`);
|
|
819
|
+
}
|
|
820
|
+
catch (error) {
|
|
821
|
+
if (this.conversationQueueStopping) {
|
|
822
|
+
await this.requeueConversationTurn(queued.id);
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
const lastError = error instanceof Error ? error.message : String(error);
|
|
826
|
+
await prisma.conversationTurn.updateMany({
|
|
827
|
+
where: { id: queued.id, status: CONVERSATION_TURN_RUNNING },
|
|
828
|
+
data: {
|
|
829
|
+
status: CONVERSATION_TURN_FAILED,
|
|
830
|
+
lastError: lastError.slice(0, 2_000),
|
|
831
|
+
completedAt: new Date(),
|
|
832
|
+
},
|
|
833
|
+
});
|
|
834
|
+
const errorSummary = summarizeTextForLog(lastError);
|
|
835
|
+
console.log(`[ConversationQueue] failed session=${sessionId} turn=${queued.id} errorLength=${errorSummary.length} errorSha256=${errorSummary.sha256}`);
|
|
836
|
+
this.logSessionError('conversation.queueTurn', error, {
|
|
837
|
+
sessionId,
|
|
838
|
+
turnId: queued.id,
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
async requeueConversationTurn(turnId) {
|
|
844
|
+
await prisma.conversationTurn.updateMany({
|
|
845
|
+
where: { id: turnId, status: CONVERSATION_TURN_RUNNING },
|
|
846
|
+
data: {
|
|
847
|
+
status: CONVERSATION_TURN_QUEUED,
|
|
848
|
+
startedAt: null,
|
|
849
|
+
},
|
|
850
|
+
});
|
|
851
|
+
}
|
|
672
852
|
resolveAgentSessionId(sessionId, logSnapshot) {
|
|
673
853
|
const msgStore = sessionMsgStoreManager.get(sessionId);
|
|
674
854
|
if (msgStore) {
|
|
@@ -1651,6 +1831,48 @@ export class SessionManager {
|
|
|
1651
1831
|
},
|
|
1652
1832
|
});
|
|
1653
1833
|
}
|
|
1834
|
+
appendUserMessageEntry(session, message, entryId) {
|
|
1835
|
+
const sessionId = session.id;
|
|
1836
|
+
const isNewStore = !sessionMsgStoreManager.has(sessionId);
|
|
1837
|
+
const msgStore = sessionMsgStoreManager.getOrCreate(sessionId);
|
|
1838
|
+
if (isNewStore && session.logSnapshot) {
|
|
1839
|
+
try {
|
|
1840
|
+
msgStore.restoreFromSnapshot(JSON.parse(session.logSnapshot));
|
|
1841
|
+
}
|
|
1842
|
+
catch (error) {
|
|
1843
|
+
console.error(`[SessionManager] Failed to restore snapshot for session ${sessionId}:`, error);
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
// Heal index drift caused by previously failed patches (e.g. invalid value).
|
|
1847
|
+
const preflightSnapshot = msgStore.getSnapshot();
|
|
1848
|
+
const expectedIndex = preflightSnapshot.entries.length;
|
|
1849
|
+
const currentIndex = msgStore.entryIndex.current();
|
|
1850
|
+
if (currentIndex !== expectedIndex) {
|
|
1851
|
+
if (DEBUG_SNAPSHOT) {
|
|
1852
|
+
console.warn(`[SessionManager:snapshot] rebase entryIndex sessionId=${sessionId} currentIndex=${currentIndex} expectedIndex=${expectedIndex}`);
|
|
1853
|
+
}
|
|
1854
|
+
msgStore.entryIndex.startFrom(expectedIndex);
|
|
1855
|
+
}
|
|
1856
|
+
// Queue retries may reach this point after the patch was already applied
|
|
1857
|
+
// but before its durable userEntryId update. Reusing the stable id makes
|
|
1858
|
+
// the replay a no-op instead of appending the same message twice.
|
|
1859
|
+
if (entryId) {
|
|
1860
|
+
const existing = preflightSnapshot.entries.find((entry) => entry.id === entryId);
|
|
1861
|
+
if (existing)
|
|
1862
|
+
return entryId;
|
|
1863
|
+
}
|
|
1864
|
+
const userEntry = createUserMessage(message, entryId);
|
|
1865
|
+
const userIndex = msgStore.entryIndex.next();
|
|
1866
|
+
const userPatch = addNormalizedEntry(userIndex, userEntry);
|
|
1867
|
+
if (DEBUG_SNAPSHOT) {
|
|
1868
|
+
console.log(`[SessionManager:snapshot] userPatch sessionId=${sessionId} index=${userIndex} currentIndex=${msgStore.entryIndex.current()}`);
|
|
1869
|
+
}
|
|
1870
|
+
const userPatchSeq = msgStore.pushPatch(userPatch);
|
|
1871
|
+
// Emit directly to EventBus — a previous pipeline may have been destroyed
|
|
1872
|
+
// before the queued turn starts, leaving no MsgStore patch listener.
|
|
1873
|
+
this.eventBus.emit('session:patch', { sessionId, patch: userPatch, seq: userPatchSeq });
|
|
1874
|
+
return userEntry.id;
|
|
1875
|
+
}
|
|
1654
1876
|
isConversationSession(session) {
|
|
1655
1877
|
return session.context === SessionContext.CONVERSATION || Boolean(session.conversationId);
|
|
1656
1878
|
}
|