@xalia/agent 0.6.9 → 0.6.11
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/README.md +11 -0
- package/dist/agent/src/agent/agent.js +77 -18
- package/dist/agent/src/agent/agentUtils.js +3 -2
- package/dist/agent/src/agent/documentSummarizer.js +126 -0
- package/dist/agent/src/agent/dummyLLM.js +25 -22
- package/dist/agent/src/agent/imageGenLLM.js +22 -19
- package/dist/agent/src/agent/llm.js +1 -1
- package/dist/agent/src/agent/openAILLM.js +15 -12
- package/dist/agent/src/agent/openAILLMStreaming.js +68 -37
- package/dist/agent/src/agent/repeatLLM.js +16 -7
- package/dist/agent/src/agent/tokenCounter.js +390 -0
- package/dist/agent/src/agent/tokenCounter.test.js +206 -0
- package/dist/agent/src/agent/toolSettings.js +17 -0
- package/dist/agent/src/agent/tools/calculatorTool.js +45 -0
- package/dist/agent/src/agent/tools/contentExtractors/pdfToText.js +55 -0
- package/dist/agent/src/agent/tools/datetimeTool.js +38 -0
- package/dist/agent/src/agent/tools/fileManager/fileManagerTool.js +156 -0
- package/dist/agent/src/agent/tools/fileManager/index.js +31 -0
- package/dist/agent/src/agent/tools/fileManager/memoryFileManager.js +102 -0
- package/dist/agent/src/{chat/data → agent/tools/fileManager}/mimeTypes.js +3 -1
- package/dist/agent/src/agent/tools/fileManager/prompt.js +33 -0
- package/dist/agent/src/{chat/data/dbSessionFileModels.js → agent/tools/fileManager/types.js} +7 -0
- package/dist/agent/src/agent/tools/index.js +64 -0
- package/dist/agent/src/agent/tools/openUrlTool.js +57 -0
- package/dist/agent/src/agent/tools/renderTool.js +89 -0
- package/dist/agent/src/agent/tools/utils.js +61 -0
- package/dist/agent/src/{chat/utils/search.js → agent/tools/webSearch.js} +1 -2
- package/dist/agent/src/agent/tools/webSearchTool.js +40 -0
- package/dist/agent/src/chat/client/chatClient.js +28 -0
- package/dist/agent/src/chat/client/index.js +4 -1
- package/dist/agent/src/chat/client/sessionClient.js +28 -2
- package/dist/agent/src/chat/constants.js +8 -0
- package/dist/agent/src/chat/data/dbSessionFiles.js +11 -6
- package/dist/agent/src/chat/protocol/messages.js +5 -0
- package/dist/agent/src/chat/server/chatContextManager.js +45 -25
- package/dist/agent/src/chat/server/conversation.js +3 -0
- package/dist/agent/src/chat/server/imageGeneratorTools.js +20 -8
- package/dist/agent/src/chat/server/openAIRouterLLM.js +0 -3
- package/dist/agent/src/chat/server/openSession.js +218 -55
- package/dist/agent/src/chat/server/promptRefiner.js +86 -0
- package/dist/agent/src/chat/server/server.js +5 -1
- package/dist/agent/src/chat/server/sessionFileManager.js +22 -221
- package/dist/agent/src/chat/server/sessionRegistry.js +87 -0
- package/dist/agent/src/chat/server/titleGenerator.js +112 -0
- package/dist/agent/src/chat/server/titleGenerator.test.js +113 -0
- package/dist/agent/src/chat/server/tools.js +63 -287
- package/dist/agent/src/chat/utils/approvalManager.js +6 -3
- package/dist/agent/src/chat/utils/multiAsyncQueue.js +3 -0
- package/dist/agent/src/test/agent.test.js +16 -17
- package/dist/agent/src/test/chatContextManager.test.js +15 -3
- package/dist/agent/src/test/dbMcpServerConfigs.test.js +4 -4
- package/dist/agent/src/test/dbSessionFiles.test.js +17 -17
- package/dist/agent/src/test/testTools.js +6 -1
- package/dist/agent/src/test/tools.test.js +27 -9
- package/dist/agent/src/tool/agentChat.js +5 -2
- package/dist/agent/src/tool/chatMain.js +34 -7
- package/dist/agent/src/tool/commandPrompt.js +2 -2
- package/dist/agent/src/tool/files.js +7 -8
- package/package.json +8 -2
- package/.env.development +0 -1
- package/.prettierrc.json +0 -11
- package/dist/agent/src/agent/tools.js +0 -44
- package/eslint.config.mjs +0 -38
- package/scripts/chat_server +0 -8
- package/scripts/git_message +0 -31
- package/scripts/git_wip +0 -21
- package/scripts/pr_message +0 -18
- package/scripts/pr_review +0 -16
- package/scripts/setup_chat +0 -90
- package/scripts/shutdown_chat_server +0 -42
- package/scripts/start_chat_server +0 -24
- package/scripts/sudomcp_import +0 -23
- package/scripts/test_chat +0 -308
- package/src/agent/agent.ts +0 -624
- package/src/agent/agentUtils.ts +0 -285
- package/src/agent/compressingContextManager.ts +0 -129
- package/src/agent/context.ts +0 -265
- package/src/agent/contextWithWorkspace.ts +0 -162
- package/src/agent/dummyLLM.ts +0 -126
- package/src/agent/iAgentEventHandler.ts +0 -64
- package/src/agent/imageGenLLM.ts +0 -97
- package/src/agent/imageGenerator.ts +0 -45
- package/src/agent/iplatform.ts +0 -18
- package/src/agent/llm.ts +0 -74
- package/src/agent/mcpServerManager.ts +0 -541
- package/src/agent/nullAgentEventHandler.ts +0 -26
- package/src/agent/nullPlatform.ts +0 -13
- package/src/agent/openAI.ts +0 -123
- package/src/agent/openAILLM.ts +0 -95
- package/src/agent/openAILLMStreaming.ts +0 -609
- package/src/agent/promptProvider.ts +0 -87
- package/src/agent/repeatLLM.ts +0 -50
- package/src/agent/sudoMcpServerManager.ts +0 -361
- package/src/agent/tokenAuth.ts +0 -50
- package/src/agent/tools.ts +0 -57
- package/src/chat/client/chatClient.ts +0 -922
- package/src/chat/client/connection.test.ts +0 -241
- package/src/chat/client/connection.ts +0 -286
- package/src/chat/client/constants.ts +0 -1
- package/src/chat/client/index.ts +0 -18
- package/src/chat/client/interfaces.ts +0 -34
- package/src/chat/client/sessionClient.ts +0 -537
- package/src/chat/client/sessionFiles.ts +0 -142
- package/src/chat/client/teamManager.ts +0 -29
- package/src/chat/data/apiKeyManager.ts +0 -76
- package/src/chat/data/dataModels.ts +0 -101
- package/src/chat/data/database.ts +0 -997
- package/src/chat/data/dbMcpServerConfigs.ts +0 -59
- package/src/chat/data/dbSessionFileModels.ts +0 -113
- package/src/chat/data/dbSessionFiles.ts +0 -99
- package/src/chat/data/dbSessionMessages.ts +0 -102
- package/src/chat/data/mimeTypes.ts +0 -58
- package/src/chat/protocol/connectionMessages.ts +0 -49
- package/src/chat/protocol/constants.ts +0 -55
- package/src/chat/protocol/errors.ts +0 -16
- package/src/chat/protocol/messages.ts +0 -846
- package/src/chat/server/README.md +0 -127
- package/src/chat/server/chatContextManager.ts +0 -639
- package/src/chat/server/connectionManager.test.ts +0 -246
- package/src/chat/server/connectionManager.ts +0 -506
- package/src/chat/server/conversation.ts +0 -316
- package/src/chat/server/errorUtils.ts +0 -28
- package/src/chat/server/imageGeneratorTools.ts +0 -160
- package/src/chat/server/openAIRouterLLM.ts +0 -171
- package/src/chat/server/openSession.ts +0 -1689
- package/src/chat/server/openSessionMessageSender.ts +0 -4
- package/src/chat/server/server.ts +0 -175
- package/src/chat/server/sessionFileManager.ts +0 -422
- package/src/chat/server/sessionRegistry.test.ts +0 -137
- package/src/chat/server/sessionRegistry.ts +0 -1425
- package/src/chat/server/test-utils/mockFactories.ts +0 -422
- package/src/chat/server/tools.ts +0 -397
- package/src/chat/utils/agentSessionMap.ts +0 -76
- package/src/chat/utils/approvalManager.ts +0 -183
- package/src/chat/utils/asyncLock.ts +0 -43
- package/src/chat/utils/asyncQueue.ts +0 -62
- package/src/chat/utils/htmlToText.ts +0 -61
- package/src/chat/utils/multiAsyncQueue.ts +0 -62
- package/src/chat/utils/responseAwaiter.ts +0 -181
- package/src/chat/utils/search.ts +0 -139
- package/src/chat/utils/userResolver.ts +0 -48
- package/src/chat/utils/websocket.ts +0 -16
- package/src/index.ts +0 -0
- package/src/test/agent.test.ts +0 -590
- package/src/test/approvalManager.test.ts +0 -141
- package/src/test/chatContextManager.test.ts +0 -527
- package/src/test/clientServerConnection.test.ts +0 -205
- package/src/test/compressingContextManager.test.ts +0 -77
- package/src/test/context.test.ts +0 -150
- package/src/test/contextTestTools.ts +0 -95
- package/src/test/conversation.test.ts +0 -109
- package/src/test/db.test.ts +0 -363
- package/src/test/dbMcpServerConfigs.test.ts +0 -112
- package/src/test/dbSessionFiles.test.ts +0 -258
- package/src/test/dbSessionMessages.test.ts +0 -85
- package/src/test/dbTestTools.ts +0 -157
- package/src/test/imageLoad.test.ts +0 -15
- package/src/test/mcpServerManager.test.ts +0 -114
- package/src/test/multiAsyncQueue.test.ts +0 -183
- package/src/test/openaiStreaming.test.ts +0 -177
- package/src/test/prompt.test.ts +0 -27
- package/src/test/promptProvider.test.ts +0 -33
- package/src/test/responseAwaiter.test.ts +0 -103
- package/src/test/sudoMcpServerManager.test.ts +0 -63
- package/src/test/testTools.ts +0 -171
- package/src/test/tools.test.ts +0 -39
- package/src/tool/agentChat.ts +0 -194
- package/src/tool/agentMain.ts +0 -180
- package/src/tool/chatMain.ts +0 -594
- package/src/tool/commandPrompt.ts +0 -264
- package/src/tool/files.ts +0 -84
- package/src/tool/main.ts +0 -25
- package/src/tool/nodePlatform.ts +0 -73
- package/src/tool/options.ts +0 -144
- package/src/tool/prompt.ts +0 -101
- package/test_data/background_test_profile.json +0 -6
- package/test_data/background_test_script.json +0 -11
- package/test_data/dummyllm_script_crash.json +0 -32
- package/test_data/dummyllm_script_image_gen.json +0 -19
- package/test_data/dummyllm_script_image_gen_fe.json +0 -29
- package/test_data/dummyllm_script_invoke_image_gen_tool.json +0 -37
- package/test_data/dummyllm_script_render_tool.json +0 -29
- package/test_data/dummyllm_script_simplecalc.json +0 -28
- package/test_data/dummyllm_script_test_auto_approve.json +0 -81
- package/test_data/dummyllm_script_test_simplecalc_addition.json +0 -29
- package/test_data/frog.png +0 -0
- package/test_data/frog.png.b64 +0 -1
- package/test_data/git_message_profile.json +0 -4
- package/test_data/git_wip_system.txt +0 -5
- package/test_data/image_gen_test_profile.json +0 -5
- package/test_data/pr_message_profile.json +0 -4
- package/test_data/pr_review_profile.json +0 -4
- package/test_data/prompt_simplecalc.txt +0 -1
- package/test_data/simplecalc_profile.json +0 -4
- package/test_data/sudomcp_import_profile.json +0 -4
- package/test_data/test_script_profile.json +0 -8
- package/tsconfig.json +0 -13
- package/vitest.config.ts +0 -39
- /package/dist/agent/src/{chat/utils → agent/tools/contentExtractors}/htmlToText.js +0 -0
|
@@ -14,7 +14,6 @@ const DEFAULT_PROVIDER_URLS = {
|
|
|
14
14
|
openrouter: "https://openrouter.ai/api/v1",
|
|
15
15
|
openai: "https://api.openai.com/v1",
|
|
16
16
|
anthropic: "https://api.anthropic.com/v1",
|
|
17
|
-
together: "https://api.together.xyz/v1",
|
|
18
17
|
};
|
|
19
18
|
const DEFAULT_MODEL_MAP = {
|
|
20
19
|
"gpt-4o-mini": "openai",
|
|
@@ -28,8 +27,6 @@ const DEFAULT_MODEL_MAP = {
|
|
|
28
27
|
"anthropic/claude-sonnet-4": "openrouter",
|
|
29
28
|
"anthropic/claude-sonnet-4.5": "openrouter",
|
|
30
29
|
"claude-3-7-sonnet-20250219": "anthropic",
|
|
31
|
-
"arcee-ai/AFM-4.5B-Preview": "together",
|
|
32
|
-
"meta-llama/Llama-3.3-70B-Instruct-Turbo-Free": "together",
|
|
33
30
|
};
|
|
34
31
|
let cached_maps = undefined;
|
|
35
32
|
// TODO: Move this to the CLI command args?
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.OpenSession = exports.ChatSessionAgentEventHandler = exports.ChatSessionMessageSender = exports.GUEST_TOKEN_PREFIX = exports.DEFAULT_NUM_MESSGAES = void 0;
|
|
3
|
+
exports.OpenSession = exports.ChatSessionAgentEventHandler = exports.ChatSessionMessageSender = exports.RACE_MODE_TIMEOUT_MS = exports.GUEST_TOKEN_PREFIX = exports.DEFAULT_NUM_MESSGAES = void 0;
|
|
4
4
|
const assert_1 = require("assert");
|
|
5
|
+
const uuid_1 = require("uuid");
|
|
5
6
|
const sdk_1 = require("@xalia/xmcp/sdk");
|
|
6
7
|
const agent_1 = require("../../agent/agent");
|
|
7
8
|
const sudoMcpServerManager_1 = require("../../agent/sudoMcpServerManager");
|
|
8
9
|
const agentUtils_1 = require("../../agent/agentUtils");
|
|
10
|
+
const titleGenerator_1 = require("./titleGenerator");
|
|
9
11
|
const asyncQueue_1 = require("../utils/asyncQueue");
|
|
10
12
|
const multiAsyncQueue_1 = require("../utils/multiAsyncQueue");
|
|
11
13
|
const database_1 = require("../data/database");
|
|
@@ -15,12 +17,16 @@ const tools_1 = require("./tools");
|
|
|
15
17
|
const chatContextManager_1 = require("./chatContextManager");
|
|
16
18
|
const conversation_1 = require("./conversation");
|
|
17
19
|
const sessionFileManager_1 = require("./sessionFileManager");
|
|
20
|
+
const fileManager_1 = require("../../agent/tools/fileManager");
|
|
21
|
+
const pdfToText_1 = require("../../agent/tools/contentExtractors/pdfToText");
|
|
22
|
+
const documentSummarizer_1 = require("../../agent/documentSummarizer");
|
|
18
23
|
const errorUtils_1 = require("./errorUtils");
|
|
19
24
|
const nodePlatform_1 = require("../../tool/nodePlatform");
|
|
20
25
|
const dbMcpServerConfigs_1 = require("../data/dbMcpServerConfigs");
|
|
21
26
|
const apiKeyManager_1 = require("../data/apiKeyManager");
|
|
22
27
|
const dbSessionMessages_1 = require("../data/dbSessionMessages");
|
|
23
28
|
const openAIRouterLLM_1 = require("./openAIRouterLLM");
|
|
29
|
+
const responseAwaiter_1 = require("../utils/responseAwaiter");
|
|
24
30
|
/**
|
|
25
31
|
* The model to use when the AgentProfile does not specify one.
|
|
26
32
|
*/
|
|
@@ -30,6 +36,7 @@ const DEFAULT_CHAT_LLM_MODEL = process.env["DEFAULT_LLM_MODEL"] || "anthropic/cl
|
|
|
30
36
|
*/
|
|
31
37
|
exports.DEFAULT_NUM_MESSGAES = 500;
|
|
32
38
|
exports.GUEST_TOKEN_PREFIX = "guest";
|
|
39
|
+
exports.RACE_MODE_TIMEOUT_MS = 120000;
|
|
33
40
|
const logger = (0, sdk_1.getLogger)();
|
|
34
41
|
/**
|
|
35
42
|
* Implementation of ICheckpointWriter that writes into the DB.
|
|
@@ -111,23 +118,24 @@ class ChatSessionPlatform {
|
|
|
111
118
|
}
|
|
112
119
|
}
|
|
113
120
|
class ChatSessionAgentEventHandler {
|
|
114
|
-
constructor(sessionUUID, sender, approvalManager, contextTx) {
|
|
121
|
+
constructor(sessionUUID, sender, approvalManager, contextTx, alt) {
|
|
115
122
|
this.sessionUUID = sessionUUID;
|
|
116
123
|
this.sender = sender;
|
|
117
124
|
this.approvalManager = approvalManager;
|
|
118
125
|
this.contextTx = contextTx;
|
|
126
|
+
this.alt = alt;
|
|
119
127
|
}
|
|
120
128
|
onCompletion(result) {
|
|
121
|
-
logger.debug(`[OpenSession.onCompletion] : ${JSON.stringify(result)}`);
|
|
129
|
+
logger.debug(`[OpenSession.onCompletion] ${this.alt || ""} : ${JSON.stringify(result)}`);
|
|
122
130
|
// Nothing to broadcast. Caller will receive this via onAgentMessage.
|
|
123
131
|
this.contextTx.processAgentResponse(result);
|
|
124
132
|
}
|
|
125
133
|
onImage(image) {
|
|
126
|
-
logger.debug(`[OpenSession.onImage] : ${image.image_url.url}`);
|
|
134
|
+
logger.debug(`[OpenSession.onImage] ${this.alt || ""} : ${image.image_url.url}`);
|
|
127
135
|
throw new Error("[OpenSession.onImage] unimplemented");
|
|
128
136
|
}
|
|
129
137
|
onToolCallResult(result) {
|
|
130
|
-
logger.debug(`[onToolCallResult] : ${JSON.stringify(result)}`);
|
|
138
|
+
logger.debug(`[onToolCallResult] ${this.alt || ""} : ${JSON.stringify(result)}`);
|
|
131
139
|
const toolCallMessage = this.contextTx.processToolCallResult(result);
|
|
132
140
|
this.sender.broadcast(toolCallMessage);
|
|
133
141
|
}
|
|
@@ -139,12 +147,13 @@ class ChatSessionAgentEventHandler {
|
|
|
139
147
|
type: "tool_call",
|
|
140
148
|
tool_call: toolCall,
|
|
141
149
|
session_id: this.sessionUUID,
|
|
150
|
+
...(this.alt ? { alt: this.alt } : {}),
|
|
142
151
|
});
|
|
143
152
|
return true;
|
|
144
153
|
}
|
|
145
154
|
// TODO: Need a proper mapping to/from MCP calls to tool names
|
|
146
155
|
const [serverName, tool] = toolCall.function.name.split("__");
|
|
147
|
-
const { approved, requested } = await this.approvalManager.getApproval(serverName, tool, toolCall);
|
|
156
|
+
const { approved, requested } = await this.approvalManager.getApproval(serverName, tool, toolCall, this.alt);
|
|
148
157
|
// For now, the frontend uses the tool_call data in the
|
|
149
158
|
// "approve_tool_call" request to display the tool call data. If approval
|
|
150
159
|
// was requested in this way, don't send the "tool_call" message as well.
|
|
@@ -153,25 +162,31 @@ class ChatSessionAgentEventHandler {
|
|
|
153
162
|
type: "tool_call",
|
|
154
163
|
tool_call: toolCall,
|
|
155
164
|
session_id: this.sessionUUID,
|
|
165
|
+
...(this.alt ? { alt: this.alt } : {}),
|
|
156
166
|
});
|
|
157
167
|
}
|
|
158
168
|
return approved;
|
|
159
169
|
}
|
|
160
170
|
onAgentMessage(msg, end) {
|
|
161
|
-
logger.debug(`[OpenSession.onAgentMessage] msg: ${msg},
|
|
171
|
+
logger.debug(`[OpenSession.onAgentMessage] ${this.alt || ""} msg: ${msg}, ` +
|
|
172
|
+
`end: ${String(end)}`);
|
|
162
173
|
// Inform the contextManager and broadcast the ServerAgentMessageChunk
|
|
163
174
|
const agentMsgChunk = this.contextTx.processAgentMessageChunk(msg, end);
|
|
175
|
+
if (this.alt) {
|
|
176
|
+
agentMsgChunk.alt = this.alt;
|
|
177
|
+
}
|
|
164
178
|
this.sender.broadcast(agentMsgChunk);
|
|
165
179
|
return Promise.resolve();
|
|
166
180
|
}
|
|
167
181
|
onReasoning(reasoning) {
|
|
168
182
|
return new Promise((r) => {
|
|
169
|
-
logger.debug(`[OpenSession.onReasoning]${reasoning}`);
|
|
183
|
+
logger.debug(`[OpenSession.onReasoning] ${this.alt || ""} ${reasoning}`);
|
|
170
184
|
if (reasoning.length > 0) {
|
|
171
185
|
this.sender.broadcast({
|
|
172
186
|
type: "agent_reasoning_chunk",
|
|
173
187
|
reasoning,
|
|
174
188
|
session_id: this.sessionUUID,
|
|
189
|
+
...(this.alt ? { alt: this.alt } : {}),
|
|
175
190
|
});
|
|
176
191
|
}
|
|
177
192
|
r();
|
|
@@ -190,7 +205,7 @@ exports.ChatSessionAgentEventHandler = ChatSessionAgentEventHandler;
|
|
|
190
205
|
* tool approvals and other interactions).
|
|
191
206
|
*/
|
|
192
207
|
class OpenSession {
|
|
193
|
-
constructor(db, agent, sessionData, savedAgentProfile, isPersisted, sessionParticipants, agentProfilePreferences, skillManager, contextManager, sender, approvalManager, fileManager) {
|
|
208
|
+
constructor(db, agent, sessionData, savedAgentProfile, isPersisted, sessionParticipants, agentProfilePreferences, skillManager, contextManager, sender, approvalManager, fileManager, platform) {
|
|
194
209
|
this.db = db;
|
|
195
210
|
this.agent = agent;
|
|
196
211
|
this.sessionUUID = sessionData.session_uuid;
|
|
@@ -208,10 +223,13 @@ class OpenSession {
|
|
|
208
223
|
this.approvalManager = approvalManager;
|
|
209
224
|
this.savedAgentProfile = savedAgentProfile;
|
|
210
225
|
this.sessionFileManager = fileManager;
|
|
226
|
+
this.platform = platform;
|
|
227
|
+
this.raceModeAwaiter = responseAwaiter_1.ResponseAwaiter.init(undefined, (m) => m.message_id, exports.RACE_MODE_TIMEOUT_MS);
|
|
211
228
|
this.isPersisted = isPersisted;
|
|
212
229
|
this.sessionTitle = sessionData.title;
|
|
213
230
|
this.sessionUpdatedAt = sessionData.updated_at;
|
|
214
231
|
this.agentPaused = sessionData.agent_paused;
|
|
232
|
+
this.titleGenerator = (0, titleGenerator_1.createTitleGenerator)();
|
|
215
233
|
fileManager.addEventHandler(this);
|
|
216
234
|
this.updateParticipantsPrompt();
|
|
217
235
|
}
|
|
@@ -222,8 +240,8 @@ class OpenSession {
|
|
|
222
240
|
const platform = new ChatSessionPlatform(sender, sessionId, ownerData.uuid);
|
|
223
241
|
const toolApprovalManager = new approvalManager_1.ToolApprovalManager(sessionData.session_uuid, savedAgentProfile.uuid, savedAgentProfile.preferences, sender, new approvalManager_1.DbAgentPreferencesWriter(db));
|
|
224
242
|
const checkpointWriter = new DBCheckpointWriter(db, sessionId);
|
|
225
|
-
const { agent, skillManager, contextManager } = await createContextAndAgent(sessionId, savedAgentProfile.profile.system_prompt, savedAgentProfile.profile.model || DEFAULT_CHAT_LLM_MODEL, sessionMessages, sessionData.workspace, sessionCheckpoint, ownerData, ownerApiKey, xmcpUrl, fileManager, platform, checkpointWriter);
|
|
226
|
-
const openSession = new OpenSession(db, agent, sessionData, savedAgentProfile, isPersisted, sessionParticipants, savedAgentProfile.preferences, skillManager, contextManager, sender, toolApprovalManager, fileManager);
|
|
243
|
+
const { agent, skillManager, contextManager } = await createContextAndAgent(sessionId, savedAgentProfile.profile.system_prompt, savedAgentProfile.profile.model || DEFAULT_CHAT_LLM_MODEL, sessionMessages, sessionData.workspace, sessionCheckpoint, ownerData, ownerApiKey, xmcpUrl, fileManager, platform, checkpointWriter, sender);
|
|
244
|
+
const openSession = new OpenSession(db, agent, sessionData, savedAgentProfile, isPersisted, sessionParticipants, savedAgentProfile.preferences, skillManager, contextManager, sender, toolApprovalManager, fileManager, platform);
|
|
227
245
|
// Note, MCP servers have not been enabled yet
|
|
228
246
|
return openSession;
|
|
229
247
|
}
|
|
@@ -298,7 +316,9 @@ class OpenSession {
|
|
|
298
316
|
});
|
|
299
317
|
});
|
|
300
318
|
// send conversation history
|
|
301
|
-
const conversationMessages = this.contextManager
|
|
319
|
+
const conversationMessages = this.contextManager
|
|
320
|
+
.getConversationMessages()
|
|
321
|
+
.concat(this.userMessageQueue.getEntries());
|
|
302
322
|
conversationMessages.forEach((message) => {
|
|
303
323
|
connMgr.sendToConnection(connectionId, message);
|
|
304
324
|
});
|
|
@@ -381,30 +401,25 @@ class OpenSession {
|
|
|
381
401
|
this.sender.broadcast(msg);
|
|
382
402
|
}
|
|
383
403
|
};
|
|
404
|
+
let errorMessage;
|
|
384
405
|
if (err instanceof errors_1.ChatFatalError) {
|
|
385
406
|
// ChatFatalError in session context should send error to specific user
|
|
386
407
|
// or broadcast if no specific user context
|
|
387
|
-
|
|
388
|
-
type: "session_error",
|
|
389
|
-
message: err.message,
|
|
390
|
-
session_id: this.sessionUUID,
|
|
391
|
-
});
|
|
408
|
+
errorMessage = err.message;
|
|
392
409
|
}
|
|
393
410
|
else if (err instanceof errors_1.ChatErrorMessage) {
|
|
394
|
-
|
|
395
|
-
type: "session_error",
|
|
396
|
-
message: err.message,
|
|
397
|
-
session_id: this.sessionUUID,
|
|
398
|
-
});
|
|
411
|
+
errorMessage = err.message;
|
|
399
412
|
}
|
|
400
413
|
else {
|
|
401
|
-
|
|
402
|
-
sendError({
|
|
403
|
-
type: "session_error",
|
|
404
|
-
message: errString,
|
|
405
|
-
session_id: this.sessionUUID,
|
|
406
|
-
});
|
|
414
|
+
errorMessage = (0, errorUtils_1.getErrorString)(err);
|
|
407
415
|
}
|
|
416
|
+
logger.error(`[OpenSession.handleError] sessionUUID=${this.sessionUUID} ` +
|
|
417
|
+
`from=${from ?? "broadcast"}: ${errorMessage}`);
|
|
418
|
+
sendError({
|
|
419
|
+
type: "session_error",
|
|
420
|
+
message: errorMessage,
|
|
421
|
+
session_id: this.sessionUUID,
|
|
422
|
+
});
|
|
408
423
|
return true;
|
|
409
424
|
}
|
|
410
425
|
// ISessionFileManagerEventHandler.onFileDeleted
|
|
@@ -415,6 +430,15 @@ class OpenSession {
|
|
|
415
430
|
name,
|
|
416
431
|
});
|
|
417
432
|
}
|
|
433
|
+
broadcastContextUsage() {
|
|
434
|
+
const { used, max } = this.contextManager.getContextUsage();
|
|
435
|
+
this.sender.broadcast({
|
|
436
|
+
type: "context_usage",
|
|
437
|
+
session_id: this.sessionUUID,
|
|
438
|
+
used_tokens: used,
|
|
439
|
+
max_tokens: max,
|
|
440
|
+
});
|
|
441
|
+
}
|
|
418
442
|
// ISessionFileManagerEventHandler.onFileChanged
|
|
419
443
|
onFileChanged(entry, new_file) {
|
|
420
444
|
this.sender.broadcast({
|
|
@@ -493,6 +517,9 @@ class OpenSession {
|
|
|
493
517
|
case "msg":
|
|
494
518
|
broadcastMsg = await this.handleUserMessage(msg, queuedMessage.from);
|
|
495
519
|
break;
|
|
520
|
+
case "stop":
|
|
521
|
+
this.agent.stop();
|
|
522
|
+
break;
|
|
496
523
|
case "add_mcp_server":
|
|
497
524
|
broadcastMsg = await this.handleAddMcpServer(msg.server_name, msg.enable_all);
|
|
498
525
|
break;
|
|
@@ -547,6 +574,9 @@ class OpenSession {
|
|
|
547
574
|
case "get_mcp_resource":
|
|
548
575
|
void this.handleGetMcpResource(msg, queuedMessage.from);
|
|
549
576
|
break;
|
|
577
|
+
case "race_mode_result":
|
|
578
|
+
this.raceModeAwaiter.onMessage(msg);
|
|
579
|
+
break;
|
|
550
580
|
default: {
|
|
551
581
|
const exhaustive = msg; // Error => non-exhaustive switch-case.
|
|
552
582
|
return exhaustive;
|
|
@@ -560,6 +590,10 @@ class OpenSession {
|
|
|
560
590
|
}
|
|
561
591
|
else {
|
|
562
592
|
this.sender.broadcast(broadcastMsg);
|
|
593
|
+
// Broadcast context usage after user message
|
|
594
|
+
if (broadcastMsg.type === "user_msg") {
|
|
595
|
+
this.broadcastContextUsage();
|
|
596
|
+
}
|
|
563
597
|
}
|
|
564
598
|
}
|
|
565
599
|
}
|
|
@@ -618,12 +652,11 @@ class OpenSession {
|
|
|
618
652
|
// Just send the user LLM user messages direct to the ContextManager, so
|
|
619
653
|
// they are available to the LLM once it is restarted.
|
|
620
654
|
const { contextTx } = await this.contextManager.startAgentResponse(msgs);
|
|
621
|
-
|
|
655
|
+
const result = this.contextManager.endAgentResponse(contextTx);
|
|
656
|
+
this.broadcastContextUsage();
|
|
657
|
+
return result;
|
|
622
658
|
}
|
|
623
659
|
async processUserMessagesActive(msgs) {
|
|
624
|
-
// TODO: create the contextTx and store all new messages on this. Event
|
|
625
|
-
// handler should accept the contextTx and forward messages to it, as well
|
|
626
|
-
// as sending the updates.
|
|
627
660
|
// All accumulated messages (DB, Protocol and LLM) should be on the
|
|
628
661
|
// specialized contextTx.
|
|
629
662
|
const { contextTx, agentFirstChunk } = await this.contextManager.startAgentResponse(msgs);
|
|
@@ -641,13 +674,77 @@ class OpenSession {
|
|
|
641
674
|
// DB. Should we keep them?
|
|
642
675
|
throw new Error(errMsg);
|
|
643
676
|
}
|
|
644
|
-
|
|
677
|
+
const result = this.contextManager.endAgentResponse(contextTx);
|
|
678
|
+
this.broadcastContextUsage();
|
|
679
|
+
return result;
|
|
680
|
+
}
|
|
681
|
+
/**
|
|
682
|
+
* `processUserMessage` logic for race-mode.
|
|
683
|
+
*/
|
|
684
|
+
async processUserMessagesRaceMode(msgs) {
|
|
685
|
+
// Create a second agent, same skillManager
|
|
686
|
+
const modelB = msgs[0].race_mode;
|
|
687
|
+
(0, assert_1.strict)(typeof modelB === "string");
|
|
688
|
+
const agentB = await (async () => {
|
|
689
|
+
try {
|
|
690
|
+
const llmB = await createLLM(modelB, this.platform);
|
|
691
|
+
return new agent_1.AgentEx(this.skillManager, llmB);
|
|
692
|
+
}
|
|
693
|
+
catch (e) {
|
|
694
|
+
logger.warn("[OpenSession.processUserMessages] error creating race agent: " +
|
|
695
|
+
String(e));
|
|
696
|
+
throw new Error(`error creating race: ${String(e)}`);
|
|
697
|
+
}
|
|
698
|
+
})();
|
|
699
|
+
const run = async (alt, msgs) => {
|
|
700
|
+
const { contextTx: contextTx, agentFirstChunk: agentFirstChunk } = await this.contextManager.startAgentResponse(msgs.slice());
|
|
701
|
+
this.sender.broadcast(agentFirstChunk);
|
|
702
|
+
const eventHandler = new ChatSessionAgentEventHandler(this.sessionUUID, this.sender, this.approvalManager, contextTx, alt);
|
|
703
|
+
try {
|
|
704
|
+
const agent = alt === "B" ? agentB : this.agent;
|
|
705
|
+
await agent.userMessagesRaw(contextTx, eventHandler);
|
|
706
|
+
}
|
|
707
|
+
catch (e) {
|
|
708
|
+
logger.warn(`[OpenSession.processUserMessages] agent ${alt} error: ${String(e)}`);
|
|
709
|
+
const errMsg = `error from LLM: ${String(e)}`;
|
|
710
|
+
contextTx.revertAgentResponse(errMsg);
|
|
711
|
+
throw new Error(errMsg);
|
|
712
|
+
}
|
|
713
|
+
return contextTx;
|
|
714
|
+
};
|
|
715
|
+
const [txA, txB] = await Promise.all([
|
|
716
|
+
run("A", msgs.slice()),
|
|
717
|
+
run("B", msgs),
|
|
718
|
+
]);
|
|
719
|
+
// Ask which fork to commit
|
|
720
|
+
const answer = await (async () => {
|
|
721
|
+
const message_id = (0, uuid_1.v4)();
|
|
722
|
+
const answerP = this.raceModeAwaiter.waitForResponse(message_id);
|
|
723
|
+
const getResultMsg = {
|
|
724
|
+
type: "race_mode_get_result",
|
|
725
|
+
message_id,
|
|
726
|
+
alts: ["A", "B"],
|
|
727
|
+
session_id: this.sessionUUID,
|
|
728
|
+
};
|
|
729
|
+
this.sender.broadcast(getResultMsg);
|
|
730
|
+
return answerP;
|
|
731
|
+
})();
|
|
732
|
+
if (answer.result === "A") {
|
|
733
|
+
return this.contextManager.endAgentResponse(txA);
|
|
734
|
+
}
|
|
735
|
+
else {
|
|
736
|
+
return this.contextManager.endAgentResponse(txB);
|
|
737
|
+
}
|
|
738
|
+
// UI is responsible for switching model if the user wants to.
|
|
645
739
|
}
|
|
646
740
|
async processUserMessages(msgs) {
|
|
741
|
+
logger.debug(`[processUserMessages] msgs: ${JSON.stringify(msgs)}`);
|
|
647
742
|
try {
|
|
648
743
|
const newSessionMessages = this.agentPaused
|
|
649
744
|
? await this.processUserMessagePaused(msgs)
|
|
650
|
-
: await
|
|
745
|
+
: await (msgs[0].race_mode
|
|
746
|
+
? this.processUserMessagesRaceMode(msgs)
|
|
747
|
+
: this.processUserMessagesActive(msgs));
|
|
651
748
|
logger.debug("[processUserMessages] newSessionMessages: " +
|
|
652
749
|
JSON.stringify(newSessionMessages));
|
|
653
750
|
// Append to in-memory conversation and write to the DB
|
|
@@ -655,6 +752,8 @@ class OpenSession {
|
|
|
655
752
|
await dbsm.append(this.sessionUUID, newSessionMessages);
|
|
656
753
|
}
|
|
657
754
|
catch (e) {
|
|
755
|
+
logger.error(`[processUserMessages] ERROR session=${this.sessionUUID}: ` +
|
|
756
|
+
String(e));
|
|
658
757
|
if (!this.handleError(e)) {
|
|
659
758
|
throw e;
|
|
660
759
|
}
|
|
@@ -664,9 +763,16 @@ class OpenSession {
|
|
|
664
763
|
// Return a ServerUserMessage for broadcast. The actual message is places
|
|
665
764
|
// on a queue to be dealt with in another loop. This allows Agent
|
|
666
765
|
// processing of user messages to depend on other messages.
|
|
667
|
-
(0, assert_1.strict)(msg);
|
|
668
|
-
(0, assert_1.strict)(from);
|
|
669
|
-
|
|
766
|
+
(0, assert_1.strict)(msg, "undefined user message");
|
|
767
|
+
(0, assert_1.strict)(from, "undefined user message sender");
|
|
768
|
+
logger.info(`[handleUserMessage] msg.attachedFiles: ${JSON.stringify(msg.attachedFiles
|
|
769
|
+
? msg.attachedFiles.map((f) => ({
|
|
770
|
+
name: f.name,
|
|
771
|
+
data_url_length: f.data_url.length,
|
|
772
|
+
}))
|
|
773
|
+
: "none")}`);
|
|
774
|
+
// Assign the user message_idx first so we can check if this is
|
|
775
|
+
// the first message
|
|
670
776
|
const user = this.sessionParticipants.get(from);
|
|
671
777
|
if (!user) {
|
|
672
778
|
throw new Error(`unrecognized user ${from}`);
|
|
@@ -675,6 +781,62 @@ class OpenSession {
|
|
|
675
781
|
if (!userMessage) {
|
|
676
782
|
return;
|
|
677
783
|
}
|
|
784
|
+
// Handle attached files by adding them to session files
|
|
785
|
+
if (msg.attachedFiles && msg.attachedFiles.length > 0) {
|
|
786
|
+
const fileCount = String(msg.attachedFiles.length);
|
|
787
|
+
logger.info(`[handleUserMessage] Processing ${fileCount} attached files`);
|
|
788
|
+
// If this is the first message, set the session title before
|
|
789
|
+
// creating the session
|
|
790
|
+
if (userMessage.message_idx === conversation_1.MESSAGE_INDEX_START_VALUE &&
|
|
791
|
+
!this.isPersisted) {
|
|
792
|
+
this.sessionTitle = userMessage.message?.slice(0, 128) || "New Chat";
|
|
793
|
+
}
|
|
794
|
+
// If the session hasn't been persisted, it must be written to
|
|
795
|
+
// the DB first
|
|
796
|
+
if (!this.isPersisted) {
|
|
797
|
+
await this.createSessionInDB();
|
|
798
|
+
}
|
|
799
|
+
// Add each attached file to session files
|
|
800
|
+
for (const file of msg.attachedFiles) {
|
|
801
|
+
logger.info(`[handleUserMessage] Adding file ${file.name} to session files`);
|
|
802
|
+
// Extract content and generate summary for PDFs
|
|
803
|
+
let parsed_content;
|
|
804
|
+
let summary;
|
|
805
|
+
const mimeType = (0, fileManager_1.getMimeTypeFromDataUrl)(file.data_url);
|
|
806
|
+
if (mimeType === "application/pdf") {
|
|
807
|
+
try {
|
|
808
|
+
// Extract base64 data and convert to ArrayBuffer
|
|
809
|
+
const base64Data = file.data_url.split(",")[1];
|
|
810
|
+
const binaryString = atob(base64Data);
|
|
811
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
812
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
813
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
814
|
+
}
|
|
815
|
+
const arrayBuffer = bytes.buffer;
|
|
816
|
+
// Extract text from PDF
|
|
817
|
+
const extractedText = await (0, pdfToText_1.pdfToText)(arrayBuffer);
|
|
818
|
+
parsed_content = {
|
|
819
|
+
version: 1,
|
|
820
|
+
text: extractedText,
|
|
821
|
+
};
|
|
822
|
+
// Generate summary from extracted text
|
|
823
|
+
if (extractedText.trim().length > 0) {
|
|
824
|
+
summary = await (0, documentSummarizer_1.summarizeDocument)(extractedText);
|
|
825
|
+
}
|
|
826
|
+
logger.info(`[handleUserMessage] Extracted ${String(extractedText.length)}` +
|
|
827
|
+
` chars from PDF ${file.name}`);
|
|
828
|
+
}
|
|
829
|
+
catch (err) {
|
|
830
|
+
logger.warn(`[handleUserMessage] Failed to extract PDF content: ` +
|
|
831
|
+
String(err));
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
await this.sessionFileManager.putFileContent(file.name, summary, file.data_url, parsed_content);
|
|
835
|
+
}
|
|
836
|
+
// Remove attachedFiles from the message so they don't get
|
|
837
|
+
// included in the LLM context
|
|
838
|
+
msg = { ...msg, attachedFiles: undefined };
|
|
839
|
+
}
|
|
678
840
|
// Special case for the first message of the session
|
|
679
841
|
if (userMessage.message_idx === conversation_1.MESSAGE_INDEX_START_VALUE) {
|
|
680
842
|
// No need to wait for this to complete before broadcasting.
|
|
@@ -714,8 +876,8 @@ class OpenSession {
|
|
|
714
876
|
this.isPersisted = true;
|
|
715
877
|
}
|
|
716
878
|
async onFirstMessage(userMsg) {
|
|
717
|
-
//
|
|
718
|
-
this.sessionTitle = userMsg.message
|
|
879
|
+
// Generate title using LLM with automatic fallback
|
|
880
|
+
this.sessionTitle = await this.titleGenerator.generateTitle(userMsg.message || "");
|
|
719
881
|
// The session may already have been saved (e.g. if the workspace is
|
|
720
882
|
// updated before any messages are sent).
|
|
721
883
|
if (!this.isPersisted) {
|
|
@@ -1080,27 +1242,28 @@ async function loadSessionData(db, sessionId) {
|
|
|
1080
1242
|
sessionParticipants: (0, database_1.createSessionParticipantMap)(sessionParticipants),
|
|
1081
1243
|
};
|
|
1082
1244
|
}
|
|
1083
|
-
async function
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
let llm = await (0, agentUtils_1.createSpecializedLLM)(model, platform);
|
|
1088
|
-
if (!llm) {
|
|
1089
|
-
llm = new openAIRouterLLM_1.OpenAIRouterLLM(model);
|
|
1090
|
-
}
|
|
1091
|
-
(0, assert_1.strict)(llm);
|
|
1092
|
-
return llm;
|
|
1093
|
-
};
|
|
1094
|
-
const contextManager = new chatContextManager_1.ChatContextManager(systemPrompt, sessionMessages, sessionUUID, ownerData.uuid, sessionCheckpoint, checkpointWriter, fileManager, await createLLM());
|
|
1095
|
-
if (workspace) {
|
|
1096
|
-
contextManager.setWorkspace((0, agent_1.createUserMessage)(workspace.message, workspace.imageB64));
|
|
1245
|
+
async function createLLM(model, platform) {
|
|
1246
|
+
let llm = await (0, agentUtils_1.createSpecializedLLM)(model, platform);
|
|
1247
|
+
if (!llm) {
|
|
1248
|
+
llm = new openAIRouterLLM_1.OpenAIRouterLLM(model);
|
|
1097
1249
|
}
|
|
1250
|
+
(0, assert_1.strict)(llm);
|
|
1251
|
+
return llm;
|
|
1252
|
+
}
|
|
1253
|
+
async function createContextAndAgent(sessionUUID, systemPrompt, model, sessionMessages, workspace, sessionCheckpoint, ownerData, ownerApiKey, xmcpUrl, fileManager, platform, checkpointWriter, messageSender) {
|
|
1254
|
+
// Create SkillManager
|
|
1098
1255
|
const xmcpConfig = sdk_1.Configuration.new(ownerApiKey, xmcpUrl, false);
|
|
1099
1256
|
const skillManager = await sudoMcpServerManager_1.SkillManager.initialize((url, authResultP, displayName) => {
|
|
1100
1257
|
platform.openUrl(url, authResultP, displayName);
|
|
1101
1258
|
}, xmcpConfig.backend_url, xmcpConfig.api_key, undefined /* authorizedUrl */);
|
|
1102
|
-
|
|
1259
|
+
// Fn to create the llm. One invocation for the compression context, one
|
|
1260
|
+
// for the Agent.
|
|
1261
|
+
const llm = await createLLM(model, platform);
|
|
1103
1262
|
const agent = new agent_1.AgentEx(skillManager, llm);
|
|
1104
|
-
await (0, tools_1.addDefaultChatTools)(agent, ownerData.timezone, platform, fileManager);
|
|
1263
|
+
await (0, tools_1.addDefaultChatTools)(agent, ownerData.timezone, platform, fileManager, messageSender);
|
|
1264
|
+
const contextManager = new chatContextManager_1.ChatContextManager(systemPrompt, sessionMessages, sessionUUID, ownerData.uuid, sessionCheckpoint, checkpointWriter, fileManager, await createLLM(model, platform));
|
|
1265
|
+
if (workspace) {
|
|
1266
|
+
contextManager.setWorkspace((0, agent_1.createUserMessage)(workspace.message, workspace.imageB64));
|
|
1267
|
+
}
|
|
1105
1268
|
return { agent, skillManager, contextManager };
|
|
1106
1269
|
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LLMPromptRefiner = void 0;
|
|
4
|
+
exports.getPromptRefiner = getPromptRefiner;
|
|
5
|
+
const openAIRouterLLM_1 = require("./openAIRouterLLM");
|
|
6
|
+
const sdk_1 = require("@xalia/xmcp/sdk");
|
|
7
|
+
const logger = (0, sdk_1.getLogger)();
|
|
8
|
+
const REFINER_MODEL = "google/gemini-2.5-flash";
|
|
9
|
+
const REFINER_MAX_TOKENS = 2000;
|
|
10
|
+
const REFINER_TEMPERATURE = 0.3;
|
|
11
|
+
const REFINER_TIMEOUT_MS = 30000;
|
|
12
|
+
// prettier-ignore
|
|
13
|
+
const REFINEMENT_SYSTEM_PROMPT = `You are an expert at writing system prompts for AI assistants. Your task is \
|
|
14
|
+
to refine and improve the given system prompt to make it more effective, \
|
|
15
|
+
clear, and well-structured for an LLM to follow.
|
|
16
|
+
|
|
17
|
+
Guidelines for refinement:
|
|
18
|
+
1. Make instructions clear, specific, and actionable
|
|
19
|
+
2. Use structured formatting (sections, bullet points) when appropriate
|
|
20
|
+
3. Remove ambiguity and redundancy
|
|
21
|
+
4. Add relevant context if missing
|
|
22
|
+
5. Ensure the tone and style are consistent
|
|
23
|
+
6. Preserve the original intent and personality
|
|
24
|
+
7. Keep the prompt concise but comprehensive
|
|
25
|
+
|
|
26
|
+
Return ONLY the refined system prompt, without any explanations or \
|
|
27
|
+
meta-commentary.`;
|
|
28
|
+
class LLMPromptRefiner {
|
|
29
|
+
constructor(model = REFINER_MODEL) {
|
|
30
|
+
this.model = model;
|
|
31
|
+
}
|
|
32
|
+
async refinePrompt(prompt) {
|
|
33
|
+
if (!prompt || prompt.trim().length === 0) {
|
|
34
|
+
return prompt;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const refined = await this.refineWithTimeout(prompt);
|
|
38
|
+
return refined.trim();
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
42
|
+
logger.warn(`[PromptRefiner] LLM refinement failed: ${errorMsg}, returning original`);
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async refineWithTimeout(prompt) {
|
|
47
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
48
|
+
setTimeout(() => {
|
|
49
|
+
reject(new Error("Prompt refinement timeout"));
|
|
50
|
+
}, REFINER_TIMEOUT_MS);
|
|
51
|
+
});
|
|
52
|
+
const refinePromise = this.callLLM(prompt);
|
|
53
|
+
return Promise.race([refinePromise, timeoutPromise]);
|
|
54
|
+
}
|
|
55
|
+
async callLLM(prompt) {
|
|
56
|
+
const client = (0, openAIRouterLLM_1.getOpenAIClient)(this.model);
|
|
57
|
+
const response = await client.chat.completions.create({
|
|
58
|
+
model: this.model,
|
|
59
|
+
messages: [
|
|
60
|
+
{
|
|
61
|
+
role: "system",
|
|
62
|
+
content: REFINEMENT_SYSTEM_PROMPT,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
role: "user",
|
|
66
|
+
content: `Please refine this system prompt:\n\n${prompt}`,
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
max_tokens: REFINER_MAX_TOKENS,
|
|
70
|
+
temperature: REFINER_TEMPERATURE,
|
|
71
|
+
});
|
|
72
|
+
const refined = response.choices[0]?.message?.content?.trim();
|
|
73
|
+
if (!refined) {
|
|
74
|
+
throw new Error("Empty response from LLM");
|
|
75
|
+
}
|
|
76
|
+
return refined;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.LLMPromptRefiner = LLMPromptRefiner;
|
|
80
|
+
let promptRefinerInstance;
|
|
81
|
+
function getPromptRefiner(model) {
|
|
82
|
+
if (!promptRefinerInstance) {
|
|
83
|
+
promptRefinerInstance = new LLMPromptRefiner(model);
|
|
84
|
+
}
|
|
85
|
+
return promptRefinerInstance;
|
|
86
|
+
}
|
|
@@ -47,8 +47,12 @@ const database_1 = require("../data/database");
|
|
|
47
47
|
const errors_1 = require("../protocol/errors");
|
|
48
48
|
const sessionRegistry_1 = require("./sessionRegistry");
|
|
49
49
|
const DEVELOPMENT = process.env.DEVELOPMENT === "1";
|
|
50
|
+
const TEST = process.env.TEST === "1";
|
|
50
51
|
dotenv.config();
|
|
51
|
-
if (
|
|
52
|
+
if (TEST) {
|
|
53
|
+
dotenv.config({ path: ".env.test" });
|
|
54
|
+
}
|
|
55
|
+
else if (DEVELOPMENT) {
|
|
52
56
|
dotenv.config({ path: ".env.development" });
|
|
53
57
|
}
|
|
54
58
|
const logger = (0, sdk_1.getLogger)();
|