openfox 1.6.21 → 1.6.25
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 +46 -13
- package/dist/{auto-compaction-U75EINMB.js → auto-compaction-7LK3QGPI.js} +4 -3
- package/dist/{chat-handler-JEMPI5UF.js → chat-handler-ZU74RXED.js} +6 -5
- package/dist/{chunk-HWOYZ245.js → chunk-2V7VPPBP.js} +6 -6
- package/dist/{chunk-HZP2V5Z6.js → chunk-4O3C2JMB.js} +5 -9
- package/dist/{chunk-SJVEX2NR.js → chunk-7LPL774T.js} +19 -19
- package/dist/{chunk-AU33PQAB.js → chunk-BOEXJCOD.js} +2 -2
- package/dist/{chunk-6NPMZFMP.js → chunk-CJNQGEYG.js} +2 -2
- package/dist/{chunk-XYD5JXRM.js → chunk-D4ZLSV6P.js} +292 -1
- package/dist/{chunk-FX4SUY2S.js → chunk-KSASIV4B.js} +10 -287
- package/dist/{chunk-XRGMFOVG.js → chunk-P6GUT2QQ.js} +3 -3
- package/dist/{chunk-WINI5HX7.js → chunk-PYBB34ZK.js} +3 -3
- package/dist/cli/dev.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/{config-SWDAJMQ3.js → config-ACVEHBKG.js} +5 -5
- package/dist/{orchestrator-T2IPRZ7B.js → orchestrator-OE7WFEW6.js} +5 -4
- package/dist/package.json +3 -3
- package/dist/{processor-VKFEOK46.js → processor-GAOK7TPI.js} +2 -2
- package/dist/{provider-CDM4LQAC.js → provider-RLQMVV2Z.js} +7 -7
- package/dist/{serve-X3PKC27B.js → serve-3L3HLUVT.js} +9 -9
- package/dist/server/index.js +7 -7
- package/dist/{tools-4ODVFMW7.js → tools-CSV7G554.js} +4 -3
- package/dist/{vision-fallback-VXGCQKLA.js → vision-fallback-QJ26DCEF.js} +2 -2
- package/dist/web/assets/index-VCGZnpy0.js +153 -0
- package/dist/web/assets/{index-B9-lT3Kc.css → index-y9uYQYP-.css} +1 -1
- package/dist/web/index.html +2 -2
- package/dist/web/sw.js +1 -1
- package/package.json +3 -3
- package/dist/web/assets/index-DHP3d5Cl.js +0 -151
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
describeImageFromDataUrl
|
|
3
|
+
} from "./chunk-CJNQGEYG.js";
|
|
1
4
|
import {
|
|
2
5
|
logger
|
|
3
6
|
} from "./chunk-PNBH3RAX.js";
|
|
@@ -360,6 +363,289 @@ function getModelProfile(modelName) {
|
|
|
360
363
|
return DEFAULT_PROFILE;
|
|
361
364
|
}
|
|
362
365
|
|
|
366
|
+
// src/server/llm/client-pure.ts
|
|
367
|
+
function buildModelParams(params) {
|
|
368
|
+
return {
|
|
369
|
+
...params.temperature !== void 0 && { temperature: params.temperature },
|
|
370
|
+
...params.topP !== void 0 && { topP: params.topP },
|
|
371
|
+
...params.topK !== void 0 && { topK: params.topK },
|
|
372
|
+
...params.maxTokens !== void 0 && { maxTokens: params.maxTokens }
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
function buildAttachmentContent(msgContent, attachments, modelSupportsVision) {
|
|
376
|
+
const content = [];
|
|
377
|
+
if (msgContent?.trim()) {
|
|
378
|
+
content.push({ type: "text", text: msgContent });
|
|
379
|
+
}
|
|
380
|
+
for (const attachment of attachments) {
|
|
381
|
+
content.push(convertAttachmentSync(attachment, modelSupportsVision));
|
|
382
|
+
}
|
|
383
|
+
return content;
|
|
384
|
+
}
|
|
385
|
+
async function convertMessagesWithOptions(messages, profile, visionFallbackEnabled, signal, onVisionFallbackStart, onVisionFallbackDone) {
|
|
386
|
+
const modelSupportsVision = profile.supportsVision ?? false;
|
|
387
|
+
const options = {
|
|
388
|
+
modelSupportsVision,
|
|
389
|
+
visionFallbackEnabled,
|
|
390
|
+
signal,
|
|
391
|
+
onVisionFallbackStart,
|
|
392
|
+
onVisionFallbackDone
|
|
393
|
+
};
|
|
394
|
+
return needsVisionFallback(messages, modelSupportsVision, visionFallbackEnabled) ? await convertMessagesWithFallback(messages, options) : convertMessages(messages, { modelSupportsVision, visionFallbackEnabled: false });
|
|
395
|
+
}
|
|
396
|
+
function convertToolCalls(toolCalls) {
|
|
397
|
+
return toolCalls.map((toolCall) => ({
|
|
398
|
+
id: toolCall.id,
|
|
399
|
+
type: "function",
|
|
400
|
+
function: {
|
|
401
|
+
name: toolCall.name,
|
|
402
|
+
arguments: JSON.stringify(toolCall.arguments)
|
|
403
|
+
}
|
|
404
|
+
}));
|
|
405
|
+
}
|
|
406
|
+
function convertAttachmentSync(attachment, modelSupportsVision) {
|
|
407
|
+
if (modelSupportsVision) {
|
|
408
|
+
return {
|
|
409
|
+
type: "image_url",
|
|
410
|
+
image_url: { url: attachment.data }
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
return {
|
|
414
|
+
type: "text",
|
|
415
|
+
text: `[Image: ${attachment.filename || "image"}] (vision not supported, cannot describe)`
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
function createAttachmentForConversion(data, filename, id) {
|
|
419
|
+
return {
|
|
420
|
+
data,
|
|
421
|
+
...filename !== void 0 && { filename },
|
|
422
|
+
...id !== void 0 && { id }
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
async function convertAttachmentWithFallback(attachment, options) {
|
|
426
|
+
logger.debug("[VisionFallback] convertAttachmentWithFallback called", { filename: attachment.filename, id: attachment.id, hasCallbacks: !!options.onVisionFallbackStart });
|
|
427
|
+
if (options.modelSupportsVision) {
|
|
428
|
+
logger.debug("[VisionFallback] Model supports vision - passing image directly");
|
|
429
|
+
return {
|
|
430
|
+
type: "image_url",
|
|
431
|
+
image_url: { url: attachment.data }
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
if (!options.visionFallbackEnabled) {
|
|
435
|
+
logger.debug("[VisionFallback] Fallback disabled - returning placeholder");
|
|
436
|
+
return {
|
|
437
|
+
type: "text",
|
|
438
|
+
text: `[Image: ${attachment.filename || "image"}] (vision not supported)`
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
const attachmentId = attachment.id ?? crypto.randomUUID();
|
|
442
|
+
const filename = attachment.filename;
|
|
443
|
+
logger.debug("[VisionFallback] Starting delegation for:", { attachmentId, filename });
|
|
444
|
+
options.onVisionFallbackStart?.(attachmentId, filename);
|
|
445
|
+
const context = filename ? `File: ${filename}` : void 0;
|
|
446
|
+
const description = await describeImageFromDataUrl(attachment.data, { context, signal: options.signal });
|
|
447
|
+
logger.debug("[VisionFallback] Delegation complete:", { attachmentId, descriptionLength: description.length });
|
|
448
|
+
options.onVisionFallbackDone?.(attachmentId, description);
|
|
449
|
+
return {
|
|
450
|
+
type: "text",
|
|
451
|
+
text: `[Image: ${attachment.filename || "image"}] ${description}`
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
async function buildAttachmentContentWithFallback(msgContent, attachments, options) {
|
|
455
|
+
const content = [];
|
|
456
|
+
if (msgContent?.trim()) {
|
|
457
|
+
content.push({ type: "text", text: msgContent });
|
|
458
|
+
}
|
|
459
|
+
for (const attachment of attachments) {
|
|
460
|
+
const convertedContent = await convertAttachmentWithFallback(
|
|
461
|
+
createAttachmentForConversion(attachment.data, attachment.filename, attachment.id),
|
|
462
|
+
options
|
|
463
|
+
);
|
|
464
|
+
content.push(convertedContent);
|
|
465
|
+
}
|
|
466
|
+
return content;
|
|
467
|
+
}
|
|
468
|
+
function convertMessages(messages, options) {
|
|
469
|
+
const filtered = messages.filter((msg) => {
|
|
470
|
+
return !(msg.role === "assistant" && !msg.content?.trim() && (!msg.toolCalls || msg.toolCalls.length === 0));
|
|
471
|
+
});
|
|
472
|
+
return filtered.map((msg) => {
|
|
473
|
+
if (msg.role === "tool") {
|
|
474
|
+
if (msg.attachments && msg.attachments.length > 0) {
|
|
475
|
+
const content = buildAttachmentContent(msg.content, msg.attachments, options.modelSupportsVision);
|
|
476
|
+
return {
|
|
477
|
+
role: "tool",
|
|
478
|
+
content,
|
|
479
|
+
tool_call_id: msg.toolCallId
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
return {
|
|
483
|
+
role: "tool",
|
|
484
|
+
content: msg.content,
|
|
485
|
+
tool_call_id: msg.toolCallId
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
if (msg.role === "assistant" && msg.toolCalls?.length) {
|
|
489
|
+
return {
|
|
490
|
+
role: "assistant",
|
|
491
|
+
content: msg.content || null,
|
|
492
|
+
tool_calls: convertToolCalls(msg.toolCalls)
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
if (msg.role === "user" && msg.attachments && msg.attachments.length > 0) {
|
|
496
|
+
const content = buildAttachmentContent(msg.content, msg.attachments, options.modelSupportsVision);
|
|
497
|
+
return {
|
|
498
|
+
role: "user",
|
|
499
|
+
content
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
return {
|
|
503
|
+
role: msg.role,
|
|
504
|
+
content: msg.content
|
|
505
|
+
};
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
async function convertMessagesWithFallback(messages, options) {
|
|
509
|
+
logger.debug("[VisionFallback] convertMessagesWithFallback called", { messageCount: messages.length });
|
|
510
|
+
const filtered = messages.filter((msg) => {
|
|
511
|
+
return !(msg.role === "assistant" && !msg.content?.trim() && (!msg.toolCalls || msg.toolCalls.length === 0));
|
|
512
|
+
});
|
|
513
|
+
const converted = [];
|
|
514
|
+
for (const msg of filtered) {
|
|
515
|
+
if (msg.role === "tool") {
|
|
516
|
+
if (msg.attachments && msg.attachments.length > 0) {
|
|
517
|
+
const content = await buildAttachmentContentWithFallback(msg.content, msg.attachments, options);
|
|
518
|
+
converted.push({
|
|
519
|
+
role: "tool",
|
|
520
|
+
content,
|
|
521
|
+
tool_call_id: msg.toolCallId
|
|
522
|
+
});
|
|
523
|
+
} else {
|
|
524
|
+
converted.push({
|
|
525
|
+
role: "tool",
|
|
526
|
+
content: msg.content,
|
|
527
|
+
tool_call_id: msg.toolCallId
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
continue;
|
|
531
|
+
}
|
|
532
|
+
if (msg.role === "assistant" && msg.toolCalls?.length) {
|
|
533
|
+
converted.push({
|
|
534
|
+
role: "assistant",
|
|
535
|
+
content: msg.content || null,
|
|
536
|
+
tool_calls: convertToolCalls(msg.toolCalls)
|
|
537
|
+
});
|
|
538
|
+
continue;
|
|
539
|
+
}
|
|
540
|
+
if (msg.role === "user" && msg.attachments && msg.attachments.length > 0) {
|
|
541
|
+
const content = await buildAttachmentContentWithFallback(msg.content, msg.attachments, options);
|
|
542
|
+
converted.push({
|
|
543
|
+
role: "user",
|
|
544
|
+
content
|
|
545
|
+
});
|
|
546
|
+
continue;
|
|
547
|
+
}
|
|
548
|
+
converted.push({
|
|
549
|
+
role: msg.role,
|
|
550
|
+
content: msg.content
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
return converted;
|
|
554
|
+
}
|
|
555
|
+
function convertTools(tools) {
|
|
556
|
+
return tools.map((tool) => ({
|
|
557
|
+
type: "function",
|
|
558
|
+
function: {
|
|
559
|
+
name: tool.function.name,
|
|
560
|
+
description: tool.function.description,
|
|
561
|
+
parameters: tool.function.parameters
|
|
562
|
+
}
|
|
563
|
+
}));
|
|
564
|
+
}
|
|
565
|
+
function needsVisionFallback(messages, modelSupportsVision, visionFallbackEnabled) {
|
|
566
|
+
const hasAttachments = messages.some(
|
|
567
|
+
(msg) => msg.attachments && msg.attachments.length > 0 || msg.role === "tool" && msg.attachments && msg.attachments.length > 0
|
|
568
|
+
);
|
|
569
|
+
const result = hasAttachments && !modelSupportsVision && visionFallbackEnabled;
|
|
570
|
+
logger.debug("[VisionFallback] needsVisionFallback check", {
|
|
571
|
+
hasAttachments,
|
|
572
|
+
modelSupportsVision,
|
|
573
|
+
visionFallbackEnabled,
|
|
574
|
+
result
|
|
575
|
+
});
|
|
576
|
+
return result;
|
|
577
|
+
}
|
|
578
|
+
async function buildChatCompletionCreateParams(model, request, profile, capabilities, disableThinking, visionFallbackEnabled, isStreaming, onVisionFallbackStart, onVisionFallbackDone) {
|
|
579
|
+
const convertedMessages = await convertMessagesWithOptions(
|
|
580
|
+
request.messages,
|
|
581
|
+
profile,
|
|
582
|
+
visionFallbackEnabled,
|
|
583
|
+
request.signal,
|
|
584
|
+
onVisionFallbackStart,
|
|
585
|
+
onVisionFallbackDone
|
|
586
|
+
);
|
|
587
|
+
const temperature = request.temperature ?? profile.temperature;
|
|
588
|
+
const maxTokens = request.maxTokens ?? profile.defaultMaxTokens;
|
|
589
|
+
const topP = profile.topP;
|
|
590
|
+
const topK = capabilities.supportsTopK ? profile.topK : void 0;
|
|
591
|
+
const params = {
|
|
592
|
+
model,
|
|
593
|
+
messages: convertedMessages,
|
|
594
|
+
...request.tools ? { tools: convertTools(request.tools) } : {},
|
|
595
|
+
...request.toolChoice ? { tool_choice: request.toolChoice } : {},
|
|
596
|
+
temperature,
|
|
597
|
+
max_tokens: maxTokens,
|
|
598
|
+
top_p: topP,
|
|
599
|
+
stream: isStreaming,
|
|
600
|
+
...isStreaming ? { stream_options: { include_usage: true } } : {}
|
|
601
|
+
};
|
|
602
|
+
if (topK !== void 0) {
|
|
603
|
+
;
|
|
604
|
+
params["top_k"] = topK;
|
|
605
|
+
}
|
|
606
|
+
const shouldDisableThinking = isStreaming ? disableThinking || request.disableThinking : disableThinking;
|
|
607
|
+
if (capabilities.supportsChatTemplateKwargs && profile.supportsReasoning && shouldDisableThinking) {
|
|
608
|
+
;
|
|
609
|
+
params["chat_template_kwargs"] = { enable_thinking: false };
|
|
610
|
+
}
|
|
611
|
+
const modelParams = buildModelParams({ temperature, topP, topK, maxTokens });
|
|
612
|
+
return { params, modelParams };
|
|
613
|
+
}
|
|
614
|
+
async function buildCreateParamsFromInput(input, isStreaming) {
|
|
615
|
+
const { model, request, profile, capabilities, disableThinking, visionFallbackEnabled = false, onVisionFallbackStart, onVisionFallbackDone } = input;
|
|
616
|
+
return buildChatCompletionCreateParams(model, request, profile, capabilities, !!disableThinking, visionFallbackEnabled, isStreaming, onVisionFallbackStart, onVisionFallbackDone);
|
|
617
|
+
}
|
|
618
|
+
var buildNonStreamingCreateParams = (input) => buildCreateParamsFromInput(input, false);
|
|
619
|
+
var buildStreamingCreateParams = (input) => buildCreateParamsFromInput(input, true);
|
|
620
|
+
function mapFinishReason(reason) {
|
|
621
|
+
switch (reason) {
|
|
622
|
+
case "stop":
|
|
623
|
+
return "stop";
|
|
624
|
+
case "tool_calls":
|
|
625
|
+
return "tool_calls";
|
|
626
|
+
case "length":
|
|
627
|
+
return "length";
|
|
628
|
+
case "content_filter":
|
|
629
|
+
return "content_filter";
|
|
630
|
+
default:
|
|
631
|
+
return "stop";
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
function extractThinking(content) {
|
|
635
|
+
const thinkRegex = /<think>([\s\S]*?)<\/think>/g;
|
|
636
|
+
let thinkingContent = "";
|
|
637
|
+
let cleanContent = content;
|
|
638
|
+
let match;
|
|
639
|
+
while ((match = thinkRegex.exec(content)) !== null) {
|
|
640
|
+
thinkingContent += match[1];
|
|
641
|
+
cleanContent = cleanContent.replace(match[0], "");
|
|
642
|
+
}
|
|
643
|
+
return {
|
|
644
|
+
content: cleanContent.trim(),
|
|
645
|
+
thinkingContent: thinkingContent.trim() || null
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
|
|
363
649
|
// src/server/llm/streaming.ts
|
|
364
650
|
var XML_TOOL_PATTERNS = ["<tool_call>", "<function=", "</tool_call>", "<parameter="];
|
|
365
651
|
function hasXmlToolPattern(text) {
|
|
@@ -478,6 +764,11 @@ export {
|
|
|
478
764
|
getBackendCapabilities,
|
|
479
765
|
detectBackend,
|
|
480
766
|
getBackendDisplayName,
|
|
767
|
+
buildModelParams,
|
|
768
|
+
buildNonStreamingCreateParams,
|
|
769
|
+
buildStreamingCreateParams,
|
|
770
|
+
mapFinishReason,
|
|
771
|
+
extractThinking,
|
|
481
772
|
streamWithSegments
|
|
482
773
|
};
|
|
483
|
-
//# sourceMappingURL=chunk-
|
|
774
|
+
//# sourceMappingURL=chunk-D4ZLSV6P.js.map
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
+
buildNonStreamingCreateParams,
|
|
3
|
+
buildStreamingCreateParams,
|
|
4
|
+
extractThinking,
|
|
2
5
|
getBackendCapabilities,
|
|
3
|
-
getModelProfile
|
|
4
|
-
|
|
6
|
+
getModelProfile,
|
|
7
|
+
mapFinishReason
|
|
8
|
+
} from "./chunk-D4ZLSV6P.js";
|
|
5
9
|
import {
|
|
6
|
-
describeImageFromDataUrl,
|
|
7
10
|
ensureVisionFallbackConfigLoaded
|
|
8
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-CJNQGEYG.js";
|
|
9
12
|
import {
|
|
10
13
|
logger
|
|
11
14
|
} from "./chunk-PNBH3RAX.js";
|
|
@@ -138,286 +141,6 @@ var LLMError = class extends OpenFoxError {
|
|
|
138
141
|
}
|
|
139
142
|
};
|
|
140
143
|
|
|
141
|
-
// src/server/llm/client-pure.ts
|
|
142
|
-
function buildAttachmentContent(msgContent, attachments, modelSupportsVision) {
|
|
143
|
-
const content = [];
|
|
144
|
-
if (msgContent?.trim()) {
|
|
145
|
-
content.push({ type: "text", text: msgContent });
|
|
146
|
-
}
|
|
147
|
-
for (const attachment of attachments) {
|
|
148
|
-
content.push(convertAttachmentSync(attachment, modelSupportsVision));
|
|
149
|
-
}
|
|
150
|
-
return content;
|
|
151
|
-
}
|
|
152
|
-
async function convertMessagesWithOptions(messages, profile, visionFallbackEnabled, signal, onVisionFallbackStart, onVisionFallbackDone) {
|
|
153
|
-
const modelSupportsVision = profile.supportsVision ?? false;
|
|
154
|
-
const options = {
|
|
155
|
-
modelSupportsVision,
|
|
156
|
-
visionFallbackEnabled,
|
|
157
|
-
signal,
|
|
158
|
-
onVisionFallbackStart,
|
|
159
|
-
onVisionFallbackDone
|
|
160
|
-
};
|
|
161
|
-
return needsVisionFallback(messages, modelSupportsVision, visionFallbackEnabled) ? await convertMessagesWithFallback(messages, options) : convertMessages(messages, { modelSupportsVision, visionFallbackEnabled: false });
|
|
162
|
-
}
|
|
163
|
-
function convertToolCalls(toolCalls) {
|
|
164
|
-
return toolCalls.map((toolCall) => ({
|
|
165
|
-
id: toolCall.id,
|
|
166
|
-
type: "function",
|
|
167
|
-
function: {
|
|
168
|
-
name: toolCall.name,
|
|
169
|
-
arguments: JSON.stringify(toolCall.arguments)
|
|
170
|
-
}
|
|
171
|
-
}));
|
|
172
|
-
}
|
|
173
|
-
function convertAttachmentSync(attachment, modelSupportsVision) {
|
|
174
|
-
if (modelSupportsVision) {
|
|
175
|
-
return {
|
|
176
|
-
type: "image_url",
|
|
177
|
-
image_url: { url: attachment.data }
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
return {
|
|
181
|
-
type: "text",
|
|
182
|
-
text: `[Image: ${attachment.filename || "image"}] (vision not supported, cannot describe)`
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
function createAttachmentForConversion(data, filename, id) {
|
|
186
|
-
return {
|
|
187
|
-
data,
|
|
188
|
-
...filename !== void 0 && { filename },
|
|
189
|
-
...id !== void 0 && { id }
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
async function convertAttachmentWithFallback(attachment, options) {
|
|
193
|
-
logger.debug("[VisionFallback] convertAttachmentWithFallback called", { filename: attachment.filename, id: attachment.id, hasCallbacks: !!options.onVisionFallbackStart });
|
|
194
|
-
if (options.modelSupportsVision) {
|
|
195
|
-
logger.debug("[VisionFallback] Model supports vision - passing image directly");
|
|
196
|
-
return {
|
|
197
|
-
type: "image_url",
|
|
198
|
-
image_url: { url: attachment.data }
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
if (!options.visionFallbackEnabled) {
|
|
202
|
-
logger.debug("[VisionFallback] Fallback disabled - returning placeholder");
|
|
203
|
-
return {
|
|
204
|
-
type: "text",
|
|
205
|
-
text: `[Image: ${attachment.filename || "image"}] (vision not supported)`
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
const attachmentId = attachment.id ?? crypto.randomUUID();
|
|
209
|
-
const filename = attachment.filename;
|
|
210
|
-
logger.debug("[VisionFallback] Starting delegation for:", { attachmentId, filename });
|
|
211
|
-
options.onVisionFallbackStart?.(attachmentId, filename);
|
|
212
|
-
const context = filename ? `File: ${filename}` : void 0;
|
|
213
|
-
const description = await describeImageFromDataUrl(attachment.data, { context, signal: options.signal });
|
|
214
|
-
logger.debug("[VisionFallback] Delegation complete:", { attachmentId, descriptionLength: description.length });
|
|
215
|
-
options.onVisionFallbackDone?.(attachmentId, description);
|
|
216
|
-
return {
|
|
217
|
-
type: "text",
|
|
218
|
-
text: `[Image: ${attachment.filename || "image"}] ${description}`
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
async function buildAttachmentContentWithFallback(msgContent, attachments, options) {
|
|
222
|
-
const content = [];
|
|
223
|
-
if (msgContent?.trim()) {
|
|
224
|
-
content.push({ type: "text", text: msgContent });
|
|
225
|
-
}
|
|
226
|
-
for (const attachment of attachments) {
|
|
227
|
-
const convertedContent = await convertAttachmentWithFallback(
|
|
228
|
-
createAttachmentForConversion(attachment.data, attachment.filename, attachment.id),
|
|
229
|
-
options
|
|
230
|
-
);
|
|
231
|
-
content.push(convertedContent);
|
|
232
|
-
}
|
|
233
|
-
return content;
|
|
234
|
-
}
|
|
235
|
-
function convertMessages(messages, options) {
|
|
236
|
-
const filtered = messages.filter((msg) => {
|
|
237
|
-
return !(msg.role === "assistant" && !msg.content?.trim() && (!msg.toolCalls || msg.toolCalls.length === 0));
|
|
238
|
-
});
|
|
239
|
-
return filtered.map((msg) => {
|
|
240
|
-
if (msg.role === "tool") {
|
|
241
|
-
if (msg.attachments && msg.attachments.length > 0) {
|
|
242
|
-
const content = buildAttachmentContent(msg.content, msg.attachments, options.modelSupportsVision);
|
|
243
|
-
return {
|
|
244
|
-
role: "tool",
|
|
245
|
-
content,
|
|
246
|
-
tool_call_id: msg.toolCallId
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
return {
|
|
250
|
-
role: "tool",
|
|
251
|
-
content: msg.content,
|
|
252
|
-
tool_call_id: msg.toolCallId
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
if (msg.role === "assistant" && msg.toolCalls?.length) {
|
|
256
|
-
return {
|
|
257
|
-
role: "assistant",
|
|
258
|
-
content: msg.content || null,
|
|
259
|
-
tool_calls: convertToolCalls(msg.toolCalls)
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
if (msg.role === "user" && msg.attachments && msg.attachments.length > 0) {
|
|
263
|
-
const content = buildAttachmentContent(msg.content, msg.attachments, options.modelSupportsVision);
|
|
264
|
-
return {
|
|
265
|
-
role: "user",
|
|
266
|
-
content
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
return {
|
|
270
|
-
role: msg.role,
|
|
271
|
-
content: msg.content
|
|
272
|
-
};
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
async function convertMessagesWithFallback(messages, options) {
|
|
276
|
-
logger.debug("[VisionFallback] convertMessagesWithFallback called", { messageCount: messages.length });
|
|
277
|
-
const filtered = messages.filter((msg) => {
|
|
278
|
-
return !(msg.role === "assistant" && !msg.content?.trim() && (!msg.toolCalls || msg.toolCalls.length === 0));
|
|
279
|
-
});
|
|
280
|
-
const converted = [];
|
|
281
|
-
for (const msg of filtered) {
|
|
282
|
-
if (msg.role === "tool") {
|
|
283
|
-
if (msg.attachments && msg.attachments.length > 0) {
|
|
284
|
-
const content = await buildAttachmentContentWithFallback(msg.content, msg.attachments, options);
|
|
285
|
-
converted.push({
|
|
286
|
-
role: "tool",
|
|
287
|
-
content,
|
|
288
|
-
tool_call_id: msg.toolCallId
|
|
289
|
-
});
|
|
290
|
-
} else {
|
|
291
|
-
converted.push({
|
|
292
|
-
role: "tool",
|
|
293
|
-
content: msg.content,
|
|
294
|
-
tool_call_id: msg.toolCallId
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
continue;
|
|
298
|
-
}
|
|
299
|
-
if (msg.role === "assistant" && msg.toolCalls?.length) {
|
|
300
|
-
converted.push({
|
|
301
|
-
role: "assistant",
|
|
302
|
-
content: msg.content || null,
|
|
303
|
-
tool_calls: convertToolCalls(msg.toolCalls)
|
|
304
|
-
});
|
|
305
|
-
continue;
|
|
306
|
-
}
|
|
307
|
-
if (msg.role === "user" && msg.attachments && msg.attachments.length > 0) {
|
|
308
|
-
const content = await buildAttachmentContentWithFallback(msg.content, msg.attachments, options);
|
|
309
|
-
converted.push({
|
|
310
|
-
role: "user",
|
|
311
|
-
content
|
|
312
|
-
});
|
|
313
|
-
continue;
|
|
314
|
-
}
|
|
315
|
-
converted.push({
|
|
316
|
-
role: msg.role,
|
|
317
|
-
content: msg.content
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
return converted;
|
|
321
|
-
}
|
|
322
|
-
function convertTools(tools) {
|
|
323
|
-
return tools.map((tool) => ({
|
|
324
|
-
type: "function",
|
|
325
|
-
function: {
|
|
326
|
-
name: tool.function.name,
|
|
327
|
-
description: tool.function.description,
|
|
328
|
-
parameters: tool.function.parameters
|
|
329
|
-
}
|
|
330
|
-
}));
|
|
331
|
-
}
|
|
332
|
-
function needsVisionFallback(messages, modelSupportsVision, visionFallbackEnabled) {
|
|
333
|
-
const hasAttachments = messages.some(
|
|
334
|
-
(msg) => msg.attachments && msg.attachments.length > 0 || msg.role === "tool" && msg.attachments && msg.attachments.length > 0
|
|
335
|
-
);
|
|
336
|
-
const result = hasAttachments && !modelSupportsVision && visionFallbackEnabled;
|
|
337
|
-
logger.debug("[VisionFallback] needsVisionFallback check", {
|
|
338
|
-
hasAttachments,
|
|
339
|
-
modelSupportsVision,
|
|
340
|
-
visionFallbackEnabled,
|
|
341
|
-
result
|
|
342
|
-
});
|
|
343
|
-
return result;
|
|
344
|
-
}
|
|
345
|
-
async function buildChatCompletionCreateParams(model, request, profile, capabilities, disableThinking, visionFallbackEnabled, isStreaming, onVisionFallbackStart, onVisionFallbackDone) {
|
|
346
|
-
const convertedMessages = await convertMessagesWithOptions(
|
|
347
|
-
request.messages,
|
|
348
|
-
profile,
|
|
349
|
-
visionFallbackEnabled,
|
|
350
|
-
request.signal,
|
|
351
|
-
onVisionFallbackStart,
|
|
352
|
-
onVisionFallbackDone
|
|
353
|
-
);
|
|
354
|
-
const temperature = request.temperature ?? profile.temperature;
|
|
355
|
-
const maxTokens = request.maxTokens ?? profile.defaultMaxTokens;
|
|
356
|
-
const topP = profile.topP;
|
|
357
|
-
const topK = capabilities.supportsTopK ? profile.topK : void 0;
|
|
358
|
-
const params = {
|
|
359
|
-
model,
|
|
360
|
-
messages: convertedMessages,
|
|
361
|
-
...request.tools ? { tools: convertTools(request.tools) } : {},
|
|
362
|
-
...request.toolChoice ? { tool_choice: request.toolChoice } : {},
|
|
363
|
-
temperature,
|
|
364
|
-
max_tokens: maxTokens,
|
|
365
|
-
top_p: topP,
|
|
366
|
-
stream: isStreaming,
|
|
367
|
-
...isStreaming ? { stream_options: { include_usage: true } } : {}
|
|
368
|
-
};
|
|
369
|
-
if (topK !== void 0) {
|
|
370
|
-
;
|
|
371
|
-
params["top_k"] = topK;
|
|
372
|
-
}
|
|
373
|
-
const shouldDisableThinking = isStreaming ? disableThinking || request.disableThinking : disableThinking;
|
|
374
|
-
if (capabilities.supportsChatTemplateKwargs && profile.supportsReasoning && shouldDisableThinking) {
|
|
375
|
-
;
|
|
376
|
-
params["chat_template_kwargs"] = { enable_thinking: false };
|
|
377
|
-
}
|
|
378
|
-
const modelParams = {
|
|
379
|
-
...temperature !== void 0 && { temperature },
|
|
380
|
-
...topP !== void 0 && { topP },
|
|
381
|
-
...topK !== void 0 && { topK },
|
|
382
|
-
...maxTokens !== void 0 && { maxTokens }
|
|
383
|
-
};
|
|
384
|
-
return { params, modelParams };
|
|
385
|
-
}
|
|
386
|
-
async function buildCreateParamsFromInput(input, isStreaming) {
|
|
387
|
-
const { model, request, profile, capabilities, disableThinking, visionFallbackEnabled = false, onVisionFallbackStart, onVisionFallbackDone } = input;
|
|
388
|
-
return buildChatCompletionCreateParams(model, request, profile, capabilities, !!disableThinking, visionFallbackEnabled, isStreaming, onVisionFallbackStart, onVisionFallbackDone);
|
|
389
|
-
}
|
|
390
|
-
var buildNonStreamingCreateParams = (input) => buildCreateParamsFromInput(input, false);
|
|
391
|
-
var buildStreamingCreateParams = (input) => buildCreateParamsFromInput(input, true);
|
|
392
|
-
function mapFinishReason(reason) {
|
|
393
|
-
switch (reason) {
|
|
394
|
-
case "stop":
|
|
395
|
-
return "stop";
|
|
396
|
-
case "tool_calls":
|
|
397
|
-
return "tool_calls";
|
|
398
|
-
case "length":
|
|
399
|
-
return "length";
|
|
400
|
-
case "content_filter":
|
|
401
|
-
return "content_filter";
|
|
402
|
-
default:
|
|
403
|
-
return "stop";
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
function extractThinking(content) {
|
|
407
|
-
const thinkRegex = /<think>([\s\S]*?)<\/think>/g;
|
|
408
|
-
let thinkingContent = "";
|
|
409
|
-
let cleanContent = content;
|
|
410
|
-
let match;
|
|
411
|
-
while ((match = thinkRegex.exec(content)) !== null) {
|
|
412
|
-
thinkingContent += match[1];
|
|
413
|
-
cleanContent = cleanContent.replace(match[0], "");
|
|
414
|
-
}
|
|
415
|
-
return {
|
|
416
|
-
content: cleanContent.trim(),
|
|
417
|
-
thinkingContent: thinkingContent.trim() || null
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
|
-
|
|
421
144
|
// src/server/llm/client.ts
|
|
422
145
|
function createLLMClient(config, initialBackend = "unknown") {
|
|
423
146
|
const baseURL = config.llm.baseUrl.includes("/v1") ? config.llm.baseUrl : `${config.llm.baseUrl}/v1`;
|
|
@@ -468,7 +191,7 @@ function createLLMClient(config, initialBackend = "unknown") {
|
|
|
468
191
|
try {
|
|
469
192
|
const shouldDisableThinking = disableThinking || request.disableThinking === true;
|
|
470
193
|
await ensureVisionFallbackConfigLoaded();
|
|
471
|
-
const { isVisionFallbackEnabled } = await import("./vision-fallback-
|
|
194
|
+
const { isVisionFallbackEnabled } = await import("./vision-fallback-QJ26DCEF.js");
|
|
472
195
|
const paramsOptions = {
|
|
473
196
|
model,
|
|
474
197
|
request,
|
|
@@ -546,7 +269,7 @@ function createLLMClient(config, initialBackend = "unknown") {
|
|
|
546
269
|
});
|
|
547
270
|
try {
|
|
548
271
|
await ensureVisionFallbackConfigLoaded();
|
|
549
|
-
const { isVisionFallbackEnabled } = await import("./vision-fallback-
|
|
272
|
+
const { isVisionFallbackEnabled } = await import("./vision-fallback-QJ26DCEF.js");
|
|
550
273
|
const shouldDisableThinking = disableThinking || request.disableThinking === true;
|
|
551
274
|
const createParams = await buildStreamingCreateParams({
|
|
552
275
|
model,
|
|
@@ -760,4 +483,4 @@ export {
|
|
|
760
483
|
setLlmStatus,
|
|
761
484
|
clearModelCache
|
|
762
485
|
};
|
|
763
|
-
//# sourceMappingURL=chunk-
|
|
486
|
+
//# sourceMappingURL=chunk-KSASIV4B.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
detectModel
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-KSASIV4B.js";
|
|
4
4
|
import {
|
|
5
5
|
detectBackend
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-D4ZLSV6P.js";
|
|
7
7
|
import {
|
|
8
8
|
getGlobalConfigPath
|
|
9
9
|
} from "./chunk-R4HADRYO.js";
|
|
@@ -386,4 +386,4 @@ export {
|
|
|
386
386
|
activateProvider,
|
|
387
387
|
mergeConfigs
|
|
388
388
|
};
|
|
389
|
-
//# sourceMappingURL=chunk-
|
|
389
|
+
//# sourceMappingURL=chunk-P6GUT2QQ.js.map
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
createLLMClient,
|
|
4
4
|
detectModel,
|
|
5
5
|
setLlmStatus
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-KSASIV4B.js";
|
|
7
7
|
import {
|
|
8
8
|
detectBackend
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-D4ZLSV6P.js";
|
|
10
10
|
import {
|
|
11
11
|
logger
|
|
12
12
|
} from "./chunk-PNBH3RAX.js";
|
|
@@ -457,4 +457,4 @@ export {
|
|
|
457
457
|
parseDefaultModelSelection,
|
|
458
458
|
createProviderManager
|
|
459
459
|
};
|
|
460
|
-
//# sourceMappingURL=chunk-
|
|
460
|
+
//# sourceMappingURL=chunk-PYBB34ZK.js.map
|
package/dist/cli/dev.js
CHANGED