@aituber-onair/chat 0.37.0 → 0.38.0
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.ja.md +45 -1
- package/README.md +44 -1
- package/dist/cjs/constants/openai.d.ts +2 -1
- package/dist/cjs/constants/openai.d.ts.map +1 -1
- package/dist/cjs/constants/openai.js +3 -4
- package/dist/cjs/constants/openai.js.map +1 -1
- package/dist/cjs/services/providers/gemini/GeminiChatService.d.ts +5 -0
- package/dist/cjs/services/providers/gemini/GeminiChatService.d.ts.map +1 -1
- package/dist/cjs/services/providers/gemini/GeminiChatService.js +22 -6
- package/dist/cjs/services/providers/gemini/GeminiChatService.js.map +1 -1
- package/dist/cjs/services/providers/openai/OpenAIChatServiceProvider.d.ts +6 -0
- package/dist/cjs/services/providers/openai/OpenAIChatServiceProvider.d.ts.map +1 -1
- package/dist/cjs/services/providers/openai/OpenAIChatServiceProvider.js +17 -7
- package/dist/cjs/services/providers/openai/OpenAIChatServiceProvider.js.map +1 -1
- package/dist/cjs/services/providers/openai/responsesParser.d.ts +7 -2
- package/dist/cjs/services/providers/openai/responsesParser.d.ts.map +1 -1
- package/dist/cjs/services/providers/openai/responsesParser.js +9 -7
- package/dist/cjs/services/providers/openai/responsesParser.js.map +1 -1
- package/dist/cjs/services/providers/openrouter/OpenRouterChatService.d.ts.map +1 -1
- package/dist/cjs/services/providers/openrouter/OpenRouterChatService.js +7 -5
- package/dist/cjs/services/providers/openrouter/OpenRouterChatService.js.map +1 -1
- package/dist/cjs/utils/index.d.ts +1 -0
- package/dist/cjs/utils/index.d.ts.map +1 -1
- package/dist/cjs/utils/index.js +1 -0
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/cjs/utils/mcpSchemaFetcher.d.ts +20 -0
- package/dist/cjs/utils/mcpSchemaFetcher.d.ts.map +1 -1
- package/dist/cjs/utils/mcpSchemaFetcher.js +60 -44
- package/dist/cjs/utils/mcpSchemaFetcher.js.map +1 -1
- package/dist/cjs/utils/openaiCompatibleSse.d.ts +3 -2
- package/dist/cjs/utils/openaiCompatibleSse.d.ts.map +1 -1
- package/dist/cjs/utils/openaiCompatibleSse.js +4 -3
- package/dist/cjs/utils/openaiCompatibleSse.js.map +1 -1
- package/dist/cjs/utils/safeJsonParse.d.ts +4 -0
- package/dist/cjs/utils/safeJsonParse.d.ts.map +1 -0
- package/dist/cjs/utils/safeJsonParse.js +21 -0
- package/dist/cjs/utils/safeJsonParse.js.map +1 -0
- package/dist/esm/constants/openai.d.ts +2 -1
- package/dist/esm/constants/openai.d.ts.map +1 -1
- package/dist/esm/constants/openai.js +3 -4
- package/dist/esm/constants/openai.js.map +1 -1
- package/dist/esm/services/providers/gemini/GeminiChatService.d.ts +5 -0
- package/dist/esm/services/providers/gemini/GeminiChatService.d.ts.map +1 -1
- package/dist/esm/services/providers/gemini/GeminiChatService.js +22 -6
- package/dist/esm/services/providers/gemini/GeminiChatService.js.map +1 -1
- package/dist/esm/services/providers/openai/OpenAIChatServiceProvider.d.ts +6 -0
- package/dist/esm/services/providers/openai/OpenAIChatServiceProvider.d.ts.map +1 -1
- package/dist/esm/services/providers/openai/OpenAIChatServiceProvider.js +17 -7
- package/dist/esm/services/providers/openai/OpenAIChatServiceProvider.js.map +1 -1
- package/dist/esm/services/providers/openai/responsesParser.d.ts +7 -2
- package/dist/esm/services/providers/openai/responsesParser.d.ts.map +1 -1
- package/dist/esm/services/providers/openai/responsesParser.js +9 -7
- package/dist/esm/services/providers/openai/responsesParser.js.map +1 -1
- package/dist/esm/services/providers/openrouter/OpenRouterChatService.d.ts.map +1 -1
- package/dist/esm/services/providers/openrouter/OpenRouterChatService.js +7 -5
- package/dist/esm/services/providers/openrouter/OpenRouterChatService.js.map +1 -1
- package/dist/esm/utils/index.d.ts +1 -0
- package/dist/esm/utils/index.d.ts.map +1 -1
- package/dist/esm/utils/index.js +1 -0
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/esm/utils/mcpSchemaFetcher.d.ts +20 -0
- package/dist/esm/utils/mcpSchemaFetcher.d.ts.map +1 -1
- package/dist/esm/utils/mcpSchemaFetcher.js +60 -44
- package/dist/esm/utils/mcpSchemaFetcher.js.map +1 -1
- package/dist/esm/utils/openaiCompatibleSse.d.ts +3 -2
- package/dist/esm/utils/openaiCompatibleSse.d.ts.map +1 -1
- package/dist/esm/utils/openaiCompatibleSse.js +4 -3
- package/dist/esm/utils/openaiCompatibleSse.js.map +1 -1
- package/dist/esm/utils/safeJsonParse.d.ts +4 -0
- package/dist/esm/utils/safeJsonParse.d.ts.map +1 -0
- package/dist/esm/utils/safeJsonParse.js +16 -0
- package/dist/esm/utils/safeJsonParse.js.map +1 -0
- package/dist/umd/aituber-onair-chat.js +142 -72
- package/dist/umd/aituber-onair-chat.min.js +10 -10
- package/package.json +1 -1
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const safeJsonParse = (payload, fallback, onJsonError) => {
|
|
2
|
+
try {
|
|
3
|
+
return JSON.parse(payload);
|
|
4
|
+
}
|
|
5
|
+
catch (error) {
|
|
6
|
+
onJsonError?.(payload, error);
|
|
7
|
+
return fallback;
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
export const safeParseToolCallInput = (payload, onJsonError) => {
|
|
11
|
+
if (!payload) {
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
return safeJsonParse(payload, {}, onJsonError);
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=safeJsonParse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safeJsonParse.js","sourceRoot":"","sources":["../../../src/utils/safeJsonParse.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,OAAe,EACf,QAAW,EACX,WAAmC,EAChC,EAAE;IACL,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAM,CAAC;IAClC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,WAAW,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC9B,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,OAA2B,EAC3B,WAAmC,EAC9B,EAAE;IACP,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,aAAa,CAAC,OAAO,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;AACjD,CAAC,CAAC"}
|
|
@@ -213,6 +213,8 @@ var AITuberOnAirChat = (() => {
|
|
|
213
213
|
refreshOpenRouterFreeModels: () => refreshOpenRouterFreeModels,
|
|
214
214
|
resolveVisionModel: () => resolveVisionModel,
|
|
215
215
|
runOnceText: () => runOnceText,
|
|
216
|
+
safeJsonParse: () => safeJsonParse,
|
|
217
|
+
safeParseToolCallInput: () => safeParseToolCallInput,
|
|
216
218
|
screenplayToText: () => screenplayToText,
|
|
217
219
|
textToScreenplay: () => textToScreenplay,
|
|
218
220
|
textsToScreenplay: () => textsToScreenplay
|
|
@@ -286,7 +288,7 @@ var AITuberOnAirChat = (() => {
|
|
|
286
288
|
return model !== MODEL_GPT_5_4_PRO;
|
|
287
289
|
}
|
|
288
290
|
function getDefaultReasoningEffortForGPT5Model(model) {
|
|
289
|
-
if (model
|
|
291
|
+
if (allowsReasoningNone(model)) {
|
|
290
292
|
return "none";
|
|
291
293
|
}
|
|
292
294
|
return "medium";
|
|
@@ -836,6 +838,22 @@ If it's in another language, summarize in that language.
|
|
|
836
838
|
return StreamTextAccumulator.getFullText(blocks);
|
|
837
839
|
}
|
|
838
840
|
|
|
841
|
+
// src/utils/safeJsonParse.ts
|
|
842
|
+
var safeJsonParse = (payload, fallback, onJsonError) => {
|
|
843
|
+
try {
|
|
844
|
+
return JSON.parse(payload);
|
|
845
|
+
} catch (error) {
|
|
846
|
+
onJsonError?.(payload, error);
|
|
847
|
+
return fallback;
|
|
848
|
+
}
|
|
849
|
+
};
|
|
850
|
+
var safeParseToolCallInput = (payload, onJsonError) => {
|
|
851
|
+
if (!payload) {
|
|
852
|
+
return {};
|
|
853
|
+
}
|
|
854
|
+
return safeJsonParse(payload, {}, onJsonError);
|
|
855
|
+
};
|
|
856
|
+
|
|
839
857
|
// src/utils/openaiCompatibleSse.ts
|
|
840
858
|
var parseJsonPayload = (payload, onJsonError) => {
|
|
841
859
|
try {
|
|
@@ -943,7 +961,7 @@ If it's in another language, summarize in that language.
|
|
|
943
961
|
type: "tool_use",
|
|
944
962
|
id: e.id,
|
|
945
963
|
name: e.name,
|
|
946
|
-
input:
|
|
964
|
+
input: safeParseToolCallInput(e.args, options.onJsonError)
|
|
947
965
|
}));
|
|
948
966
|
const blocks = [...textBlocks, ...toolBlocks];
|
|
949
967
|
return {
|
|
@@ -954,7 +972,7 @@ If it's in another language, summarize in that language.
|
|
|
954
972
|
usage
|
|
955
973
|
};
|
|
956
974
|
}
|
|
957
|
-
function parseOpenAICompatibleOneShot(data) {
|
|
975
|
+
function parseOpenAICompatibleOneShot(data, options = {}) {
|
|
958
976
|
const choice = data?.choices?.[0];
|
|
959
977
|
const blocks = [];
|
|
960
978
|
if (choice?.message?.tool_calls?.length) {
|
|
@@ -963,7 +981,10 @@ If it's in another language, summarize in that language.
|
|
|
963
981
|
type: "tool_use",
|
|
964
982
|
id: c.id,
|
|
965
983
|
name: c.function?.name,
|
|
966
|
-
input:
|
|
984
|
+
input: safeParseToolCallInput(
|
|
985
|
+
c.function?.arguments,
|
|
986
|
+
options.onJsonError
|
|
987
|
+
)
|
|
967
988
|
})
|
|
968
989
|
);
|
|
969
990
|
} else {
|
|
@@ -1755,7 +1776,7 @@ If it's in another language, summarize in that language.
|
|
|
1755
1776
|
};
|
|
1756
1777
|
|
|
1757
1778
|
// src/services/providers/openai/responsesParser.ts
|
|
1758
|
-
async function parseOpenAIResponsesStream(res, onPartial) {
|
|
1779
|
+
async function parseOpenAIResponsesStream(res, onPartial, options = {}) {
|
|
1759
1780
|
const reader = res.body.getReader();
|
|
1760
1781
|
const dec = new TextDecoder();
|
|
1761
1782
|
const textBlocks = [];
|
|
@@ -1787,6 +1808,7 @@ If it's in another language, summarize in that language.
|
|
|
1787
1808
|
onPartial,
|
|
1788
1809
|
textBlocks,
|
|
1789
1810
|
toolCallsMap,
|
|
1811
|
+
options,
|
|
1790
1812
|
(metadata) => {
|
|
1791
1813
|
if (metadata.responseStatus !== void 0) {
|
|
1792
1814
|
responseStatus = metadata.responseStatus;
|
|
@@ -1799,7 +1821,8 @@ If it's in another language, summarize in that language.
|
|
|
1799
1821
|
}
|
|
1800
1822
|
}
|
|
1801
1823
|
);
|
|
1802
|
-
} catch {
|
|
1824
|
+
} catch (error) {
|
|
1825
|
+
options.onJsonError?.(eventData, error);
|
|
1803
1826
|
console.warn("Failed to parse SSE data:", eventData);
|
|
1804
1827
|
}
|
|
1805
1828
|
eventType = "";
|
|
@@ -1824,7 +1847,7 @@ If it's in another language, summarize in that language.
|
|
|
1824
1847
|
usage
|
|
1825
1848
|
};
|
|
1826
1849
|
}
|
|
1827
|
-
function handleResponsesSSEEvent(eventType, data, onPartial, textBlocks, toolCallsMap, onMetadata) {
|
|
1850
|
+
function handleResponsesSSEEvent(eventType, data, onPartial, textBlocks, toolCallsMap, options, onMetadata) {
|
|
1828
1851
|
switch (eventType) {
|
|
1829
1852
|
case "response.output_item.added":
|
|
1830
1853
|
if (data.item?.type === "message" && Array.isArray(data.item.content)) {
|
|
@@ -1838,7 +1861,10 @@ If it's in another language, summarize in that language.
|
|
|
1838
1861
|
toolCallsMap.set(data.item.id, {
|
|
1839
1862
|
id: data.item.id,
|
|
1840
1863
|
name: data.item.name,
|
|
1841
|
-
input:
|
|
1864
|
+
input: safeParseToolCallInput(
|
|
1865
|
+
data.item.arguments,
|
|
1866
|
+
options.onJsonError
|
|
1867
|
+
)
|
|
1842
1868
|
});
|
|
1843
1869
|
}
|
|
1844
1870
|
break;
|
|
@@ -1881,7 +1907,7 @@ If it's in another language, summarize in that language.
|
|
|
1881
1907
|
usage: response?.usage
|
|
1882
1908
|
};
|
|
1883
1909
|
}
|
|
1884
|
-
function parseOpenAIResponsesOneShot(data) {
|
|
1910
|
+
function parseOpenAIResponsesOneShot(data, options = {}) {
|
|
1885
1911
|
const blocks = [];
|
|
1886
1912
|
if (data.output && Array.isArray(data.output)) {
|
|
1887
1913
|
data.output.forEach((outputItem) => {
|
|
@@ -1897,7 +1923,10 @@ If it's in another language, summarize in that language.
|
|
|
1897
1923
|
type: "tool_use",
|
|
1898
1924
|
id: outputItem.id,
|
|
1899
1925
|
name: outputItem.name,
|
|
1900
|
-
input:
|
|
1926
|
+
input: safeParseToolCallInput(
|
|
1927
|
+
outputItem.arguments,
|
|
1928
|
+
options.onJsonError
|
|
1929
|
+
)
|
|
1901
1930
|
});
|
|
1902
1931
|
}
|
|
1903
1932
|
});
|
|
@@ -2414,6 +2443,20 @@ If it's in another language, summarize in that language.
|
|
|
2414
2443
|
};
|
|
2415
2444
|
|
|
2416
2445
|
// src/utils/mcpSchemaFetcher.ts
|
|
2446
|
+
var createGenericSearchTool = (serverConfig, reason) => ({
|
|
2447
|
+
name: `mcp_${serverConfig.name}_search`,
|
|
2448
|
+
description: reason === "schema-fetch-failed" ? `Search using ${serverConfig.name} MCP server (schema fetch failed)` : `Search using ${serverConfig.name} MCP server`,
|
|
2449
|
+
parameters: {
|
|
2450
|
+
type: "object",
|
|
2451
|
+
properties: {
|
|
2452
|
+
query: {
|
|
2453
|
+
type: "string",
|
|
2454
|
+
description: "Search query"
|
|
2455
|
+
}
|
|
2456
|
+
},
|
|
2457
|
+
required: ["query"]
|
|
2458
|
+
}
|
|
2459
|
+
});
|
|
2417
2460
|
var MCPSchemaFetcher = class {
|
|
2418
2461
|
/**
|
|
2419
2462
|
* Fetch tool schemas from MCP server
|
|
@@ -2421,6 +2464,15 @@ If it's in another language, summarize in that language.
|
|
|
2421
2464
|
* @returns Array of tool definitions
|
|
2422
2465
|
*/
|
|
2423
2466
|
static async fetchToolSchemas(serverConfig) {
|
|
2467
|
+
const result = await this.fetchToolSchemasWithStatus(serverConfig);
|
|
2468
|
+
return result.schemas;
|
|
2469
|
+
}
|
|
2470
|
+
/**
|
|
2471
|
+
* Fetch tool schemas from MCP server with failure metadata.
|
|
2472
|
+
* @param serverConfig MCP server configuration
|
|
2473
|
+
* @returns Tool schemas and failure metadata if fallback was used
|
|
2474
|
+
*/
|
|
2475
|
+
static async fetchToolSchemasWithStatus(serverConfig) {
|
|
2424
2476
|
try {
|
|
2425
2477
|
const headers = {
|
|
2426
2478
|
"Content-Type": "application/json"
|
|
@@ -2435,53 +2487,32 @@ If it's in another language, summarize in that language.
|
|
|
2435
2487
|
);
|
|
2436
2488
|
const toolsData = await response.json();
|
|
2437
2489
|
if (Array.isArray(toolsData.tools)) {
|
|
2438
|
-
return
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2490
|
+
return {
|
|
2491
|
+
schemas: toolsData.tools.map((tool) => ({
|
|
2492
|
+
name: `mcp_${serverConfig.name}_${tool.name}`,
|
|
2493
|
+
description: tool.description || `Tool from ${serverConfig.name} MCP server`,
|
|
2494
|
+
parameters: tool.inputSchema || {
|
|
2495
|
+
type: "object",
|
|
2496
|
+
properties: {},
|
|
2497
|
+
required: []
|
|
2498
|
+
}
|
|
2499
|
+
})),
|
|
2500
|
+
failures: []
|
|
2501
|
+
};
|
|
2447
2502
|
}
|
|
2448
|
-
return
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
parameters: {
|
|
2453
|
-
type: "object",
|
|
2454
|
-
properties: {
|
|
2455
|
-
query: {
|
|
2456
|
-
type: "string",
|
|
2457
|
-
description: "Search query"
|
|
2458
|
-
}
|
|
2459
|
-
},
|
|
2460
|
-
required: ["query"]
|
|
2461
|
-
}
|
|
2462
|
-
}
|
|
2463
|
-
];
|
|
2503
|
+
return {
|
|
2504
|
+
schemas: [createGenericSearchTool(serverConfig)],
|
|
2505
|
+
failures: []
|
|
2506
|
+
};
|
|
2464
2507
|
} catch (error) {
|
|
2465
2508
|
console.warn(
|
|
2466
2509
|
`Failed to fetch MCP schemas from ${serverConfig.name}:`,
|
|
2467
2510
|
error
|
|
2468
2511
|
);
|
|
2469
|
-
return
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
parameters: {
|
|
2474
|
-
type: "object",
|
|
2475
|
-
properties: {
|
|
2476
|
-
query: {
|
|
2477
|
-
type: "string",
|
|
2478
|
-
description: "Search query"
|
|
2479
|
-
}
|
|
2480
|
-
},
|
|
2481
|
-
required: ["query"]
|
|
2482
|
-
}
|
|
2483
|
-
}
|
|
2484
|
-
];
|
|
2512
|
+
return {
|
|
2513
|
+
schemas: [createGenericSearchTool(serverConfig, "schema-fetch-failed")],
|
|
2514
|
+
failures: [{ server: serverConfig, error }]
|
|
2515
|
+
};
|
|
2485
2516
|
}
|
|
2486
2517
|
}
|
|
2487
2518
|
/**
|
|
@@ -2490,16 +2521,28 @@ If it's in another language, summarize in that language.
|
|
|
2490
2521
|
* @returns Array of all tool definitions
|
|
2491
2522
|
*/
|
|
2492
2523
|
static async fetchAllToolSchemas(mcpServers) {
|
|
2524
|
+
const result = await this.fetchAllToolSchemasWithStatus(mcpServers);
|
|
2525
|
+
return result.schemas;
|
|
2526
|
+
}
|
|
2527
|
+
/**
|
|
2528
|
+
* Fetch all tool schemas from multiple MCP servers with failure metadata.
|
|
2529
|
+
* @param mcpServers Array of MCP server configurations
|
|
2530
|
+
* @returns Array of all tool definitions and failures
|
|
2531
|
+
*/
|
|
2532
|
+
static async fetchAllToolSchemasWithStatus(mcpServers) {
|
|
2493
2533
|
const allSchemas = [];
|
|
2534
|
+
const failures = [];
|
|
2494
2535
|
for (const server of mcpServers) {
|
|
2495
2536
|
try {
|
|
2496
|
-
const
|
|
2497
|
-
allSchemas.push(...schemas);
|
|
2537
|
+
const result = await this.fetchToolSchemasWithStatus(server);
|
|
2538
|
+
allSchemas.push(...result.schemas);
|
|
2539
|
+
failures.push(...result.failures);
|
|
2498
2540
|
} catch (error) {
|
|
2499
2541
|
console.error(`Failed to fetch schemas from ${server.name}:`, error);
|
|
2542
|
+
failures.push({ server, error });
|
|
2500
2543
|
}
|
|
2501
2544
|
}
|
|
2502
|
-
return allSchemas;
|
|
2545
|
+
return { schemas: allSchemas, failures };
|
|
2503
2546
|
}
|
|
2504
2547
|
};
|
|
2505
2548
|
|
|
@@ -2555,7 +2598,7 @@ If it's in another language, summarize in that language.
|
|
|
2555
2598
|
{
|
|
2556
2599
|
functionResponse: {
|
|
2557
2600
|
name: funcName,
|
|
2558
|
-
response: normalizeToolResult(
|
|
2601
|
+
response: normalizeToolResult(safeJsonParse2(msg.content))
|
|
2559
2602
|
}
|
|
2560
2603
|
}
|
|
2561
2604
|
]
|
|
@@ -2602,7 +2645,7 @@ If it's in another language, summarize in that language.
|
|
|
2602
2645
|
functionResponse: {
|
|
2603
2646
|
name: funcName,
|
|
2604
2647
|
response: normalizeToolResult(
|
|
2605
|
-
|
|
2648
|
+
safeJsonParse2(msg.content)
|
|
2606
2649
|
)
|
|
2607
2650
|
}
|
|
2608
2651
|
}
|
|
@@ -2651,7 +2694,7 @@ If it's in another language, summarize in that language.
|
|
|
2651
2694
|
}
|
|
2652
2695
|
return geminiMessages;
|
|
2653
2696
|
}
|
|
2654
|
-
function
|
|
2697
|
+
function safeJsonParse2(str) {
|
|
2655
2698
|
try {
|
|
2656
2699
|
return JSON.parse(str);
|
|
2657
2700
|
} catch {
|
|
@@ -2810,6 +2853,7 @@ If it's in another language, summarize in that language.
|
|
|
2810
2853
|
addMCPServer(serverConfig) {
|
|
2811
2854
|
this.mcpServers.push(serverConfig);
|
|
2812
2855
|
this.mcpSchemasInitialized = false;
|
|
2856
|
+
this.mcpSchemaInitializationError = void 0;
|
|
2813
2857
|
}
|
|
2814
2858
|
/**
|
|
2815
2859
|
* Remove MCP server by name
|
|
@@ -2820,6 +2864,7 @@ If it's in another language, summarize in that language.
|
|
|
2820
2864
|
(server) => server.name !== serverName
|
|
2821
2865
|
);
|
|
2822
2866
|
this.mcpSchemasInitialized = false;
|
|
2867
|
+
this.mcpSchemaInitializationError = void 0;
|
|
2823
2868
|
}
|
|
2824
2869
|
/**
|
|
2825
2870
|
* Check if MCP servers are configured
|
|
@@ -2828,6 +2873,12 @@ If it's in another language, summarize in that language.
|
|
|
2828
2873
|
hasMCPServers() {
|
|
2829
2874
|
return this.mcpServers.length > 0;
|
|
2830
2875
|
}
|
|
2876
|
+
/**
|
|
2877
|
+
* Get the last MCP schema initialization error, if schema fallback was used.
|
|
2878
|
+
*/
|
|
2879
|
+
getMCPSchemaInitializationError() {
|
|
2880
|
+
return this.mcpSchemaInitializationError;
|
|
2881
|
+
}
|
|
2831
2882
|
/**
|
|
2832
2883
|
* Initialize MCP tool schemas by fetching from servers
|
|
2833
2884
|
* @private
|
|
@@ -2840,16 +2891,16 @@ If it's in another language, summarize in that language.
|
|
|
2840
2891
|
const timeoutPromise = new Promise(
|
|
2841
2892
|
(_, reject) => setTimeout(() => reject(new Error("MCP schema fetch timeout")), 5e3)
|
|
2842
2893
|
);
|
|
2843
|
-
const schemasPromise = MCPSchemaFetcher.
|
|
2894
|
+
const schemasPromise = MCPSchemaFetcher.fetchAllToolSchemasWithStatus(
|
|
2844
2895
|
this.mcpServers
|
|
2845
2896
|
);
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
timeoutPromise
|
|
2849
|
-
]);
|
|
2897
|
+
const result = await Promise.race([schemasPromise, timeoutPromise]);
|
|
2898
|
+
this.mcpToolSchemas = result.schemas;
|
|
2850
2899
|
this.mcpSchemasInitialized = true;
|
|
2900
|
+
this.mcpSchemaInitializationError = result.failures[0]?.error;
|
|
2851
2901
|
} catch (error) {
|
|
2852
2902
|
console.warn("Failed to initialize MCP schemas, using fallback:", error);
|
|
2903
|
+
this.mcpSchemaInitializationError = error;
|
|
2853
2904
|
this.mcpToolSchemas = createFallbackMCPToolSchemas(this.mcpServers);
|
|
2854
2905
|
this.mcpSchemasInitialized = true;
|
|
2855
2906
|
}
|
|
@@ -2970,7 +3021,14 @@ If it's in another language, summarize in that language.
|
|
|
2970
3021
|
} catch (e) {
|
|
2971
3022
|
const looksLikeVersionMismatch = /Unknown name|Cannot find field|404/.test(e?.message || "") || e?.status === 404;
|
|
2972
3023
|
if (!requiresV1beta && looksLikeVersionMismatch) {
|
|
2973
|
-
|
|
3024
|
+
try {
|
|
3025
|
+
return await fetchOnce("v1beta", this.adaptKeysForApi(body));
|
|
3026
|
+
} catch (fallbackError) {
|
|
3027
|
+
if (fallbackError instanceof Error) {
|
|
3028
|
+
fallbackError.cause = e;
|
|
3029
|
+
}
|
|
3030
|
+
throw fallbackError;
|
|
3031
|
+
}
|
|
2974
3032
|
}
|
|
2975
3033
|
throw e;
|
|
2976
3034
|
}
|
|
@@ -3895,28 +3953,38 @@ If it's in another language, summarize in that language.
|
|
|
3895
3953
|
}
|
|
3896
3954
|
/**
|
|
3897
3955
|
* Normalize reasoning effort to a model-supported value
|
|
3956
|
+
*
|
|
3957
|
+
* Unsupported values are rounded to the nearest supported level instead of
|
|
3958
|
+
* resetting to the model default, so a low-latency request stays low
|
|
3959
|
+
* (e.g. 'minimal' on GPT-5.4 resolves to 'none', not 'medium') and a
|
|
3960
|
+
* high-effort request stays high (e.g. 'xhigh' on GPT-5.1 resolves to
|
|
3961
|
+
* 'high', not 'none').
|
|
3898
3962
|
*/
|
|
3899
3963
|
normalizeReasoningEffort(modelName, effort) {
|
|
3900
3964
|
if (!effort) {
|
|
3901
3965
|
return void 0;
|
|
3902
3966
|
}
|
|
3903
|
-
if (effort === "none" && !allowsReasoningNone(modelName)) {
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3967
|
+
if (effort === "none" && !allowsReasoningNone(modelName) || effort === "minimal" && !allowsReasoningMinimal(modelName)) {
|
|
3968
|
+
if (effort === "minimal" && allowsReasoningNone(modelName)) {
|
|
3969
|
+
return "none";
|
|
3970
|
+
}
|
|
3971
|
+
if (effort === "none" && allowsReasoningMinimal(modelName)) {
|
|
3972
|
+
return "minimal";
|
|
3973
|
+
}
|
|
3974
|
+
return allowsReasoningLow(modelName) ? "low" : "medium";
|
|
3908
3975
|
}
|
|
3909
3976
|
if (effort === "low" && !allowsReasoningLow(modelName)) {
|
|
3910
|
-
return
|
|
3977
|
+
return "medium";
|
|
3911
3978
|
}
|
|
3912
3979
|
if (effort === "xhigh" && !allowsReasoningXHigh(modelName)) {
|
|
3913
|
-
return
|
|
3980
|
+
return "high";
|
|
3914
3981
|
}
|
|
3915
3982
|
return effort;
|
|
3916
3983
|
}
|
|
3917
3984
|
};
|
|
3918
3985
|
|
|
3919
3986
|
// src/services/providers/openrouter/OpenRouterChatService.ts
|
|
3987
|
+
var isTokenLimitUnsupportedModel = (model) => model.trim() === MODEL_GPT_OSS_20B_FREE;
|
|
3920
3988
|
var OpenRouterChatService = class {
|
|
3921
3989
|
/**
|
|
3922
3990
|
* Constructor
|
|
@@ -4110,10 +4178,12 @@ If it's in another language, summarize in that language.
|
|
|
4110
4178
|
stream
|
|
4111
4179
|
};
|
|
4112
4180
|
const tokenLimit = maxTokens !== void 0 ? maxTokens : getMaxTokensForResponseLength(this.responseLength);
|
|
4113
|
-
if (tokenLimit) {
|
|
4181
|
+
if (tokenLimit && isTokenLimitUnsupportedModel(model)) {
|
|
4114
4182
|
console.warn(
|
|
4115
|
-
`OpenRouter: Token limits are not supported for
|
|
4183
|
+
`OpenRouter: Token limits are not supported for ${model} due to known issues. Using unlimited tokens instead.`
|
|
4116
4184
|
);
|
|
4185
|
+
} else if (tokenLimit) {
|
|
4186
|
+
body.max_tokens = tokenLimit;
|
|
4117
4187
|
}
|
|
4118
4188
|
if (this.reasoning_effort !== void 0 || this.includeReasoning !== void 0 || this.reasoningMaxTokens) {
|
|
4119
4189
|
body.reasoning = {};
|