@xalia/agent 0.6.9 → 0.6.10
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/.env.development +6 -1
- package/.env.test +7 -0
- package/README.md +11 -0
- package/context_system.md +498 -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 +4 -1
- package/scripts/test_chat +195 -176
- package/src/agent/agent.ts +98 -23
- package/src/agent/agentUtils.ts +3 -2
- package/src/agent/documentSummarizer.ts +157 -0
- package/src/agent/dummyLLM.ts +27 -23
- package/src/agent/imageGenLLM.ts +28 -24
- package/src/agent/llm.ts +2 -2
- package/src/agent/openAILLM.ts +17 -13
- package/src/agent/openAILLMStreaming.ts +80 -41
- package/src/agent/repeatLLM.ts +19 -7
- package/src/agent/test_data/harrypotter.txt +6065 -0
- package/src/agent/tokenCounter.test.ts +243 -0
- package/src/agent/tokenCounter.ts +483 -0
- package/src/agent/toolSettings.ts +24 -0
- package/src/agent/tools/calculatorTool.ts +50 -0
- package/src/agent/tools/contentExtractors/pdfToText.ts +60 -0
- package/src/agent/tools/datetimeTool.ts +41 -0
- package/src/agent/tools/fileManager/fileManagerTool.ts +199 -0
- package/src/agent/tools/fileManager/index.ts +50 -0
- package/src/agent/tools/fileManager/memoryFileManager.ts +120 -0
- package/src/{chat/data → agent/tools/fileManager}/mimeTypes.ts +3 -1
- package/src/agent/tools/fileManager/prompt.ts +38 -0
- package/src/{chat/data/dbSessionFileModels.ts → agent/tools/fileManager/types.ts} +76 -0
- package/src/agent/tools/index.ts +49 -0
- package/src/agent/tools/openUrlTool.ts +62 -0
- package/src/agent/tools/renderTool.ts +92 -0
- package/src/agent/tools/utils.ts +74 -0
- package/src/{chat/utils/search.ts → agent/tools/webSearch.ts} +0 -1
- package/src/agent/tools/webSearchTool.ts +44 -0
- package/src/chat/client/chatClient.ts +45 -0
- package/src/chat/client/index.ts +3 -0
- package/src/chat/client/sessionClient.ts +40 -3
- package/src/chat/client/sessionFiles.ts +1 -1
- package/src/chat/constants.ts +6 -0
- package/src/chat/data/dataModels.ts +6 -0
- package/src/chat/data/dbSessionFiles.ts +12 -4
- package/src/chat/protocol/messages.ts +60 -7
- package/src/chat/server/chatContextManager.ts +58 -37
- package/src/chat/server/conversation.ts +3 -0
- package/src/chat/server/imageGeneratorTools.ts +31 -12
- package/src/chat/server/openAIRouterLLM.ts +1 -4
- package/src/chat/server/openSession.ts +323 -67
- package/src/chat/server/promptRefiner.ts +106 -0
- package/src/chat/server/server.ts +4 -1
- package/src/chat/server/sessionFileManager.ts +35 -306
- package/src/chat/server/sessionRegistry.ts +128 -0
- package/src/chat/server/titleGenerator.test.ts +103 -0
- package/src/chat/server/titleGenerator.ts +143 -0
- package/src/chat/server/tools.ts +77 -304
- package/src/chat/utils/approvalManager.ts +9 -3
- package/src/chat/utils/multiAsyncQueue.ts +4 -0
- package/src/test/agent.test.ts +17 -23
- package/src/test/chatContextManager.test.ts +29 -4
- package/src/test/dbMcpServerConfigs.test.ts +4 -4
- package/src/test/dbSessionFiles.test.ts +16 -16
- package/src/test/testTools.ts +8 -3
- package/src/test/tools.test.ts +30 -5
- package/src/tool/agentChat.ts +12 -3
- package/src/tool/chatMain.ts +33 -6
- package/src/tool/commandPrompt.ts +2 -2
- package/src/tool/files.ts +1 -3
- package/dist/agent/src/agent/tools.js +0 -44
- package/src/agent/tools.ts +0 -57
- /package/dist/agent/src/{chat/utils → agent/tools/contentExtractors}/htmlToText.js +0 -0
- /package/src/{chat/utils → agent/tools/contentExtractors}/htmlToText.ts +0 -0
|
@@ -34,15 +34,14 @@ import {
|
|
|
34
34
|
ISessionFileManager,
|
|
35
35
|
ISessionFileManagerEventHandler,
|
|
36
36
|
createSessionFilesManagerPrompt,
|
|
37
|
-
} from "./sessionFileManager";
|
|
38
|
-
import {
|
|
39
37
|
SessionFileDescriptor,
|
|
40
38
|
SessionFileEntry,
|
|
41
|
-
} from "
|
|
39
|
+
} from "../../agent/tools/fileManager";
|
|
42
40
|
// eslint-disable-next-line max-len
|
|
43
41
|
import { ContextTransactionWithWorkspace } from "../../agent/contextWithWorkspace";
|
|
44
42
|
import { getErrorString } from "./errorUtils";
|
|
45
43
|
import { createUserMessage } from "../../agent/agent";
|
|
44
|
+
import { TokenCounter } from "../../agent/tokenCounter";
|
|
46
45
|
|
|
47
46
|
const logger = getLogger();
|
|
48
47
|
|
|
@@ -64,7 +63,8 @@ export interface ICheckpointWriter {
|
|
|
64
63
|
export class ChatContextTransaction implements IContextTransaction {
|
|
65
64
|
private readonly baseTx: ContextTransactionWithWorkspace;
|
|
66
65
|
private readonly sessionUUID: string;
|
|
67
|
-
/// Index of final message in the committed context
|
|
66
|
+
/// Index of final message in the committed context. If this has changed
|
|
67
|
+
/// before we try to commit this tx, the commit will fail.
|
|
68
68
|
private readonly baseMsgIdx: number | undefined;
|
|
69
69
|
private readonly startingLLMContextLength: number;
|
|
70
70
|
private readonly pendingMessages: ConversationMessage[];
|
|
@@ -216,7 +216,6 @@ export class ChatContextManager implements ISessionFileManagerEventHandler {
|
|
|
216
216
|
private readonly llmContext: CompressingContextManager;
|
|
217
217
|
|
|
218
218
|
private nextMessageIdx: number;
|
|
219
|
-
private pendingUserMessages: ServerUserMessage[];
|
|
220
219
|
|
|
221
220
|
// Compression state
|
|
222
221
|
private readonly checkpointWriter: ICheckpointWriter;
|
|
@@ -226,6 +225,10 @@ export class ChatContextManager implements ISessionFileManagerEventHandler {
|
|
|
226
225
|
private readonly fileManager: ISessionFileManager;
|
|
227
226
|
private fileManagerDescriptionsDirty: boolean;
|
|
228
227
|
|
|
228
|
+
// LLM and token counting
|
|
229
|
+
private readonly llm: ILLM;
|
|
230
|
+
private tokenCounter: TokenCounter;
|
|
231
|
+
|
|
229
232
|
constructor(
|
|
230
233
|
systemPrompt: string,
|
|
231
234
|
sessionMessages: SessionMessage[],
|
|
@@ -254,7 +257,6 @@ export class ChatContextManager implements ISessionFileManagerEventHandler {
|
|
|
254
257
|
defaultUserName,
|
|
255
258
|
sessionUUID
|
|
256
259
|
);
|
|
257
|
-
this.pendingUserMessages = [];
|
|
258
260
|
this.llmContext = new CompressingContextManager(
|
|
259
261
|
systemPrompt,
|
|
260
262
|
llmMessages,
|
|
@@ -266,13 +268,14 @@ export class ChatContextManager implements ISessionFileManagerEventHandler {
|
|
|
266
268
|
this.fileManager = fileManager;
|
|
267
269
|
fileManager.addEventHandler(this);
|
|
268
270
|
this.fileManagerDescriptionsDirty = true;
|
|
271
|
+
this.llm = llm;
|
|
272
|
+
this.tokenCounter = new TokenCounter(llm.getModel());
|
|
269
273
|
}
|
|
270
274
|
|
|
271
275
|
// IContextManager.getLLMContext
|
|
272
276
|
getLLMContext(): MessageParam[] {
|
|
273
277
|
if (this.fileManagerDescriptionsDirty) {
|
|
274
278
|
const prompt = createSessionFilesManagerPrompt(this.fileManager);
|
|
275
|
-
logger.debug(`[ChatContextManager] filemanager prompt:\n${prompt}`);
|
|
276
279
|
this.llmContext.setPromptFragment("file_manager", prompt);
|
|
277
280
|
this.fileManagerDescriptionsDirty = false;
|
|
278
281
|
}
|
|
@@ -324,7 +327,22 @@ export class ChatContextManager implements ISessionFileManagerEventHandler {
|
|
|
324
327
|
|
|
325
328
|
// Get the conversation (to send to clients)
|
|
326
329
|
getConversationMessages(): ConversationMessage[] {
|
|
327
|
-
return this.conversationMessages
|
|
330
|
+
return this.conversationMessages;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Get current context usage (tokens)
|
|
334
|
+
getContextUsage(): { used: number; max: number } {
|
|
335
|
+
// Update tokenCounter if model changed
|
|
336
|
+
const currentModel = this.llm.getModel();
|
|
337
|
+
if (this.tokenCounter.getModel() !== currentModel) {
|
|
338
|
+
this.tokenCounter.free();
|
|
339
|
+
this.tokenCounter = new TokenCounter(currentModel);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const messages = this.getLLMContext();
|
|
343
|
+
const used = this.tokenCounter.countMessagesTokens(messages);
|
|
344
|
+
const max = this.tokenCounter.getContextWindow();
|
|
345
|
+
return { used, max };
|
|
328
346
|
}
|
|
329
347
|
|
|
330
348
|
processUserMessage(
|
|
@@ -336,7 +354,11 @@ export class ChatContextManager implements ISessionFileManagerEventHandler {
|
|
|
336
354
|
// pass in our generated messages back into `startAgentResponse`.
|
|
337
355
|
|
|
338
356
|
// Filter out null messages immediately.
|
|
339
|
-
if (
|
|
357
|
+
if (
|
|
358
|
+
!msg.imageB64 &&
|
|
359
|
+
!msg.message &&
|
|
360
|
+
(!msg.attachedFiles || msg.attachedFiles.length === 0)
|
|
361
|
+
) {
|
|
340
362
|
return undefined;
|
|
341
363
|
}
|
|
342
364
|
|
|
@@ -352,8 +374,13 @@ export class ChatContextManager implements ISessionFileManagerEventHandler {
|
|
|
352
374
|
if (msg.imageB64) {
|
|
353
375
|
userMessage.imageB64 = msg.imageB64;
|
|
354
376
|
}
|
|
377
|
+
if (msg.attachedFiles) {
|
|
378
|
+
userMessage.attachedFiles = msg.attachedFiles;
|
|
379
|
+
}
|
|
380
|
+
if (msg.race_mode) {
|
|
381
|
+
userMessage.race_mode = msg.race_mode;
|
|
382
|
+
}
|
|
355
383
|
|
|
356
|
-
this.pendingUserMessages.push(userMessage);
|
|
357
384
|
return userMessage;
|
|
358
385
|
}
|
|
359
386
|
|
|
@@ -373,32 +400,18 @@ export class ChatContextManager implements ISessionFileManagerEventHandler {
|
|
|
373
400
|
// Sanity check the state - the incoming user messages should match the
|
|
374
401
|
// pending user messages.
|
|
375
402
|
|
|
376
|
-
const numMessages =
|
|
377
|
-
assert(numMessages > 0);
|
|
378
|
-
if (msgs.length !== this.pendingUserMessages.length) {
|
|
379
|
-
throw new Error(
|
|
380
|
-
`length mismatch: msgs: ${JSON.stringify(msgs)}, ` +
|
|
381
|
-
`this.pendingUserMsgs: ${JSON.stringify(this.pendingUserMessages)}`
|
|
382
|
-
);
|
|
383
|
-
}
|
|
384
|
-
assert(msgs[0].message_idx === this.pendingUserMessages[0].message_idx);
|
|
385
|
-
assert(
|
|
386
|
-
msgs[numMessages - 1].message_idx ===
|
|
387
|
-
this.pendingUserMessages[numMessages - 1].message_idx
|
|
388
|
-
);
|
|
389
|
-
|
|
403
|
+
const numMessages = msgs.length;
|
|
404
|
+
assert(numMessages > 0, "no messages");
|
|
390
405
|
// Collect the pending user messages and allocate a starting index for
|
|
391
406
|
// agent messages and tool calls.
|
|
392
407
|
|
|
393
|
-
const
|
|
394
|
-
const baseMsgIdx = this.lastMessageIdx();
|
|
408
|
+
const baseMsgIdx = this.lastCommittedMessageIdx();
|
|
395
409
|
const curAgentMsgIdx = this.getNextMessageIdx();
|
|
396
|
-
this.pendingUserMessages = [];
|
|
397
410
|
|
|
398
411
|
// Compute the new llm messages
|
|
399
412
|
|
|
400
413
|
const llmUserMessages: UserMessageParam[] = [];
|
|
401
|
-
for (const msg of
|
|
414
|
+
for (const msg of msgs) {
|
|
402
415
|
const userMsg = createUserMessage(
|
|
403
416
|
msg.message,
|
|
404
417
|
msg.imageB64,
|
|
@@ -419,12 +432,19 @@ export class ChatContextManager implements ISessionFileManagerEventHandler {
|
|
|
419
432
|
end: false,
|
|
420
433
|
};
|
|
421
434
|
|
|
435
|
+
// Update file manager fragment BEFORE starting the transaction
|
|
436
|
+
if (this.fileManagerDescriptionsDirty) {
|
|
437
|
+
const prompt = createSessionFilesManagerPrompt(this.fileManager);
|
|
438
|
+
this.llmContext.setPromptFragment("file_manager", prompt);
|
|
439
|
+
this.fileManagerDescriptionsDirty = false;
|
|
440
|
+
}
|
|
441
|
+
|
|
422
442
|
const baseTx = await this.llmContext.startTx(llmUserMessages);
|
|
423
443
|
const contextTx = new ChatContextTransaction(
|
|
424
444
|
baseTx,
|
|
425
445
|
this.sessionUUID,
|
|
426
446
|
baseMsgIdx,
|
|
427
|
-
|
|
447
|
+
msgs,
|
|
428
448
|
curAgentMsgIdx
|
|
429
449
|
);
|
|
430
450
|
return { agentFirstChunk, contextTx };
|
|
@@ -432,7 +452,7 @@ export class ChatContextManager implements ISessionFileManagerEventHandler {
|
|
|
432
452
|
|
|
433
453
|
async endAgentResponse(tx: IContextTransaction): Promise<SessionMessage[]> {
|
|
434
454
|
assert(tx instanceof ChatContextTransaction);
|
|
435
|
-
if (tx.baseMessageIdx() !== this.
|
|
455
|
+
if (tx.baseMessageIdx() !== this.lastCommittedMessageIdx()) {
|
|
436
456
|
throw new Error(
|
|
437
457
|
`Tx stale? tx.baseMessageIdx=${String(tx.baseMessageIdx())}, ` +
|
|
438
458
|
`this.conv: ${JSON.stringify(this.conversationMessages)}`
|
|
@@ -449,12 +469,13 @@ export class ChatContextManager implements ISessionFileManagerEventHandler {
|
|
|
449
469
|
const newLLMMessages = tx.newMessages();
|
|
450
470
|
|
|
451
471
|
const messageListError = (error: string) => {
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
);
|
|
472
|
+
const fullError =
|
|
473
|
+
`[endAgentResponse] Message list validation failed - ${error}:` +
|
|
474
|
+
`\n newSessionMessages: ${JSON.stringify(newSessionMessages)}` +
|
|
475
|
+
`\n pending: ${JSON.stringify(pending)}` +
|
|
476
|
+
`\n newLLMMessages: ${JSON.stringify(newLLMMessages)}`;
|
|
477
|
+
logger.error(fullError);
|
|
478
|
+
throw new Error(fullError);
|
|
458
479
|
};
|
|
459
480
|
|
|
460
481
|
if (newSessionMessages.length !== numPending) {
|
|
@@ -506,7 +527,7 @@ export class ChatContextManager implements ISessionFileManagerEventHandler {
|
|
|
506
527
|
return newSessionMessages;
|
|
507
528
|
}
|
|
508
529
|
|
|
509
|
-
private
|
|
530
|
+
private lastCommittedMessageIdx(): number | undefined {
|
|
510
531
|
const numMsgs = this.conversationMessages.length;
|
|
511
532
|
if (numMsgs > 0) {
|
|
512
533
|
return this.conversationMessages[numMsgs - 1].message_idx;
|
|
@@ -4,15 +4,16 @@ import { AgentEx, IAgentToolProvider, ToolCallResult } from "../../agent/agent";
|
|
|
4
4
|
import { ToolDescriptor } from "../../agent/llm";
|
|
5
5
|
import { ImageGenerator } from "../../agent/imageGenerator";
|
|
6
6
|
import {
|
|
7
|
-
|
|
7
|
+
ISessionFileManager,
|
|
8
8
|
ToolCallResultWithFileRef,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
getSessionFileMimeTypeFromDataUrl,
|
|
10
|
+
makeParseArgsFn,
|
|
11
|
+
} from "../../agent/tools";
|
|
12
12
|
import { getOpenAIClientParams } from "./openAIRouterLLM";
|
|
13
13
|
import { DEFAULT_IMAGE_GEN_MODEL, ImageGenLLM } from "../../agent/imageGenLLM";
|
|
14
14
|
import { createSpecializedLLM } from "../../agent/agentUtils";
|
|
15
15
|
import { IPlatform } from "../../agent/iplatform";
|
|
16
|
+
import { CANVAS_WORKSPACE_FILENAME } from "../constants";
|
|
16
17
|
|
|
17
18
|
const logger = getLogger();
|
|
18
19
|
|
|
@@ -95,13 +96,17 @@ export async function genImageTool(
|
|
|
95
96
|
|
|
96
97
|
export async function genImageFileTool(
|
|
97
98
|
platform: IPlatform,
|
|
98
|
-
fileManager:
|
|
99
|
+
fileManager: ISessionFileManager
|
|
99
100
|
): Promise<IAgentToolProvider> {
|
|
100
101
|
const GEN_IMAGE_FILE_DESC: ToolDescriptor = {
|
|
101
102
|
type: "function",
|
|
102
103
|
function: {
|
|
103
104
|
name: "gen_image_file",
|
|
104
|
-
description:
|
|
105
|
+
description:
|
|
106
|
+
"Generate or edit an image. Saves result to file manager. " +
|
|
107
|
+
`Canvas workspace is '${CANVAS_WORKSPACE_FILENAME}'. ` +
|
|
108
|
+
"When editing canvas images, set add_to_canvas=true to " +
|
|
109
|
+
"place the result back onto the canvas.",
|
|
105
110
|
parameters: {
|
|
106
111
|
type: "object",
|
|
107
112
|
properties: {
|
|
@@ -119,7 +124,14 @@ export async function genImageFileTool(
|
|
|
119
124
|
},
|
|
120
125
|
input_name: {
|
|
121
126
|
type: "string",
|
|
122
|
-
description:
|
|
127
|
+
description:
|
|
128
|
+
"(Optional) input image filename. " +
|
|
129
|
+
`Use '${CANVAS_WORKSPACE_FILENAME}' for canvas edits.`,
|
|
130
|
+
},
|
|
131
|
+
add_to_canvas: {
|
|
132
|
+
type: "boolean",
|
|
133
|
+
description:
|
|
134
|
+
"Set true to place result on canvas (use when editing canvas)",
|
|
123
135
|
},
|
|
124
136
|
},
|
|
125
137
|
required: ["prompt", "name", "summary"],
|
|
@@ -128,26 +140,33 @@ export async function genImageFileTool(
|
|
|
128
140
|
} as const;
|
|
129
141
|
|
|
130
142
|
const imageGenerator = await createImageGenerator(platform);
|
|
131
|
-
const
|
|
143
|
+
const getArgs = makeParseArgsFn(
|
|
132
144
|
["prompt", "name", "summary"] as const,
|
|
133
|
-
["input_name"] as const
|
|
145
|
+
["input_name"] as const,
|
|
146
|
+
["add_to_canvas"] as const
|
|
134
147
|
);
|
|
135
148
|
const toolFn = async (
|
|
136
149
|
_: AgentEx,
|
|
137
150
|
args: unknown
|
|
138
151
|
): Promise<ToolCallResultWithFileRef> => {
|
|
139
|
-
const { prompt, name, summary, input_name } =
|
|
152
|
+
const { prompt, name, summary, input_name, add_to_canvas } = getArgs(args);
|
|
153
|
+
const addToCanvas = add_to_canvas ?? false;
|
|
154
|
+
|
|
140
155
|
const input_image = input_name
|
|
141
156
|
? await fileManager.getFileContent(input_name)
|
|
142
157
|
: undefined;
|
|
143
158
|
|
|
144
159
|
const image = await imageGenerator.generate(prompt, input_image);
|
|
145
|
-
const mimeType = getSessionFileMimeTypeFromDataUrl(image);
|
|
146
160
|
await fileManager.putFileContent(name, summary, image);
|
|
147
161
|
const uri = fileManager.getSessionFileRelativeUrl(name);
|
|
162
|
+
|
|
148
163
|
return {
|
|
149
164
|
response: uri,
|
|
150
|
-
_meta: {
|
|
165
|
+
_meta: {
|
|
166
|
+
"xalia/fileUri": uri,
|
|
167
|
+
"xalia/fileMimeType": getSessionFileMimeTypeFromDataUrl(image),
|
|
168
|
+
...(addToCanvas && { "xalia/addToCanvas": "true" }),
|
|
169
|
+
},
|
|
151
170
|
};
|
|
152
171
|
};
|
|
153
172
|
|
|
@@ -20,7 +20,6 @@ const DEFAULT_PROVIDER_URLS: Record<string, string | undefined> = {
|
|
|
20
20
|
openrouter: "https://openrouter.ai/api/v1",
|
|
21
21
|
openai: "https://api.openai.com/v1",
|
|
22
22
|
anthropic: "https://api.anthropic.com/v1",
|
|
23
|
-
together: "https://api.together.xyz/v1",
|
|
24
23
|
};
|
|
25
24
|
|
|
26
25
|
const DEFAULT_MODEL_MAP: Record<string, string | undefined> = {
|
|
@@ -35,8 +34,6 @@ const DEFAULT_MODEL_MAP: Record<string, string | undefined> = {
|
|
|
35
34
|
"anthropic/claude-sonnet-4": "openrouter",
|
|
36
35
|
"anthropic/claude-sonnet-4.5": "openrouter",
|
|
37
36
|
"claude-3-7-sonnet-20250219": "anthropic",
|
|
38
|
-
"arcee-ai/AFM-4.5B-Preview": "together",
|
|
39
|
-
"meta-llama/Llama-3.3-70B-Instruct-Turbo-Free": "together",
|
|
40
37
|
};
|
|
41
38
|
|
|
42
39
|
type CachedMaps = {
|
|
@@ -158,7 +155,7 @@ export class OpenAIRouterLLM implements ILLM {
|
|
|
158
155
|
tools?: ToolDescriptor[],
|
|
159
156
|
onMessage?: (msg: string, end: boolean) => Promise<void>,
|
|
160
157
|
onReasoning?: (reasoning: string) => Promise<void>
|
|
161
|
-
): Promise<Completion> {
|
|
158
|
+
): Promise<{ stop: (msg: string) => void; completion: Promise<Completion> }> {
|
|
162
159
|
return OpenAILLMStreaming.makeRequest(
|
|
163
160
|
this.openai,
|
|
164
161
|
this.model,
|