@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
package/src/tool/chatMain.ts
DELETED
|
@@ -1,594 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/only-throw-error */
|
|
2
|
-
|
|
3
|
-
import chalk from "chalk";
|
|
4
|
-
import { command, optional, option, string, number, subcommands } from "cmd-ts";
|
|
5
|
-
import { stdout } from "process";
|
|
6
|
-
import * as fs from "fs";
|
|
7
|
-
import { strict as assert } from "assert";
|
|
8
|
-
|
|
9
|
-
import { configuration } from "@xalia/xmcp/tool";
|
|
10
|
-
import { getLogger } from "@xalia/xmcp/sdk";
|
|
11
|
-
|
|
12
|
-
import {
|
|
13
|
-
ChatClient,
|
|
14
|
-
SessionClient,
|
|
15
|
-
IChatClientEventHandler,
|
|
16
|
-
} from "../chat/client";
|
|
17
|
-
import {
|
|
18
|
-
runServer,
|
|
19
|
-
resolveSessionIdFromIdentifier,
|
|
20
|
-
} from "../chat/server/server";
|
|
21
|
-
import {
|
|
22
|
-
ServerToClient,
|
|
23
|
-
decodeAssistantMessageParam,
|
|
24
|
-
} from "../chat/protocol/messages";
|
|
25
|
-
import { Database, createSessionParticipantMap } from "../chat/data/database";
|
|
26
|
-
|
|
27
|
-
import { IPrompt, Prompt, ScriptPrompt } from "./prompt";
|
|
28
|
-
import * as options from "./options";
|
|
29
|
-
import { CommandPrompt } from "./commandPrompt";
|
|
30
|
-
import { NODE_PLATFORM } from "./nodePlatform";
|
|
31
|
-
import { loadImageAsDataUrl, loadSessionFileAsDataUrl } from "./files";
|
|
32
|
-
import { isFileMetaData } from "../chat/data/dbSessionFileModels";
|
|
33
|
-
|
|
34
|
-
const logger = getLogger();
|
|
35
|
-
|
|
36
|
-
const listSessions = command({
|
|
37
|
-
name: "delete-session",
|
|
38
|
-
args: {
|
|
39
|
-
supabaseUrl: options.supabaseUrl,
|
|
40
|
-
supabaseKey: options.supabaseKey,
|
|
41
|
-
},
|
|
42
|
-
handler: async ({ supabaseUrl, supabaseKey }): Promise<void> => {
|
|
43
|
-
const db = new Database(supabaseUrl, supabaseKey);
|
|
44
|
-
console.log(JSON.stringify(await db.sessionsGet()));
|
|
45
|
-
},
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
const clearSessions = command({
|
|
49
|
-
name: "clear-sessions",
|
|
50
|
-
args: {
|
|
51
|
-
supabaseUrl: options.supabaseUrl,
|
|
52
|
-
supabaseKey: options.supabaseKey,
|
|
53
|
-
},
|
|
54
|
-
handler: async ({ supabaseUrl, supabaseKey }): Promise<void> => {
|
|
55
|
-
const db = new Database(supabaseUrl, supabaseKey);
|
|
56
|
-
await db.clearSessions();
|
|
57
|
-
},
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
const deleteSession = command({
|
|
61
|
-
name: "delete-session",
|
|
62
|
-
args: {
|
|
63
|
-
supabaseUrl: options.supabaseUrl,
|
|
64
|
-
supabaseKey: options.supabaseKey,
|
|
65
|
-
session: option({
|
|
66
|
-
type: string,
|
|
67
|
-
long: "session",
|
|
68
|
-
description:
|
|
69
|
-
"Session identifier (id, name, user/name or name of new session)",
|
|
70
|
-
env: "SESSION",
|
|
71
|
-
}),
|
|
72
|
-
},
|
|
73
|
-
handler: async ({ supabaseUrl, supabaseKey, session }): Promise<void> => {
|
|
74
|
-
const db = new Database(supabaseUrl, supabaseKey);
|
|
75
|
-
const sessionId = await resolveSessionIdFromIdentifier(db, session);
|
|
76
|
-
if (sessionId) {
|
|
77
|
-
await db.sessionDeleteById(sessionId);
|
|
78
|
-
} else {
|
|
79
|
-
throw `No such session ${session}`;
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
const listParticipants = command({
|
|
85
|
-
name: "list-participants",
|
|
86
|
-
args: {
|
|
87
|
-
supabaseUrl: options.supabaseUrl,
|
|
88
|
-
supabaseKey: options.supabaseKey,
|
|
89
|
-
session: option({
|
|
90
|
-
type: string,
|
|
91
|
-
long: "session",
|
|
92
|
-
description:
|
|
93
|
-
"Session identifier (id, name, user/name or name of new session)",
|
|
94
|
-
env: "SESSION",
|
|
95
|
-
}),
|
|
96
|
-
},
|
|
97
|
-
handler: async ({ supabaseUrl, supabaseKey, session }): Promise<void> => {
|
|
98
|
-
const db = new Database(supabaseUrl, supabaseKey);
|
|
99
|
-
const sessionId = await resolveSessionIdFromIdentifier(db, session);
|
|
100
|
-
if (sessionId) {
|
|
101
|
-
const participants = await db.sessionGetParticipants(sessionId);
|
|
102
|
-
|
|
103
|
-
console.log(`participants: ${JSON.stringify(participants)}`);
|
|
104
|
-
const users = createSessionParticipantMap(participants);
|
|
105
|
-
console.log(JSON.stringify(users));
|
|
106
|
-
} else {
|
|
107
|
-
throw `No such session ${session}`;
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
const server = command({
|
|
113
|
-
name: "server",
|
|
114
|
-
args: {
|
|
115
|
-
port: option({
|
|
116
|
-
type: number,
|
|
117
|
-
long: "port",
|
|
118
|
-
short: "p",
|
|
119
|
-
env: "CHAT_SERVER_PORT",
|
|
120
|
-
defaultValue: () => 5003,
|
|
121
|
-
}),
|
|
122
|
-
supabaseUrl: options.supabaseUrl,
|
|
123
|
-
supabaseKey: options.supabaseKey,
|
|
124
|
-
xmcpUrl: options.xmcpUrl,
|
|
125
|
-
pidFile: options.pidFile,
|
|
126
|
-
},
|
|
127
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
128
|
-
handler: async ({
|
|
129
|
-
port,
|
|
130
|
-
supabaseUrl,
|
|
131
|
-
supabaseKey,
|
|
132
|
-
xmcpUrl,
|
|
133
|
-
pidFile,
|
|
134
|
-
}): Promise<void> => {
|
|
135
|
-
if (pidFile) {
|
|
136
|
-
fs.writeFileSync(pidFile, process.pid.toString());
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
void runServer(port, supabaseUrl, supabaseKey, xmcpUrl);
|
|
140
|
-
},
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
const client = command({
|
|
144
|
-
name: "client",
|
|
145
|
-
args: {
|
|
146
|
-
url: option({
|
|
147
|
-
type: string,
|
|
148
|
-
long: "url",
|
|
149
|
-
short: "h",
|
|
150
|
-
env: "CHAT_URL",
|
|
151
|
-
description: "Chat server url",
|
|
152
|
-
defaultValue: () => "ws://localhost:5003",
|
|
153
|
-
}),
|
|
154
|
-
apiKey: options.apiKey,
|
|
155
|
-
sessionId: option({
|
|
156
|
-
type: optional(string),
|
|
157
|
-
long: "session-id",
|
|
158
|
-
description: "Join existing session with the given UUID",
|
|
159
|
-
env: "SESSION_UUID",
|
|
160
|
-
}),
|
|
161
|
-
teamId: option({
|
|
162
|
-
type: optional(string),
|
|
163
|
-
long: "team-id",
|
|
164
|
-
description:
|
|
165
|
-
"Team uuid, if not provided, a user session will be created.",
|
|
166
|
-
env: "TEAM_ID",
|
|
167
|
-
}),
|
|
168
|
-
agentProfileId: option({
|
|
169
|
-
type: optional(string),
|
|
170
|
-
long: "agent-profile-id",
|
|
171
|
-
description: "Create new session with agent profile (uuid)",
|
|
172
|
-
env: "AGENT_PROFILE_ID",
|
|
173
|
-
}),
|
|
174
|
-
sessionTitle: option({
|
|
175
|
-
type: optional(string),
|
|
176
|
-
long: "session-title",
|
|
177
|
-
description: "Title for new session",
|
|
178
|
-
env: "SESSION_TITLE",
|
|
179
|
-
}),
|
|
180
|
-
script: option({
|
|
181
|
-
type: optional(string),
|
|
182
|
-
long: "script",
|
|
183
|
-
description: "Script (file) to execute and then exit.",
|
|
184
|
-
}),
|
|
185
|
-
},
|
|
186
|
-
handler: async ({
|
|
187
|
-
url,
|
|
188
|
-
apiKey,
|
|
189
|
-
sessionId,
|
|
190
|
-
agentProfileId,
|
|
191
|
-
sessionTitle,
|
|
192
|
-
teamId,
|
|
193
|
-
script,
|
|
194
|
-
}): Promise<void> => {
|
|
195
|
-
if (!apiKey) {
|
|
196
|
-
// TODO: configFIle param list in ../main.ts
|
|
197
|
-
const sudomcpConfig = configuration.loadEnsureConfig();
|
|
198
|
-
apiKey = sudomcpConfig.api_key;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
const repl: IPrompt = (() => {
|
|
202
|
-
if (script) {
|
|
203
|
-
const scriptLines = fs.readFileSync(script, "utf8").split("\n");
|
|
204
|
-
return new ScriptPrompt(scriptLines);
|
|
205
|
-
}
|
|
206
|
-
return new Prompt();
|
|
207
|
-
})();
|
|
208
|
-
|
|
209
|
-
const helpText = `
|
|
210
|
-
${chalk.yellow("/aa <server> <tool> [1]")} Auto approve
|
|
211
|
-
${chalk.yellow("/error <msg>")} Force server error
|
|
212
|
-
${chalk.yellow("/ap <team> <user>")} Add-Participant
|
|
213
|
-
${chalk.yellow("/rp <team> <user>")} Remove-Participant
|
|
214
|
-
${chalk.yellow("/lp")} List-Participants
|
|
215
|
-
${chalk.yellow("/si [<file>]")} Write Session id to file
|
|
216
|
-
${chalk.yellow("/ct <name>")} Create Team
|
|
217
|
-
${chalk.yellow("/ci [<file>]")} Write team id to file
|
|
218
|
-
${chalk.yellow("/sw [file:a.png|data:....]")} Set workspace (no args = clear)
|
|
219
|
-
${chalk.yellow("/list-files")} List file-manager files
|
|
220
|
-
${chalk.yellow("/put-file <name> <file:...|data:...>")} Add file
|
|
221
|
-
${chalk.yellow("/delete-file <name>")} Delete file
|
|
222
|
-
${chalk.yellow("/get-file <name>")} Get file contents
|
|
223
|
-
${chalk.yellow("/share-session <file>")} Share and write access token
|
|
224
|
-
${chalk.yellow("/pause-agent <0|1>")} Pause (or unpause) the agent
|
|
225
|
-
${chalk.yellow("/add-custom-mcp-server <server-name> <url>")} Add MCP server
|
|
226
|
-
${chalk.yellow("/remove-custom-mcp-server <server-name>")} Remove MCP server
|
|
227
|
-
${chalk.yellow("/list-custom-mcp-servers")} list custom mcp servers
|
|
228
|
-
${chalk.yellow("/get-resource <server-name> <uri>")} get MCP server resource
|
|
229
|
-
`;
|
|
230
|
-
|
|
231
|
-
const cmdPrompt = new CommandPrompt(repl, helpText);
|
|
232
|
-
const eventHandler = getCLIEventHandler(cmdPrompt);
|
|
233
|
-
|
|
234
|
-
const [client, sessionClient] = await (async () => {
|
|
235
|
-
const newClient = await ChatClient.init(url, apiKey, eventHandler);
|
|
236
|
-
if (sessionId) {
|
|
237
|
-
if (agentProfileId || sessionTitle) {
|
|
238
|
-
throw "t agent-profile-id/session-title set joining existing session";
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
console.log(`joining existing session: ${sessionId} ...`);
|
|
242
|
-
const newSessionClient = await newClient.connectToSession(sessionId);
|
|
243
|
-
return [newClient, newSessionClient];
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
const newSessionClient = await newClient.createNewSession(
|
|
247
|
-
sessionTitle || "New Chat",
|
|
248
|
-
agentProfileId,
|
|
249
|
-
teamId
|
|
250
|
-
);
|
|
251
|
-
return [newClient, newSessionClient];
|
|
252
|
-
})();
|
|
253
|
-
logger.debug("client created");
|
|
254
|
-
|
|
255
|
-
const onUnknownCommand = async (cmds: string[]): Promise<void> => {
|
|
256
|
-
switch (cmds[0]) {
|
|
257
|
-
case "aa":
|
|
258
|
-
sessionClient.setAutoApproval(cmds[1], cmds[2], !!cmds[3]);
|
|
259
|
-
break;
|
|
260
|
-
case "error":
|
|
261
|
-
sessionClient.sendMessage({ type: "fatal_error", message: cmds[1] });
|
|
262
|
-
break;
|
|
263
|
-
case "ap": // Add Participant
|
|
264
|
-
case "au":
|
|
265
|
-
client.addTeamMember(cmds[1], cmds[2]);
|
|
266
|
-
break;
|
|
267
|
-
case "rp": // Remove Participant
|
|
268
|
-
case "ru":
|
|
269
|
-
client.removeTeamMember(cmds[1], cmds[2]);
|
|
270
|
-
break;
|
|
271
|
-
case "lp": // List Participants
|
|
272
|
-
case "lu":
|
|
273
|
-
console.log(JSON.stringify(sessionClient.getParticipants()));
|
|
274
|
-
break;
|
|
275
|
-
case "si": // Write Session id to file
|
|
276
|
-
fs.writeFileSync(cmds[1], sessionClient.getSessionUUID());
|
|
277
|
-
break;
|
|
278
|
-
case "ct": // Create Team
|
|
279
|
-
client.createNewTeam(cmds[1], []);
|
|
280
|
-
break;
|
|
281
|
-
case "ci": // Write team id to file
|
|
282
|
-
fs.writeFileSync(cmds[1], client.getCurrentTeamId() ?? "");
|
|
283
|
-
break;
|
|
284
|
-
case "sw": // Set workspace
|
|
285
|
-
setWorkspaceFromPrompt(sessionClient, cmds);
|
|
286
|
-
break;
|
|
287
|
-
case "list-files": // List files
|
|
288
|
-
listFiles(sessionClient, cmds[1]);
|
|
289
|
-
break;
|
|
290
|
-
case "put-file": // Add file
|
|
291
|
-
putFile(sessionClient, cmds.slice(1));
|
|
292
|
-
break;
|
|
293
|
-
case "delete-file": // Delete file
|
|
294
|
-
deleteFile(sessionClient, cmds[1]);
|
|
295
|
-
break;
|
|
296
|
-
case "get-file": // Get file contents
|
|
297
|
-
await getFileContents(sessionClient, cmds[1]);
|
|
298
|
-
break;
|
|
299
|
-
case "share-session":
|
|
300
|
-
await shareSession(sessionClient, cmds[1]);
|
|
301
|
-
break;
|
|
302
|
-
case "pause-agent":
|
|
303
|
-
pauseAgent(sessionClient, cmds[1]);
|
|
304
|
-
break;
|
|
305
|
-
case "add-custom-mcp-server":
|
|
306
|
-
addCustomMcpServer(client, cmds[1], cmds[2]);
|
|
307
|
-
break;
|
|
308
|
-
case "remove-custom-mcp-server":
|
|
309
|
-
removeCustomMcpServer(client, cmds[1]);
|
|
310
|
-
break;
|
|
311
|
-
case "list-custom-mcp-servers":
|
|
312
|
-
listCustomMcpServers(client);
|
|
313
|
-
break;
|
|
314
|
-
case "get-resource":
|
|
315
|
-
await getResource(sessionClient, cmds[1], cmds[2]);
|
|
316
|
-
break;
|
|
317
|
-
default:
|
|
318
|
-
console.log(`error: Unknown command ${cmds[0]}`);
|
|
319
|
-
}
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
323
|
-
while (true) {
|
|
324
|
-
const [msgText, imageFile] = await cmdPrompt.getNextPrompt(
|
|
325
|
-
sessionClient,
|
|
326
|
-
sessionClient.getSudoMcpServerManager(),
|
|
327
|
-
onUnknownCommand
|
|
328
|
-
);
|
|
329
|
-
assert(imageFile === undefined);
|
|
330
|
-
|
|
331
|
-
if (msgText === undefined) {
|
|
332
|
-
logger.debug("exiting...");
|
|
333
|
-
logger.info("exiting...");
|
|
334
|
-
client.shutdown();
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// TODO: other prompts
|
|
339
|
-
|
|
340
|
-
if (msgText.length > 0) {
|
|
341
|
-
logger.debug(`sending message: ${msgText}`);
|
|
342
|
-
sessionClient.userMessage(msgText);
|
|
343
|
-
} else {
|
|
344
|
-
logger.debug("(ignoring empty message)");
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
},
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
function listFiles(
|
|
351
|
-
sessionClient: SessionClient,
|
|
352
|
-
filename: string | undefined
|
|
353
|
-
): void {
|
|
354
|
-
const sessionFiles = sessionClient.getSessionFiles();
|
|
355
|
-
const fileList = sessionFiles.listFiles();
|
|
356
|
-
const fileListStr = JSON.stringify(fileList, undefined, 2);
|
|
357
|
-
console.log(`Session files:\n${fileListStr}`);
|
|
358
|
-
if (filename) {
|
|
359
|
-
fs.writeFileSync(filename, fileListStr);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
function putFile(sessionClient: SessionClient, tail: string[]): void {
|
|
364
|
-
if (tail.length < 2) {
|
|
365
|
-
throw new Error(`usage: put-file <name> <content ....>`);
|
|
366
|
-
}
|
|
367
|
-
const name = tail[0];
|
|
368
|
-
let content = tail.slice(1).join(" ");
|
|
369
|
-
if (content.startsWith("file:")) {
|
|
370
|
-
content = loadSessionFileAsDataUrl(content.slice(5));
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
const sessionFiles = sessionClient.getSessionFiles();
|
|
374
|
-
sessionFiles.putFileContent(name, undefined, content);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
function deleteFile(sessionClient: SessionClient, name: string) {
|
|
378
|
-
const sessionFiles = sessionClient.getSessionFiles();
|
|
379
|
-
sessionFiles.deleteFile(name);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
async function getFileContents(sessionClient: SessionClient, name: string) {
|
|
383
|
-
const sessionFiles = sessionClient.getSessionFiles();
|
|
384
|
-
const dataUrl = await sessionFiles.getFileContent(name);
|
|
385
|
-
try {
|
|
386
|
-
void NODE_PLATFORM.renderHTML(`<img src="${dataUrl}" />`);
|
|
387
|
-
} catch {
|
|
388
|
-
console.log(`(render failed) file ${name}: ${dataUrl}`);
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
async function shareSession(sessionClient: SessionClient, filename: string) {
|
|
393
|
-
const accessToken = await sessionClient.shareSession();
|
|
394
|
-
fs.writeFileSync(filename, accessToken);
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
function pauseAgent(sessionClient: SessionClient, pause: string) {
|
|
398
|
-
sessionClient.setAgentPaused(!!parseInt(pause));
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
function addCustomMcpServer(chatClient: ChatClient, name: string, url: string) {
|
|
402
|
-
chatClient.addCustomMcpServer(name, "Temporary description", url);
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
function removeCustomMcpServer(chatClient: ChatClient, name: string) {
|
|
406
|
-
chatClient.removeCustomMcpServer(name);
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
function listCustomMcpServers(chatClient: ChatClient) {
|
|
410
|
-
const customMcpServers: Record<string, string> =
|
|
411
|
-
chatClient.getCustomMcpServers();
|
|
412
|
-
console.log(
|
|
413
|
-
`Custom mcp serevrs:\n${JSON.stringify(customMcpServers, undefined, 2)}`
|
|
414
|
-
);
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
async function getResource(
|
|
418
|
-
sessionClient: SessionClient,
|
|
419
|
-
serverName: string,
|
|
420
|
-
resourceUrl: string
|
|
421
|
-
) {
|
|
422
|
-
const contents = await sessionClient.getMcpResource(serverName, resourceUrl);
|
|
423
|
-
console.log(
|
|
424
|
-
`resource: (${serverName}) ${resourceUrl}: ${JSON.stringify(contents)}`
|
|
425
|
-
);
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
function setWorkspaceFromPrompt(
|
|
429
|
-
sessionClient: SessionClient,
|
|
430
|
-
cmds: string[]
|
|
431
|
-
): void {
|
|
432
|
-
let msg = "";
|
|
433
|
-
let image = undefined;
|
|
434
|
-
if (!cmds[1]) {
|
|
435
|
-
sessionClient.setWorkspace(undefined, undefined);
|
|
436
|
-
return;
|
|
437
|
-
}
|
|
438
|
-
if (cmds[1].startsWith("file:")) {
|
|
439
|
-
image = loadImageAsDataUrl(cmds[1].slice(5));
|
|
440
|
-
msg = cmds.slice(2).join(" ");
|
|
441
|
-
console.log(`setting workspace: ${msg} (image: ${image})`);
|
|
442
|
-
} else {
|
|
443
|
-
msg = cmds.slice(1).join(" ");
|
|
444
|
-
console.log(`setting workspace: ${msg}`);
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
sessionClient.setWorkspace(msg, image);
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
function getCLIEventHandler(
|
|
451
|
-
cmdPrompt?: CommandPrompt
|
|
452
|
-
): IChatClientEventHandler {
|
|
453
|
-
let numErrors = 0;
|
|
454
|
-
|
|
455
|
-
const onClosed = async () => {
|
|
456
|
-
logger.debug("[onClosed]");
|
|
457
|
-
if (cmdPrompt) {
|
|
458
|
-
// TODO: check if this fully shuts down
|
|
459
|
-
await cmdPrompt.shutdown();
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
// If there have been errors, exit with an error code.
|
|
463
|
-
process.exit(numErrors);
|
|
464
|
-
};
|
|
465
|
-
|
|
466
|
-
const onError = (message: string) => {
|
|
467
|
-
numErrors++;
|
|
468
|
-
logger.debug("[onError]");
|
|
469
|
-
console.error(message);
|
|
470
|
-
};
|
|
471
|
-
|
|
472
|
-
let startMsg = true;
|
|
473
|
-
let startReasoning = true;
|
|
474
|
-
const onMessage = async (msg: ServerToClient, client: ChatClient) => {
|
|
475
|
-
let sessionClient: SessionClient | undefined = undefined;
|
|
476
|
-
try {
|
|
477
|
-
sessionClient = client.getCurrentSession("[chatMain.onMessage]");
|
|
478
|
-
} catch (error) {
|
|
479
|
-
logger.error(String(error));
|
|
480
|
-
return;
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
switch (msg.type) {
|
|
484
|
-
case "user_msg":
|
|
485
|
-
stdout.write(`[${msg.user_nickname}]: ${msg.message || ""}\n`);
|
|
486
|
-
if (msg.imageB64) {
|
|
487
|
-
stdout.write(`[${msg.user_nickname}]: IMAGE: ${msg.imageB64}\n`);
|
|
488
|
-
}
|
|
489
|
-
break;
|
|
490
|
-
case "agent_msg":
|
|
491
|
-
{
|
|
492
|
-
const text = decodeAssistantMessageParam(msg.message);
|
|
493
|
-
if (text) {
|
|
494
|
-
stdout.write(`[AGENT]: ${text}\n`);
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
break;
|
|
498
|
-
case "agent_msg_chunk":
|
|
499
|
-
if (startMsg) {
|
|
500
|
-
if (!startReasoning) {
|
|
501
|
-
stdout.write(chalk.grey("]\n"));
|
|
502
|
-
}
|
|
503
|
-
stdout.write("[AGENT]: ");
|
|
504
|
-
startMsg = false;
|
|
505
|
-
}
|
|
506
|
-
stdout.write(msg.message);
|
|
507
|
-
if (msg.end) {
|
|
508
|
-
stdout.write("\n");
|
|
509
|
-
startMsg = true;
|
|
510
|
-
startReasoning = true;
|
|
511
|
-
}
|
|
512
|
-
break;
|
|
513
|
-
case "agent_reasoning_chunk":
|
|
514
|
-
if (startMsg) {
|
|
515
|
-
stdout.write(chalk.grey(`[${msg.reasoning}`));
|
|
516
|
-
startReasoning = false;
|
|
517
|
-
} else {
|
|
518
|
-
stdout.write(chalk.grey(msg.reasoning));
|
|
519
|
-
}
|
|
520
|
-
break;
|
|
521
|
-
case "approve_tool_call":
|
|
522
|
-
{
|
|
523
|
-
const result = cmdPrompt
|
|
524
|
-
? await cmdPrompt.promptToolCall(msg.tool_call)
|
|
525
|
-
: true;
|
|
526
|
-
logger.debug(`cmdPrompt.promptToolCall returned: ${String(result)}`);
|
|
527
|
-
sessionClient.toolCallApprovalResult(
|
|
528
|
-
msg.id,
|
|
529
|
-
result,
|
|
530
|
-
false /* auto-approve */
|
|
531
|
-
);
|
|
532
|
-
}
|
|
533
|
-
break;
|
|
534
|
-
case "tool_call_result":
|
|
535
|
-
{
|
|
536
|
-
console.log(`tool call result: ${JSON.stringify(msg.result)}`);
|
|
537
|
-
|
|
538
|
-
const metadata = msg.result._meta;
|
|
539
|
-
if (isFileMetaData(metadata)) {
|
|
540
|
-
console.log(`filemanager file: ${JSON.stringify(metadata)}`);
|
|
541
|
-
|
|
542
|
-
// SessionFiles should already hold the file information.
|
|
543
|
-
|
|
544
|
-
const sessionFiles = sessionClient.getSessionFiles();
|
|
545
|
-
const { name } = sessionFiles.decodeSessionFileUrl(
|
|
546
|
-
msg.result.content as string
|
|
547
|
-
);
|
|
548
|
-
if (!sessionFiles.descriptors.has(name)) {
|
|
549
|
-
throw new Error(`no ${name} in SessionFiles`);
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
break;
|
|
554
|
-
case "render_html":
|
|
555
|
-
await NODE_PLATFORM.renderHTML(msg.html);
|
|
556
|
-
break;
|
|
557
|
-
case "authenticate":
|
|
558
|
-
NODE_PLATFORM.openUrl(
|
|
559
|
-
msg.url,
|
|
560
|
-
new Promise<boolean>((r) => {
|
|
561
|
-
r(true);
|
|
562
|
-
}),
|
|
563
|
-
msg.display_name
|
|
564
|
-
);
|
|
565
|
-
break;
|
|
566
|
-
case "session_error":
|
|
567
|
-
stdout.write(
|
|
568
|
-
chalk.red(`session_error(${msg.session_id}): ${msg.message}`)
|
|
569
|
-
);
|
|
570
|
-
break;
|
|
571
|
-
default:
|
|
572
|
-
stdout.write(`(unrecognised) ${JSON.stringify(msg.type)}\n`);
|
|
573
|
-
break;
|
|
574
|
-
}
|
|
575
|
-
};
|
|
576
|
-
|
|
577
|
-
return {
|
|
578
|
-
onMessage,
|
|
579
|
-
onError,
|
|
580
|
-
onClosed: onClosed,
|
|
581
|
-
};
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
export const chatMain = subcommands({
|
|
585
|
-
name: "chat",
|
|
586
|
-
cmds: {
|
|
587
|
-
server,
|
|
588
|
-
client,
|
|
589
|
-
"clear-sessions": clearSessions,
|
|
590
|
-
"delete-session": deleteSession,
|
|
591
|
-
"list-sessions": listSessions,
|
|
592
|
-
"list-participants": listParticipants,
|
|
593
|
-
},
|
|
594
|
-
});
|