@dexto/core 1.6.24 → 1.6.26
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/agent/DextoAgent.cjs +52 -17
- package/dist/agent/DextoAgent.d.ts +11 -6
- package/dist/agent/DextoAgent.d.ts.map +1 -1
- package/dist/agent/DextoAgent.js +52 -17
- package/dist/agent/state-manager.cjs +6 -0
- package/dist/agent/state-manager.d.ts +4 -0
- package/dist/agent/state-manager.d.ts.map +1 -1
- package/dist/agent/state-manager.js +6 -0
- package/dist/approval/manager.cjs +328 -178
- package/dist/approval/manager.d.ts +39 -31
- package/dist/approval/manager.d.ts.map +1 -1
- package/dist/approval/manager.js +328 -178
- package/dist/approval/session-approval-store.cjs +91 -0
- package/dist/approval/session-approval-store.d.ts +55 -0
- package/dist/approval/session-approval-store.d.ts.map +1 -0
- package/dist/approval/session-approval-store.js +68 -0
- package/dist/llm/executor/stream-processor.cjs +24 -15
- package/dist/llm/executor/stream-processor.d.ts +5 -0
- package/dist/llm/executor/stream-processor.d.ts.map +1 -1
- package/dist/llm/executor/stream-processor.js +24 -15
- package/dist/llm/executor/turn-executor.cjs +7 -3
- package/dist/llm/executor/turn-executor.d.ts.map +1 -1
- package/dist/llm/executor/turn-executor.js +7 -3
- package/dist/llm/services/factory.cjs +10 -4
- package/dist/llm/services/factory.d.ts +2 -21
- package/dist/llm/services/factory.d.ts.map +1 -1
- package/dist/llm/services/factory.js +11 -7
- package/dist/llm/services/types.d.ts +33 -2
- package/dist/llm/services/types.d.ts.map +1 -1
- package/dist/llm/services/vercel.cjs +4 -5
- package/dist/llm/services/vercel.d.ts +3 -3
- package/dist/llm/services/vercel.d.ts.map +1 -1
- package/dist/llm/services/vercel.js +2 -3
- package/dist/logger/default-logger-factory.d.ts +12 -12
- package/dist/logger/v2/schemas.d.ts +6 -6
- package/dist/mcp/schemas.d.ts +10 -10
- package/dist/session/chat-session.cjs +39 -41
- package/dist/session/chat-session.d.ts +22 -12
- package/dist/session/chat-session.d.ts.map +1 -1
- package/dist/session/chat-session.js +39 -41
- package/dist/session/message-queue-store.cjs +75 -0
- package/dist/session/message-queue-store.d.ts +16 -0
- package/dist/session/message-queue-store.d.ts.map +1 -0
- package/dist/session/message-queue-store.js +52 -0
- package/dist/session/message-queue.cjs +140 -46
- package/dist/session/message-queue.d.ts +18 -6
- package/dist/session/message-queue.d.ts.map +1 -1
- package/dist/session/message-queue.js +140 -46
- package/dist/session/session-manager.cjs +130 -25
- package/dist/session/session-manager.d.ts +18 -1
- package/dist/session/session-manager.d.ts.map +1 -1
- package/dist/session/session-manager.js +130 -25
- package/dist/session/title-generator.cjs +9 -2
- package/dist/session/title-generator.d.ts +2 -0
- package/dist/session/title-generator.d.ts.map +1 -1
- package/dist/session/title-generator.js +9 -2
- package/dist/telemetry/errors.cjs +2 -2
- package/dist/telemetry/errors.js +2 -2
- package/dist/telemetry/index.d.ts +1 -1
- package/dist/telemetry/index.d.ts.map +1 -1
- package/dist/telemetry/index.js +3 -1
- package/dist/telemetry/telemetry.cjs +62 -21
- package/dist/telemetry/telemetry.d.ts +14 -0
- package/dist/telemetry/telemetry.d.ts.map +1 -1
- package/dist/telemetry/telemetry.js +62 -21
- package/dist/test-utils/session-state-stores.cjs +68 -0
- package/dist/test-utils/session-state-stores.js +42 -0
- package/dist/tools/session-tool-preferences-store.cjs +86 -0
- package/dist/tools/session-tool-preferences-store.d.ts +29 -0
- package/dist/tools/session-tool-preferences-store.d.ts.map +1 -0
- package/dist/tools/session-tool-preferences-store.js +63 -0
- package/dist/tools/tool-manager.cjs +131 -32
- package/dist/tools/tool-manager.d.ts +17 -6
- package/dist/tools/tool-manager.d.ts.map +1 -1
- package/dist/tools/tool-manager.js +131 -32
- package/dist/utils/service-initializer.cjs +38 -5
- package/dist/utils/service-initializer.d.ts +11 -1
- package/dist/utils/service-initializer.d.ts.map +1 -1
- package/dist/utils/service-initializer.js +36 -4
- package/package.json +1 -1
|
@@ -16,11 +16,13 @@ class SessionManager {
|
|
|
16
16
|
this.maxSessions = config.maxSessions ?? 100;
|
|
17
17
|
this.sessionTTL = config.sessionTTL ?? 36e5;
|
|
18
18
|
this.sessionLoggerFactory = config.sessionLoggerFactory ?? defaultSessionLoggerFactory;
|
|
19
|
+
this.languageModelFactory = config.languageModelFactory;
|
|
19
20
|
this.logger = logger.createChild(DextoLogComponent.SESSION);
|
|
20
21
|
}
|
|
21
22
|
sessions = /* @__PURE__ */ new Map();
|
|
22
23
|
maxSessions;
|
|
23
24
|
sessionTTL;
|
|
25
|
+
static MESSAGE_QUEUE_KEY_PREFIX = "session-message-queue:";
|
|
24
26
|
initialized = false;
|
|
25
27
|
cleanupInterval;
|
|
26
28
|
initializationPromise;
|
|
@@ -34,6 +36,16 @@ class SessionManager {
|
|
|
34
36
|
static FORK_TITLE_PREFIX = "Fork: ";
|
|
35
37
|
static FORK_PARENT_ID_PREVIEW_LENGTH = 8;
|
|
36
38
|
sessionLoggerFactory;
|
|
39
|
+
languageModelFactory;
|
|
40
|
+
getChatSessionServices() {
|
|
41
|
+
return {
|
|
42
|
+
...this.services,
|
|
43
|
+
sessionManager: this,
|
|
44
|
+
...this.languageModelFactory !== void 0 && {
|
|
45
|
+
languageModelFactory: this.languageModelFactory
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
37
49
|
/**
|
|
38
50
|
* Initialize the SessionManager with persistent storage.
|
|
39
51
|
* This must be called before using any session operations.
|
|
@@ -42,6 +54,7 @@ class SessionManager {
|
|
|
42
54
|
if (this.initialized) {
|
|
43
55
|
return;
|
|
44
56
|
}
|
|
57
|
+
await this.clearPersistedQueuedMessages("startup");
|
|
45
58
|
await this.restoreSessionsFromStorage();
|
|
46
59
|
const cleanupIntervalMs = Math.min(this.sessionTTL / 4, 15 * 60 * 1e3);
|
|
47
60
|
this.cleanupInterval = setInterval(
|
|
@@ -72,7 +85,11 @@ class SessionManager {
|
|
|
72
85
|
if (now - lastActivity <= this.sessionTTL) {
|
|
73
86
|
this.logger.debug(`Session ${sessionId} restored from storage`);
|
|
74
87
|
} else {
|
|
75
|
-
await
|
|
88
|
+
await Promise.all([
|
|
89
|
+
this.services.storageManager.getDatabase().delete(sessionKey),
|
|
90
|
+
this.services.storageManager.getCache().delete(sessionKey),
|
|
91
|
+
this.deleteSessionInteractionState(sessionId)
|
|
92
|
+
]);
|
|
76
93
|
this.logger.debug(`Expired session ${sessionId} cleaned up during restore`);
|
|
77
94
|
}
|
|
78
95
|
}
|
|
@@ -83,6 +100,31 @@ class SessionManager {
|
|
|
83
100
|
);
|
|
84
101
|
}
|
|
85
102
|
}
|
|
103
|
+
async clearPersistedQueuedMessages(reason) {
|
|
104
|
+
try {
|
|
105
|
+
const queueKeys = await this.services.storageManager.getDatabase().list(SessionManager.MESSAGE_QUEUE_KEY_PREFIX);
|
|
106
|
+
if (queueKeys.length === 0) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
await Promise.all(
|
|
110
|
+
queueKeys.map(
|
|
111
|
+
(key) => this.services.messageQueueStore.delete(
|
|
112
|
+
key.slice(SessionManager.MESSAGE_QUEUE_KEY_PREFIX.length)
|
|
113
|
+
)
|
|
114
|
+
)
|
|
115
|
+
);
|
|
116
|
+
const message = `${reason === "startup" ? "Cleared stale queued follow-up state from previous agent run" : "Cleared queued follow-up state during agent shutdown"} (${queueKeys.length} session bucket(s))`;
|
|
117
|
+
if (reason === "startup") {
|
|
118
|
+
this.logger.info(message);
|
|
119
|
+
} else {
|
|
120
|
+
this.logger.debug(message);
|
|
121
|
+
}
|
|
122
|
+
} catch (error) {
|
|
123
|
+
this.logger.warn(
|
|
124
|
+
`Failed to clear persisted queued follow-up state during ${reason}: ${error instanceof Error ? error.message : String(error)}`
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
86
128
|
/**
|
|
87
129
|
* Ensures the SessionManager is initialized before operations.
|
|
88
130
|
*/
|
|
@@ -274,12 +316,10 @@ class SessionManager {
|
|
|
274
316
|
this.services.stateManager.updateLLM(restoredConfig, id);
|
|
275
317
|
}
|
|
276
318
|
}
|
|
277
|
-
const session2 = new ChatSession(
|
|
278
|
-
{ ...this.services, sessionManager: this },
|
|
279
|
-
id,
|
|
280
|
-
sessionLogger
|
|
281
|
-
);
|
|
319
|
+
const session2 = new ChatSession(this.getChatSessionServices(), id, sessionLogger);
|
|
282
320
|
await session2.init();
|
|
321
|
+
await this.services.toolManager.restoreSessionState(id);
|
|
322
|
+
await this.services.approvalManager.restoreSessionState(id);
|
|
283
323
|
this.sessions.set(id, session2);
|
|
284
324
|
this.logger.info(`Restored session from storage: ${id}`);
|
|
285
325
|
return session2;
|
|
@@ -288,6 +328,7 @@ class SessionManager {
|
|
|
288
328
|
if (activeSessionKeys.length >= this.maxSessions) {
|
|
289
329
|
throw SessionError.maxSessionsExceeded(activeSessionKeys.length, this.maxSessions);
|
|
290
330
|
}
|
|
331
|
+
await this.deleteSessionInteractionState(id);
|
|
291
332
|
const workspace = await this.services.workspaceManager?.getWorkspace();
|
|
292
333
|
const sessionData = {
|
|
293
334
|
id,
|
|
@@ -313,11 +354,7 @@ class SessionManager {
|
|
|
313
354
|
agentId,
|
|
314
355
|
sessionId: id
|
|
315
356
|
});
|
|
316
|
-
session = new ChatSession(
|
|
317
|
-
{ ...this.services, sessionManager: this },
|
|
318
|
-
id,
|
|
319
|
-
sessionLogger
|
|
320
|
-
);
|
|
357
|
+
session = new ChatSession(this.getChatSessionServices(), id, sessionLogger);
|
|
321
358
|
await session.init();
|
|
322
359
|
this.sessions.set(id, session);
|
|
323
360
|
await this.services.storageManager.getCache().set(sessionKey, sessionData, this.sessionTTL / 1e3);
|
|
@@ -376,11 +413,13 @@ class SessionManager {
|
|
|
376
413
|
}
|
|
377
414
|
}
|
|
378
415
|
const session = new ChatSession(
|
|
379
|
-
|
|
416
|
+
this.getChatSessionServices(),
|
|
380
417
|
sessionId,
|
|
381
418
|
sessionLogger
|
|
382
419
|
);
|
|
383
420
|
await session.init();
|
|
421
|
+
await this.services.toolManager.restoreSessionState(sessionId);
|
|
422
|
+
await this.services.approvalManager.restoreSessionState(sessionId);
|
|
384
423
|
this.sessions.set(sessionId, session);
|
|
385
424
|
return session;
|
|
386
425
|
}
|
|
@@ -402,6 +441,7 @@ class SessionManager {
|
|
|
402
441
|
}
|
|
403
442
|
const sessionKey = `session:${sessionId}`;
|
|
404
443
|
await this.services.storageManager.getCache().delete(sessionKey);
|
|
444
|
+
this.evictSessionInteractionState(sessionId);
|
|
405
445
|
this.logger.debug(
|
|
406
446
|
`Ended session (removed from memory, chat history preserved): ${sessionId}`
|
|
407
447
|
);
|
|
@@ -422,12 +462,13 @@ class SessionManager {
|
|
|
422
462
|
const sessionKey = `session:${sessionId}`;
|
|
423
463
|
await this.services.storageManager.getDatabase().delete(sessionKey);
|
|
424
464
|
await this.services.storageManager.getCache().delete(sessionKey);
|
|
465
|
+
await this.deleteSessionInteractionState(sessionId);
|
|
425
466
|
const messagesKey = `messages:${sessionId}`;
|
|
426
467
|
await this.services.storageManager.getDatabase().delete(messagesKey);
|
|
427
468
|
this.logger.debug(`Deleted session and conversation history: ${sessionId}`);
|
|
428
469
|
}
|
|
429
470
|
/**
|
|
430
|
-
* Resets
|
|
471
|
+
* Resets conversation and session-scoped interaction state while keeping the session alive.
|
|
431
472
|
*
|
|
432
473
|
* @param sessionId The session ID to reset
|
|
433
474
|
* @throws Error if session doesn't exist
|
|
@@ -439,6 +480,15 @@ class SessionManager {
|
|
|
439
480
|
throw SessionError.notFound(sessionId);
|
|
440
481
|
}
|
|
441
482
|
await session.reset();
|
|
483
|
+
await session.clearMessageQueue();
|
|
484
|
+
await Promise.all([
|
|
485
|
+
this.services.toolManager.deleteSessionState(sessionId),
|
|
486
|
+
this.services.approvalManager.deleteSessionState(sessionId)
|
|
487
|
+
]);
|
|
488
|
+
if (this.services.stateManager.hasSessionLLMOverride(sessionId)) {
|
|
489
|
+
this.services.stateManager.clearSessionOverride(sessionId);
|
|
490
|
+
await session.switchLLM(this.services.stateManager.getRuntimeConfig().llm);
|
|
491
|
+
}
|
|
442
492
|
await this.runWithSessionDataLock(sessionId, async (sessionKey) => {
|
|
443
493
|
const sessionData = await this.services.storageManager.getDatabase().get(sessionKey);
|
|
444
494
|
if (!sessionData) {
|
|
@@ -446,6 +496,7 @@ class SessionManager {
|
|
|
446
496
|
}
|
|
447
497
|
sessionData.messageCount = 0;
|
|
448
498
|
sessionData.lastActivity = Date.now();
|
|
499
|
+
delete sessionData.llmOverride;
|
|
449
500
|
await this.persistSessionData(sessionKey, sessionData);
|
|
450
501
|
});
|
|
451
502
|
this.logger.debug(`Reset session conversation: ${sessionId}`);
|
|
@@ -736,6 +787,7 @@ class SessionManager {
|
|
|
736
787
|
if (session) {
|
|
737
788
|
session.dispose();
|
|
738
789
|
this.sessions.delete(sessionId);
|
|
790
|
+
this.evictSessionInteractionState(sessionId);
|
|
739
791
|
this.logger.debug(
|
|
740
792
|
`Removed expired session from memory: ${sessionId} (chat history preserved)`
|
|
741
793
|
);
|
|
@@ -760,8 +812,7 @@ class SessionManager {
|
|
|
760
812
|
const session = await this.getSession(sId);
|
|
761
813
|
if (session) {
|
|
762
814
|
try {
|
|
763
|
-
this.
|
|
764
|
-
await session.switchLLM(newLLMConfig);
|
|
815
|
+
await this.applySessionLLMSwitch(sId, session, newLLMConfig);
|
|
765
816
|
} catch (error) {
|
|
766
817
|
failedSessions.push(sId);
|
|
767
818
|
this.logger.warn(
|
|
@@ -790,16 +841,7 @@ class SessionManager {
|
|
|
790
841
|
if (!session) {
|
|
791
842
|
throw SessionError.notFound(sessionId);
|
|
792
843
|
}
|
|
793
|
-
await
|
|
794
|
-
await this.runWithSessionDataLock(sessionId, async (sessionKey) => {
|
|
795
|
-
const sessionData = await this.services.storageManager.getDatabase().get(sessionKey);
|
|
796
|
-
if (!sessionData) {
|
|
797
|
-
return;
|
|
798
|
-
}
|
|
799
|
-
const { apiKey: _apiKey, ...configWithoutApiKey } = newLLMConfig;
|
|
800
|
-
sessionData.llmOverride = configWithoutApiKey;
|
|
801
|
-
await this.persistSessionData(sessionKey, sessionData);
|
|
802
|
-
});
|
|
844
|
+
await this.applySessionLLMSwitch(sessionId, session, newLLMConfig);
|
|
803
845
|
this.services.agentEventBus.emit("llm:switched", {
|
|
804
846
|
newConfig: newLLMConfig,
|
|
805
847
|
historyRetained: true,
|
|
@@ -808,6 +850,68 @@ class SessionManager {
|
|
|
808
850
|
const message = `Successfully switched to ${newLLMConfig.provider}/${newLLMConfig.model} for session ${sessionId}`;
|
|
809
851
|
return { message, warnings: [] };
|
|
810
852
|
}
|
|
853
|
+
async applySessionLLMSwitch(sessionId, session, newLLMConfig) {
|
|
854
|
+
const previousLLMConfig = this.services.stateManager.getRuntimeConfig(sessionId).llm;
|
|
855
|
+
const previousHadOverride = this.services.stateManager.hasSessionLLMOverride(sessionId);
|
|
856
|
+
const previousPersistedOverride = await this.getPersistedSessionLLMOverride(sessionId);
|
|
857
|
+
await this.setPersistedSessionLLMOverride(
|
|
858
|
+
sessionId,
|
|
859
|
+
this.toPersistedLLMConfig(newLLMConfig)
|
|
860
|
+
);
|
|
861
|
+
try {
|
|
862
|
+
this.services.stateManager.updateLLM(newLLMConfig, sessionId);
|
|
863
|
+
await session.switchLLM(newLLMConfig);
|
|
864
|
+
} catch (error) {
|
|
865
|
+
await this.setPersistedSessionLLMOverride(sessionId, previousPersistedOverride);
|
|
866
|
+
if (previousHadOverride) {
|
|
867
|
+
this.services.stateManager.updateLLM(previousLLMConfig, sessionId);
|
|
868
|
+
} else {
|
|
869
|
+
this.services.stateManager.clearSessionOverride(sessionId);
|
|
870
|
+
}
|
|
871
|
+
try {
|
|
872
|
+
await session.switchLLM(previousLLMConfig);
|
|
873
|
+
} catch (rollbackError) {
|
|
874
|
+
this.logger.error(
|
|
875
|
+
`Failed to roll back LLM switch for session ${sessionId}: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`
|
|
876
|
+
);
|
|
877
|
+
}
|
|
878
|
+
throw error;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
async getPersistedSessionLLMOverride(sessionId) {
|
|
882
|
+
const sessionData = await this.getSessionData(sessionId);
|
|
883
|
+
return sessionData?.llmOverride;
|
|
884
|
+
}
|
|
885
|
+
toPersistedLLMConfig(newLLMConfig) {
|
|
886
|
+
const { apiKey: _apiKey, ...configWithoutApiKey } = newLLMConfig;
|
|
887
|
+
return configWithoutApiKey;
|
|
888
|
+
}
|
|
889
|
+
async setPersistedSessionLLMOverride(sessionId, llmOverride) {
|
|
890
|
+
await this.runWithSessionDataLock(sessionId, async (sessionKey) => {
|
|
891
|
+
const sessionData = await this.services.storageManager.getDatabase().get(sessionKey);
|
|
892
|
+
if (!sessionData) {
|
|
893
|
+
return;
|
|
894
|
+
}
|
|
895
|
+
if (llmOverride !== void 0) {
|
|
896
|
+
sessionData.llmOverride = llmOverride;
|
|
897
|
+
} else {
|
|
898
|
+
delete sessionData.llmOverride;
|
|
899
|
+
}
|
|
900
|
+
await this.persistSessionData(sessionKey, sessionData);
|
|
901
|
+
});
|
|
902
|
+
}
|
|
903
|
+
async deleteSessionInteractionState(sessionId) {
|
|
904
|
+
this.services.stateManager.clearSessionOverride(sessionId);
|
|
905
|
+
await Promise.all([
|
|
906
|
+
this.services.toolManager.deleteSessionState(sessionId),
|
|
907
|
+
this.services.approvalManager.deleteSessionState(sessionId),
|
|
908
|
+
this.services.messageQueueStore.delete(sessionId)
|
|
909
|
+
]);
|
|
910
|
+
}
|
|
911
|
+
evictSessionInteractionState(sessionId) {
|
|
912
|
+
this.services.toolManager.evictSessionState(sessionId);
|
|
913
|
+
this.services.approvalManager.evictSessionState(sessionId);
|
|
914
|
+
}
|
|
811
915
|
async runWithSessionDataLock(sessionId, fn) {
|
|
812
916
|
const sessionKey = `session:${sessionId}`;
|
|
813
917
|
const previousLock = this.sessionDataLocks.get(sessionKey) ?? Promise.resolve();
|
|
@@ -868,6 +972,7 @@ class SessionManager {
|
|
|
868
972
|
delete this.cleanupInterval;
|
|
869
973
|
this.logger.debug("Periodic session cleanup stopped");
|
|
870
974
|
}
|
|
975
|
+
await this.clearPersistedQueuedMessages("shutdown");
|
|
871
976
|
const sessionIds = Array.from(this.sessions.keys());
|
|
872
977
|
for (const sessionId of sessionIds) {
|
|
873
978
|
try {
|
|
@@ -25,6 +25,7 @@ module.exports = __toCommonJS(title_generator_exports);
|
|
|
25
25
|
var import_factory = require("../llm/services/factory.js");
|
|
26
26
|
var import_events = require("../events/index.js");
|
|
27
27
|
var import_memory = require("./history/memory.js");
|
|
28
|
+
var import_message_queue = require("./message-queue.js");
|
|
28
29
|
async function generateSessionTitle(config, toolManager, systemPromptManager, resourceManager, userText, logger, opts = {}) {
|
|
29
30
|
const timeoutMs = opts.timeoutMs;
|
|
30
31
|
const controller = timeoutMs !== void 0 ? new AbortController() : void 0;
|
|
@@ -35,15 +36,21 @@ async function generateSessionTitle(config, toolManager, systemPromptManager, re
|
|
|
35
36
|
try {
|
|
36
37
|
const history = new import_memory.MemoryHistoryProvider(logger);
|
|
37
38
|
const bus = new import_events.SessionEventBus();
|
|
39
|
+
const sessionId = `titlegen-${Math.random().toString(36).slice(2)}`;
|
|
40
|
+
const options = {
|
|
41
|
+
messageQueue: import_message_queue.MessageQueueService.createEphemeral(bus, logger, sessionId)
|
|
42
|
+
};
|
|
38
43
|
const tempService = (0, import_factory.createLLMService)(
|
|
39
44
|
config,
|
|
40
45
|
toolManager,
|
|
41
46
|
systemPromptManager,
|
|
42
47
|
history,
|
|
43
48
|
bus,
|
|
44
|
-
|
|
49
|
+
sessionId,
|
|
45
50
|
resourceManager,
|
|
46
|
-
logger
|
|
51
|
+
logger,
|
|
52
|
+
options,
|
|
53
|
+
opts.languageModelFactory
|
|
47
54
|
);
|
|
48
55
|
const instruction = [
|
|
49
56
|
"Generate a short conversation title from the following user message.",
|
|
@@ -3,6 +3,7 @@ import type { ToolManager } from '../tools/tool-manager.js';
|
|
|
3
3
|
import type { SystemPromptManager } from '../systemPrompt/manager.js';
|
|
4
4
|
import type { ResourceManager } from '../resources/index.js';
|
|
5
5
|
import type { Logger } from '../logger/v2/types.js';
|
|
6
|
+
import type { LanguageModelFactory } from '../llm/services/types.js';
|
|
6
7
|
export interface GenerateSessionTitleResult {
|
|
7
8
|
title?: string;
|
|
8
9
|
error?: string;
|
|
@@ -14,6 +15,7 @@ export interface GenerateSessionTitleResult {
|
|
|
14
15
|
*/
|
|
15
16
|
export declare function generateSessionTitle(config: ValidatedLLMConfig, toolManager: ToolManager, systemPromptManager: SystemPromptManager, resourceManager: ResourceManager, userText: string, logger: Logger, opts?: {
|
|
16
17
|
timeoutMs?: number;
|
|
18
|
+
languageModelFactory?: LanguageModelFactory;
|
|
17
19
|
}): Promise<GenerateSessionTitleResult>;
|
|
18
20
|
/**
|
|
19
21
|
* Heuristic fallback when the LLM-based title fails.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"title-generator.d.ts","sourceRoot":"","sources":["../../src/session/title-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"title-generator.d.ts","sourceRoot":"","sources":["../../src/session/title-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAA2B,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAM9F,MAAM,WAAW,0BAA0B;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACtC,MAAM,EAAE,kBAAkB,EAC1B,WAAW,EAAE,WAAW,EACxB,mBAAmB,EAAE,mBAAmB,EACxC,eAAe,EAAE,eAAe,EAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,oBAAoB,CAAC,EAAE,oBAAoB,CAAA;CAAO,GAC/E,OAAO,CAAC,0BAA0B,CAAC,CAyDrC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA8BzE"}
|
|
@@ -2,6 +2,7 @@ import "../chunk-PTJYTZNU.js";
|
|
|
2
2
|
import { createLLMService } from "../llm/services/factory.js";
|
|
3
3
|
import { SessionEventBus } from "../events/index.js";
|
|
4
4
|
import { MemoryHistoryProvider } from "./history/memory.js";
|
|
5
|
+
import { MessageQueueService } from "./message-queue.js";
|
|
5
6
|
async function generateSessionTitle(config, toolManager, systemPromptManager, resourceManager, userText, logger, opts = {}) {
|
|
6
7
|
const timeoutMs = opts.timeoutMs;
|
|
7
8
|
const controller = timeoutMs !== void 0 ? new AbortController() : void 0;
|
|
@@ -12,15 +13,21 @@ async function generateSessionTitle(config, toolManager, systemPromptManager, re
|
|
|
12
13
|
try {
|
|
13
14
|
const history = new MemoryHistoryProvider(logger);
|
|
14
15
|
const bus = new SessionEventBus();
|
|
16
|
+
const sessionId = `titlegen-${Math.random().toString(36).slice(2)}`;
|
|
17
|
+
const options = {
|
|
18
|
+
messageQueue: MessageQueueService.createEphemeral(bus, logger, sessionId)
|
|
19
|
+
};
|
|
15
20
|
const tempService = createLLMService(
|
|
16
21
|
config,
|
|
17
22
|
toolManager,
|
|
18
23
|
systemPromptManager,
|
|
19
24
|
history,
|
|
20
25
|
bus,
|
|
21
|
-
|
|
26
|
+
sessionId,
|
|
22
27
|
resourceManager,
|
|
23
|
-
logger
|
|
28
|
+
logger,
|
|
29
|
+
options,
|
|
30
|
+
opts.languageModelFactory
|
|
24
31
|
);
|
|
25
32
|
const instruction = [
|
|
26
33
|
"Generate a short conversation title from the following user message.",
|
|
@@ -80,9 +80,9 @@ class TelemetryError {
|
|
|
80
80
|
import_error_codes.TelemetryErrorCode.NOT_INITIALIZED,
|
|
81
81
|
import_types.ErrorScope.TELEMETRY,
|
|
82
82
|
import_types.ErrorType.USER,
|
|
83
|
-
"Telemetry not initialized. Call Telemetry.init() first.",
|
|
83
|
+
"Telemetry not initialized. Call Telemetry.init() or Telemetry.registerGlobal() first.",
|
|
84
84
|
{
|
|
85
|
-
hint: "Ensure telemetry is initialized before accessing the global instance."
|
|
85
|
+
hint: "Ensure telemetry is initialized via Telemetry.init() or Telemetry.registerGlobal() before accessing the global instance."
|
|
86
86
|
}
|
|
87
87
|
);
|
|
88
88
|
}
|
package/dist/telemetry/errors.js
CHANGED
|
@@ -58,9 +58,9 @@ class TelemetryError {
|
|
|
58
58
|
TelemetryErrorCode.NOT_INITIALIZED,
|
|
59
59
|
ErrorScope.TELEMETRY,
|
|
60
60
|
ErrorType.USER,
|
|
61
|
-
"Telemetry not initialized. Call Telemetry.init() first.",
|
|
61
|
+
"Telemetry not initialized. Call Telemetry.init() or Telemetry.registerGlobal() first.",
|
|
62
62
|
{
|
|
63
|
-
hint: "Ensure telemetry is initialized before accessing the global instance."
|
|
63
|
+
hint: "Ensure telemetry is initialized via Telemetry.init() or Telemetry.registerGlobal() before accessing the global instance."
|
|
64
64
|
}
|
|
65
65
|
);
|
|
66
66
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { Telemetry } from './telemetry.js';
|
|
1
|
+
export { Telemetry, type TelemetryRegistrationOptions, type TelemetryShutdownHandler, } from './telemetry.js';
|
|
2
2
|
export { OtelConfigurationSchema } from './schemas.js';
|
|
3
3
|
export type { OtelConfiguration } from './schemas.js';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/telemetry/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/telemetry/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,SAAS,EACT,KAAK,4BAA4B,EACjC,KAAK,wBAAwB,GAChC,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/telemetry/index.js
CHANGED
|
@@ -40,17 +40,17 @@ class Telemetry {
|
|
|
40
40
|
name = "dexto-service";
|
|
41
41
|
_isInitialized = false;
|
|
42
42
|
_sdk;
|
|
43
|
+
_shutdownHandler;
|
|
43
44
|
static _initPromise;
|
|
44
45
|
static _signalHandlers;
|
|
45
|
-
constructor(config,
|
|
46
|
+
constructor(config, options) {
|
|
46
47
|
const serviceName = config.serviceName ?? "dexto-service";
|
|
47
48
|
const tracerName = config.tracerName ?? serviceName;
|
|
48
49
|
this.name = serviceName;
|
|
49
50
|
this.tracer = import_api.trace.getTracer(tracerName);
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
this._isInitialized = enabled && !!sdk;
|
|
51
|
+
this._sdk = options.sdk;
|
|
52
|
+
this._shutdownHandler = options.shutdown;
|
|
53
|
+
this._isInitialized = options.initialized;
|
|
54
54
|
}
|
|
55
55
|
static async buildTraceExporter(config) {
|
|
56
56
|
const e = config?.export;
|
|
@@ -178,7 +178,10 @@ class Telemetry {
|
|
|
178
178
|
process.once("SIGINT", sigint);
|
|
179
179
|
Telemetry._signalHandlers = { sigterm, sigint };
|
|
180
180
|
}
|
|
181
|
-
globalThis.__TELEMETRY__ = new Telemetry(config,
|
|
181
|
+
globalThis.__TELEMETRY__ = new Telemetry(config, {
|
|
182
|
+
initialized: enabled && !!sdk,
|
|
183
|
+
...sdk !== void 0 && { sdk }
|
|
184
|
+
});
|
|
182
185
|
}
|
|
183
186
|
return globalThis.__TELEMETRY__;
|
|
184
187
|
})();
|
|
@@ -194,6 +197,38 @@ class Telemetry {
|
|
|
194
197
|
);
|
|
195
198
|
}
|
|
196
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* Register a global telemetry instance after a host installs its own provider/exporter lifecycle.
|
|
202
|
+
*
|
|
203
|
+
* This keeps core instrumentation active without forcing the default Node SDK bootstrap path.
|
|
204
|
+
*/
|
|
205
|
+
static async registerGlobal(options = {}) {
|
|
206
|
+
try {
|
|
207
|
+
if (globalThis.__TELEMETRY__) return globalThis.__TELEMETRY__;
|
|
208
|
+
if (Telemetry._initPromise) return Telemetry._initPromise;
|
|
209
|
+
const config = options.config ?? {};
|
|
210
|
+
const initialized = options.initialized ?? true;
|
|
211
|
+
Telemetry._initPromise = Promise.resolve().then(() => {
|
|
212
|
+
if (!globalThis.__TELEMETRY__) {
|
|
213
|
+
globalThis.__TELEMETRY__ = new Telemetry(config, {
|
|
214
|
+
initialized,
|
|
215
|
+
...options.shutdown !== void 0 && { shutdown: options.shutdown }
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
return globalThis.__TELEMETRY__;
|
|
219
|
+
});
|
|
220
|
+
return await Telemetry._initPromise;
|
|
221
|
+
} catch (error) {
|
|
222
|
+
Telemetry._initPromise = void 0;
|
|
223
|
+
if (error instanceof import_DextoRuntimeError.DextoRuntimeError) {
|
|
224
|
+
throw error;
|
|
225
|
+
}
|
|
226
|
+
throw import_errors.TelemetryError.initializationFailed(
|
|
227
|
+
error instanceof Error ? error.message : String(error),
|
|
228
|
+
error
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
197
232
|
static getActiveSpan() {
|
|
198
233
|
const span = import_api.trace.getActiveSpan();
|
|
199
234
|
return span;
|
|
@@ -275,25 +310,31 @@ class Telemetry {
|
|
|
275
310
|
* This ensures agent switching works even when telemetry export fails.
|
|
276
311
|
*/
|
|
277
312
|
async shutdown() {
|
|
278
|
-
|
|
279
|
-
|
|
313
|
+
try {
|
|
314
|
+
if (this._shutdownHandler) {
|
|
315
|
+
await this._shutdownHandler();
|
|
316
|
+
} else if (this._sdk) {
|
|
280
317
|
await this._sdk.shutdown();
|
|
281
|
-
} catch (error) {
|
|
282
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
283
|
-
import_logger.logger.warn(`Telemetry shutdown failed to flush spans (non-blocking): ${errorMsg}`);
|
|
284
|
-
} finally {
|
|
285
|
-
this._isInitialized = false;
|
|
286
|
-
globalThis.__TELEMETRY__ = void 0;
|
|
287
|
-
if (Telemetry._signalHandlers) {
|
|
288
|
-
process.off("SIGTERM", Telemetry._signalHandlers.sigterm);
|
|
289
|
-
process.off("SIGINT", Telemetry._signalHandlers.sigint);
|
|
290
|
-
Telemetry._signalHandlers = void 0;
|
|
291
|
-
}
|
|
292
|
-
this._sdk = void 0;
|
|
293
|
-
Telemetry._initPromise = void 0;
|
|
294
318
|
}
|
|
319
|
+
} catch (error) {
|
|
320
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
321
|
+
import_logger.logger.warn(`Telemetry shutdown failed to flush spans (non-blocking): ${errorMsg}`);
|
|
322
|
+
} finally {
|
|
323
|
+
this.cleanupAfterShutdown();
|
|
295
324
|
}
|
|
296
325
|
}
|
|
326
|
+
cleanupAfterShutdown() {
|
|
327
|
+
this._isInitialized = false;
|
|
328
|
+
globalThis.__TELEMETRY__ = void 0;
|
|
329
|
+
if (Telemetry._signalHandlers) {
|
|
330
|
+
process.off("SIGTERM", Telemetry._signalHandlers.sigterm);
|
|
331
|
+
process.off("SIGINT", Telemetry._signalHandlers.sigint);
|
|
332
|
+
Telemetry._signalHandlers = void 0;
|
|
333
|
+
}
|
|
334
|
+
this._sdk = void 0;
|
|
335
|
+
this._shutdownHandler = void 0;
|
|
336
|
+
Telemetry._initPromise = void 0;
|
|
337
|
+
}
|
|
297
338
|
}
|
|
298
339
|
// Annotate the CommonJS export names for ESM import in node:
|
|
299
340
|
0 && (module.exports = {
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { Tracer, Context, BaggageEntry } from '@opentelemetry/api';
|
|
2
2
|
import type { OtelConfiguration } from './schemas.js';
|
|
3
|
+
export type TelemetryShutdownHandler = () => Promise<void>;
|
|
4
|
+
export type TelemetryRegistrationOptions = {
|
|
5
|
+
config?: OtelConfiguration | undefined;
|
|
6
|
+
initialized?: boolean | undefined;
|
|
7
|
+
shutdown?: TelemetryShutdownHandler | undefined;
|
|
8
|
+
};
|
|
3
9
|
declare global {
|
|
4
10
|
var __TELEMETRY__: Telemetry | undefined;
|
|
5
11
|
}
|
|
@@ -17,6 +23,7 @@ export declare class Telemetry {
|
|
|
17
23
|
name: string;
|
|
18
24
|
private _isInitialized;
|
|
19
25
|
private _sdk?;
|
|
26
|
+
private _shutdownHandler?;
|
|
20
27
|
private static _initPromise?;
|
|
21
28
|
private static _signalHandlers?;
|
|
22
29
|
private constructor();
|
|
@@ -28,6 +35,12 @@ export declare class Telemetry {
|
|
|
28
35
|
* @returns Telemetry instance that can be used for tracing
|
|
29
36
|
*/
|
|
30
37
|
static init(config?: OtelConfiguration, exporter?: import('@opentelemetry/sdk-trace-base').SpanExporter): Promise<Telemetry>;
|
|
38
|
+
/**
|
|
39
|
+
* Register a global telemetry instance after a host installs its own provider/exporter lifecycle.
|
|
40
|
+
*
|
|
41
|
+
* This keeps core instrumentation active without forcing the default Node SDK bootstrap path.
|
|
42
|
+
*/
|
|
43
|
+
static registerGlobal(options?: TelemetryRegistrationOptions): Promise<Telemetry>;
|
|
31
44
|
static getActiveSpan(): import("@opentelemetry/api").Span | undefined;
|
|
32
45
|
/**
|
|
33
46
|
* Get the global telemetry instance
|
|
@@ -70,5 +83,6 @@ export declare class Telemetry {
|
|
|
70
83
|
* This ensures agent switching works even when telemetry export fails.
|
|
71
84
|
*/
|
|
72
85
|
shutdown(): Promise<void>;
|
|
86
|
+
private cleanupAfterShutdown;
|
|
73
87
|
}
|
|
74
88
|
//# sourceMappingURL=telemetry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/telemetry/telemetry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/telemetry/telemetry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAUtD,MAAM,MAAM,wBAAwB,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;AAE3D,MAAM,MAAM,4BAA4B,GAAG;IACvC,MAAM,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;CACnD,CAAC;AASF,OAAO,CAAC,MAAM,CAAC;IACX,IAAI,aAAa,EAAE,SAAS,GAAG,SAAS,CAAC;CAC5C;AAED;;;;;;;;GAQG;AACH,qBAAa,SAAS;IACX,MAAM,EAAE,MAAM,CAA4B;IACjD,IAAI,EAAE,MAAM,CAAmB;IAC/B,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,IAAI,CAAC,CAA0B;IACvC,OAAO,CAAC,gBAAgB,CAAC,CAAuC;IAChE,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAiC;IAC7D,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAA0D;IAEzF,OAAO;mBAWc,kBAAkB;IA0DvC;;;;;OAKG;WACU,IAAI,CACb,MAAM,GAAE,iBAAsB,EAC9B,QAAQ,CAAC,EAAE,OAAO,+BAA+B,EAAE,YAAY,GAChE,OAAO,CAAC,SAAS,CAAC;IAiIrB;;;;OAIG;WACU,cAAc,CAAC,OAAO,GAAE,4BAAiC,GAAG,OAAO,CAAC,SAAS,CAAC;IAiC3F,MAAM,CAAC,aAAa;IAKpB;;;;OAIG;IACH,MAAM,CAAC,GAAG,IAAI,SAAS;IAOvB;;;OAGG;IACH,MAAM,CAAC,iBAAiB,IAAI,OAAO;IAInC;;;;;OAKG;WACU,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5C;;;OAGG;IACI,aAAa,IAAI,OAAO;IAI/B,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,GAAG,GAAE,OAA8B;IAc5F,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,IAAI;IAI/C;;;OAGG;IACU,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAUxC;;;;;;;;;OASG;IACU,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBtC,OAAO,CAAC,oBAAoB;CAiB/B"}
|