@within-7/minto 0.3.9 → 0.3.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/dist/commands/agents/AgentsCommand.js +459 -655
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/agents/types.js +1 -0
- package/dist/commands/agents/types.js.map +2 -2
- package/dist/commands/agents/utils/fileOperations.js +96 -36
- package/dist/commands/agents/utils/fileOperations.js.map +3 -3
- package/dist/commands/agents/utils/index.js +3 -1
- package/dist/commands/agents/utils/index.js.map +2 -2
- package/dist/commands/context.js +54 -23
- package/dist/commands/context.js.map +2 -2
- package/dist/commands/export.js +673 -93
- package/dist/commands/export.js.map +2 -2
- package/dist/commands/language.js +19 -46
- package/dist/commands/language.js.map +2 -2
- package/dist/commands/mcp-interactive.js +419 -217
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/model.js +415 -66
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/permissions.js +75 -49
- package/dist/commands/permissions.js.map +2 -2
- package/dist/commands/plugin.js +882 -185
- package/dist/commands/plugin.js.map +3 -3
- package/dist/commands/resume.js +1 -1
- package/dist/commands/resume.js.map +1 -1
- package/dist/commands/sandbox.js +168 -70
- package/dist/commands/sandbox.js.map +2 -2
- package/dist/commands/setup.js +593 -107
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/stats.js +188 -131
- package/dist/commands/stats.js.map +2 -2
- package/dist/commands/status.js +75 -13
- package/dist/commands/status.js.map +2 -2
- package/dist/commands/undo.js +138 -174
- package/dist/commands/undo.js.map +2 -2
- package/dist/commands.js.map +1 -1
- package/dist/components/Help.js +165 -32
- package/dist/components/Help.js.map +2 -2
- package/dist/components/InfoPanel/InfoPanel.js +123 -0
- package/dist/components/InfoPanel/InfoPanel.js.map +7 -0
- package/dist/components/InfoPanel/index.js +5 -0
- package/dist/components/InfoPanel/index.js.map +7 -0
- package/dist/components/InfoPanel/types.js +1 -0
- package/dist/components/InfoPanel/types.js.map +7 -0
- package/dist/components/ModelSelector/BrandTextInput.js +43 -0
- package/dist/components/ModelSelector/BrandTextInput.js.map +7 -0
- package/dist/components/ModelSelector/ModelSelector.js +419 -501
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/ModelSelector/WizardContainer.js +45 -0
- package/dist/components/ModelSelector/WizardContainer.js.map +7 -0
- package/dist/components/ModelSelector/index.js +1 -3
- package/dist/components/ModelSelector/index.js.map +2 -2
- package/dist/components/PromptInput.js +5 -5
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/SimpleSelector/SimpleSelector.js +154 -0
- package/dist/components/SimpleSelector/SimpleSelector.js.map +7 -0
- package/dist/components/SimpleSelector/index.js +5 -0
- package/dist/components/SimpleSelector/index.js.map +7 -0
- package/dist/components/SimpleSelector/types.js +1 -0
- package/dist/components/SimpleSelector/types.js.map +7 -0
- package/dist/components/StatusOverlayContent.js +21 -0
- package/dist/components/StatusOverlayContent.js.map +7 -0
- package/dist/components/TabbedListView/ScrollableList.js +31 -5
- package/dist/components/TabbedListView/ScrollableList.js.map +2 -2
- package/dist/components/TabbedListView/TabbedListView.js +122 -47
- package/dist/components/TabbedListView/TabbedListView.js.map +2 -2
- package/dist/core/backupHook.js +29 -0
- package/dist/core/backupHook.js.map +7 -0
- package/dist/core/config/defaults.js +8 -2
- package/dist/core/config/defaults.js.map +2 -2
- package/dist/core/config/schema.js +14 -2
- package/dist/core/config/schema.js.map +2 -2
- package/dist/core/costTracker.js +0 -16
- package/dist/core/costTracker.js.map +2 -2
- package/dist/cost-tracker.js +0 -16
- package/dist/cost-tracker.js.map +2 -2
- package/dist/entrypoints/bootstrap.js +3 -1
- package/dist/entrypoints/bootstrap.js.map +2 -2
- package/dist/entrypoints/cli.js +32 -0
- package/dist/entrypoints/cli.js.map +2 -2
- package/dist/i18n/locales/en.js +300 -1
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +301 -2
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/i18n/types.js.map +1 -1
- package/dist/services/customCommands.js +30 -8
- package/dist/services/customCommands.js.map +2 -2
- package/dist/services/plugins/lspServers.js +1 -1
- package/dist/services/plugins/lspServers.js.map +2 -2
- package/dist/services/plugins/pluginRuntime.js +2 -1
- package/dist/services/plugins/pluginRuntime.js.map +2 -2
- package/dist/services/plugins/pluginValidation.js +10 -3
- package/dist/services/plugins/pluginValidation.js.map +2 -2
- package/dist/services/plugins/skillMarketplace.js +16 -8
- package/dist/services/plugins/skillMarketplace.js.map +2 -2
- package/dist/services/systemReminder.js +17 -6
- package/dist/services/systemReminder.js.map +2 -2
- package/dist/tools/FileEditTool/FileEditTool.js +7 -0
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileWriteTool/FileWriteTool.js +7 -0
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js +7 -0
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +2 -0
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
- package/dist/tools/TaskTool/TaskTool.js +9 -6
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/types/PermissionMode.js.map +1 -1
- package/dist/types/plugin.js +2 -4
- package/dist/types/plugin.js.map +2 -2
- package/dist/utils/agentHookExecutor.js +1 -4
- package/dist/utils/agentHookExecutor.js.map +2 -2
- package/dist/utils/agentLoader.js +67 -13
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/agentMemory.js.map +2 -2
- package/dist/utils/claudeCodeSync.js +439 -0
- package/dist/utils/claudeCodeSync.js.map +7 -0
- package/dist/utils/config.js +1 -23
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/execFileNoThrow.js +2 -1
- package/dist/utils/execFileNoThrow.js.map +2 -2
- package/dist/utils/marketplaceManager.js +80 -43
- package/dist/utils/marketplaceManager.js.map +2 -2
- package/dist/utils/messages.js +2 -2
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/pluginInstaller.js +34 -24
- package/dist/utils/pluginInstaller.js.map +2 -2
- package/dist/utils/pluginLoader.js +48 -25
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/repoFetcher.js +110 -0
- package/dist/utils/repoFetcher.js.map +7 -0
- package/dist/utils/skillLoader.js +18 -6
- package/dist/utils/skillLoader.js.map +2 -2
- package/dist/utils/stringSubstitution.js +4 -5
- package/dist/utils/stringSubstitution.js.map +2 -2
- package/dist/utils/teamConfig.js +153 -13
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/terminal.js +1 -1
- package/dist/utils/terminal.js.map +2 -2
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +6 -6
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import React, { useState, useEffect } from "react";
|
|
2
|
-
import {
|
|
3
|
-
import { getTheme } from "../../utils/theme.js";
|
|
4
|
-
import { Select } from "../CustomSelect/select.js";
|
|
2
|
+
import { Text, useInput } from "ink";
|
|
5
3
|
import { getModelManager } from "../../utils/model.js";
|
|
6
4
|
import { useExitOnCtrlCD } from "../../hooks/useExitOnCtrlCD.js";
|
|
7
5
|
import {
|
|
@@ -10,9 +8,7 @@ import {
|
|
|
10
8
|
setModelPointer
|
|
11
9
|
} from "../../utils/config.js";
|
|
12
10
|
import models, { providers } from "../../constants/models.js";
|
|
13
|
-
import TextInput from "../TextInput.js";
|
|
14
11
|
import OpenAI from "openai";
|
|
15
|
-
import chalk from "chalk";
|
|
16
12
|
import { verifyApiKey } from "../../services/claude.js";
|
|
17
13
|
import { fetchCustomModels } from "../../services/openai.js";
|
|
18
14
|
import {
|
|
@@ -20,24 +16,23 @@ import {
|
|
|
20
16
|
validateGPT5Config
|
|
21
17
|
} from "../../services/gpt5ConnectionTest.js";
|
|
22
18
|
import { SEMANTIC_COLORS } from "../../constants/colors.js";
|
|
23
|
-
import {
|
|
19
|
+
import { t } from "../../i18n/index.js";
|
|
20
|
+
import { SimpleSelector } from "../SimpleSelector/SimpleSelector.js";
|
|
21
|
+
import { InfoPanel } from "../InfoPanel/InfoPanel.js";
|
|
22
|
+
import { BrandTextInput } from "./BrandTextInput.js";
|
|
24
23
|
import {
|
|
25
24
|
CONTEXT_LENGTH_OPTIONS,
|
|
26
25
|
DEFAULT_CONTEXT_LENGTH,
|
|
27
26
|
MAX_TOKENS_OPTIONS,
|
|
28
27
|
DEFAULT_MAX_TOKENS
|
|
29
28
|
} from "./constants.js";
|
|
30
|
-
import { useEscapeNavigation } from "./hooks/index.js";
|
|
31
29
|
function printModelConfig() {
|
|
32
30
|
const config = getGlobalConfig();
|
|
33
31
|
const modelProfiles = config.modelProfiles || [];
|
|
34
32
|
const activeProfiles = modelProfiles.filter((p) => p.isActive);
|
|
35
33
|
if (activeProfiles.length === 0) {
|
|
36
|
-
console.log(chalk.gray(" \u23BF No active model profiles configured"));
|
|
37
34
|
return;
|
|
38
35
|
}
|
|
39
|
-
const profileSummary = activeProfiles.map((p) => `${p.name} (${p.provider}: ${p.modelName})`).join(" | ");
|
|
40
|
-
console.log(chalk.gray(` \u23BF ${profileSummary}`));
|
|
41
36
|
}
|
|
42
37
|
function ModelSelector({
|
|
43
38
|
onDone: onDoneProp,
|
|
@@ -48,12 +43,11 @@ function ModelSelector({
|
|
|
48
43
|
skipModelType = false
|
|
49
44
|
}) {
|
|
50
45
|
const config = getGlobalConfig();
|
|
51
|
-
const theme = getTheme();
|
|
52
46
|
const onDone = () => {
|
|
53
47
|
printModelConfig();
|
|
54
48
|
onDoneProp();
|
|
55
49
|
};
|
|
56
|
-
|
|
50
|
+
useExitOnCtrlCD(() => process.exit(0));
|
|
57
51
|
const getInitialScreen = () => {
|
|
58
52
|
return "provider";
|
|
59
53
|
};
|
|
@@ -305,10 +299,6 @@ function ModelSelector({
|
|
|
305
299
|
}));
|
|
306
300
|
} catch (error) {
|
|
307
301
|
lastError = error;
|
|
308
|
-
console.log(
|
|
309
|
-
`Anthropic API failed for ${provider}, trying OpenAI format:`,
|
|
310
|
-
error
|
|
311
|
-
);
|
|
312
302
|
}
|
|
313
303
|
try {
|
|
314
304
|
const models2 = await fetchCustomModels(baseURL, apiKey);
|
|
@@ -322,10 +312,6 @@ function ModelSelector({
|
|
|
322
312
|
}));
|
|
323
313
|
} catch (error) {
|
|
324
314
|
lastError = error;
|
|
325
|
-
console.log(
|
|
326
|
-
`OpenAI API failed for ${provider}, falling back to manual input:`,
|
|
327
|
-
error
|
|
328
|
-
);
|
|
329
315
|
}
|
|
330
316
|
let errorMessage = `Failed to fetch ${provider} models using both Anthropic and OpenAI API formats`;
|
|
331
317
|
if (lastError) {
|
|
@@ -763,7 +749,6 @@ function ModelSelector({
|
|
|
763
749
|
} else {
|
|
764
750
|
setModelLoadError(`Error loading Ollama models: ${errorMessage}`);
|
|
765
751
|
}
|
|
766
|
-
console.error("Error fetching Ollama models:", error);
|
|
767
752
|
return [];
|
|
768
753
|
}
|
|
769
754
|
}
|
|
@@ -787,7 +772,6 @@ function ModelSelector({
|
|
|
787
772
|
return models2;
|
|
788
773
|
} catch (error) {
|
|
789
774
|
lastError = error instanceof Error ? error : new Error(String(error));
|
|
790
|
-
console.log(`Model fetch attempt ${attempt} failed:`, lastError.message);
|
|
791
775
|
if (attempt === MAX_RETRIES) {
|
|
792
776
|
break;
|
|
793
777
|
}
|
|
@@ -915,7 +899,6 @@ function ModelSelector({
|
|
|
915
899
|
navigateTo("model");
|
|
916
900
|
return fetchedModels;
|
|
917
901
|
} catch (error) {
|
|
918
|
-
console.error("Error fetching models:", error);
|
|
919
902
|
throw error;
|
|
920
903
|
} finally {
|
|
921
904
|
setIsLoadingModels(false);
|
|
@@ -927,8 +910,7 @@ function ModelSelector({
|
|
|
927
910
|
navigateTo("resourceName");
|
|
928
911
|
return;
|
|
929
912
|
}
|
|
930
|
-
fetchModelsWithRetry().catch((
|
|
931
|
-
console.error("Final error after retries:", error);
|
|
913
|
+
fetchModelsWithRetry().catch(() => {
|
|
932
914
|
});
|
|
933
915
|
}
|
|
934
916
|
function handleResourceNameSubmit(name) {
|
|
@@ -1057,9 +1039,6 @@ function ModelSelector({
|
|
|
1057
1039
|
if (isOpenAICompatible) {
|
|
1058
1040
|
const isGPT5 = selectedModel?.toLowerCase().includes("gpt-5");
|
|
1059
1041
|
if (isGPT5) {
|
|
1060
|
-
console.log(
|
|
1061
|
-
`\u{1F680} Using specialized GPT-5 connection test for model: ${selectedModel}`
|
|
1062
|
-
);
|
|
1063
1042
|
const configValidation = validateGPT5Config({
|
|
1064
1043
|
model: selectedModel,
|
|
1065
1044
|
apiKey,
|
|
@@ -1153,18 +1132,11 @@ function ModelSelector({
|
|
|
1153
1132
|
stream: false
|
|
1154
1133
|
};
|
|
1155
1134
|
if (selectedModel && selectedModel.toLowerCase().includes("gpt-5")) {
|
|
1156
|
-
console.log(`Applying GPT-5 parameter fix for model: ${selectedModel}`);
|
|
1157
1135
|
if (testPayload.max_tokens) {
|
|
1158
1136
|
testPayload.max_completion_tokens = testPayload.max_tokens;
|
|
1159
1137
|
delete testPayload.max_tokens;
|
|
1160
|
-
console.log(
|
|
1161
|
-
`Transformed max_tokens \u2192 max_completion_tokens: ${testPayload.max_completion_tokens}`
|
|
1162
|
-
);
|
|
1163
1138
|
}
|
|
1164
1139
|
if (testPayload.temperature !== void 0 && testPayload.temperature !== 1) {
|
|
1165
|
-
console.log(
|
|
1166
|
-
`Adjusting temperature from ${testPayload.temperature} to 1 for GPT-5`
|
|
1167
|
-
);
|
|
1168
1140
|
testPayload.temperature = 1;
|
|
1169
1141
|
}
|
|
1170
1142
|
}
|
|
@@ -1184,10 +1156,6 @@ function ModelSelector({
|
|
|
1184
1156
|
});
|
|
1185
1157
|
if (response.ok) {
|
|
1186
1158
|
const data = await response.json();
|
|
1187
|
-
console.log(
|
|
1188
|
-
"[DEBUG] Connection test response:",
|
|
1189
|
-
JSON.stringify(data, null, 2)
|
|
1190
|
-
);
|
|
1191
1159
|
let responseContent = "";
|
|
1192
1160
|
if (data.choices && data.choices.length > 0) {
|
|
1193
1161
|
responseContent = data.choices[0]?.message?.content || "";
|
|
@@ -1196,7 +1164,6 @@ function ModelSelector({
|
|
|
1196
1164
|
} else if (data.output) {
|
|
1197
1165
|
responseContent = data.output?.text || data.output || "";
|
|
1198
1166
|
}
|
|
1199
|
-
console.log("[DEBUG] Extracted response content:", responseContent);
|
|
1200
1167
|
const containsYes = responseContent.toLowerCase().includes("yes");
|
|
1201
1168
|
if (containsYes) {
|
|
1202
1169
|
return {
|
|
@@ -1251,9 +1218,6 @@ function ModelSelector({
|
|
|
1251
1218
|
// Fast response for connection test
|
|
1252
1219
|
}
|
|
1253
1220
|
};
|
|
1254
|
-
console.log(`\u{1F527} Testing GPT-5 Responses API for model: ${selectedModel}`);
|
|
1255
|
-
console.log(`\u{1F527} Test URL: ${testURL}`);
|
|
1256
|
-
console.log(`\u{1F527} Test payload:`, JSON.stringify(testPayload, null, 2));
|
|
1257
1221
|
const headers = {
|
|
1258
1222
|
"Content-Type": "application/json",
|
|
1259
1223
|
Authorization: `Bearer ${apiKey}`
|
|
@@ -1266,17 +1230,12 @@ function ModelSelector({
|
|
|
1266
1230
|
});
|
|
1267
1231
|
if (response.ok) {
|
|
1268
1232
|
const data = await response.json();
|
|
1269
|
-
console.log(
|
|
1270
|
-
"[DEBUG] Responses API connection test response:",
|
|
1271
|
-
JSON.stringify(data, null, 2)
|
|
1272
|
-
);
|
|
1273
1233
|
let responseContent = "";
|
|
1274
1234
|
if (data.output_text) {
|
|
1275
1235
|
responseContent = data.output_text;
|
|
1276
1236
|
} else if (data.output) {
|
|
1277
1237
|
responseContent = typeof data.output === "string" ? data.output : data.output.text || "";
|
|
1278
1238
|
}
|
|
1279
|
-
console.log("[DEBUG] Extracted response content:", responseContent);
|
|
1280
1239
|
const containsYes = responseContent.toLowerCase().includes("yes");
|
|
1281
1240
|
if (containsYes) {
|
|
1282
1241
|
return {
|
|
@@ -1296,10 +1255,6 @@ function ModelSelector({
|
|
|
1296
1255
|
} else {
|
|
1297
1256
|
const errorData = await response.json().catch(() => null);
|
|
1298
1257
|
const errorMessage = errorData?.error?.message || errorData?.message || response.statusText;
|
|
1299
|
-
console.log(
|
|
1300
|
-
`\u{1F6A8} GPT-5 Responses API Error (${response.status}):`,
|
|
1301
|
-
errorData
|
|
1302
|
-
);
|
|
1303
1258
|
let details = `Responses API Error: ${errorMessage}`;
|
|
1304
1259
|
if (response.status === 400 && errorMessage.includes("max_tokens")) {
|
|
1305
1260
|
details += "\n\u{1F527} Note: This appears to be a parameter compatibility issue. The fallback to Chat Completions should handle this.";
|
|
@@ -1327,9 +1282,6 @@ function ModelSelector({
|
|
|
1327
1282
|
async function testProviderSpecificEndpoint(baseURL) {
|
|
1328
1283
|
if (selectedProvider === "anthropic" || selectedProvider === "bigdream") {
|
|
1329
1284
|
try {
|
|
1330
|
-
console.log(
|
|
1331
|
-
`[DEBUG] Testing ${selectedProvider} connection using official Anthropic SDK...`
|
|
1332
|
-
);
|
|
1333
1285
|
let testBaseURL = void 0;
|
|
1334
1286
|
if (selectedProvider === "bigdream") {
|
|
1335
1287
|
testBaseURL = baseURL || "https://api-key.info";
|
|
@@ -1357,7 +1309,6 @@ function ModelSelector({
|
|
|
1357
1309
|
};
|
|
1358
1310
|
}
|
|
1359
1311
|
} catch (error) {
|
|
1360
|
-
console.log(`[DEBUG] ${selectedProvider} connection test error:`, error);
|
|
1361
1312
|
return {
|
|
1362
1313
|
success: false,
|
|
1363
1314
|
message: `\u274C ${selectedProvider} connection failed`,
|
|
@@ -1450,10 +1401,15 @@ function ModelSelector({
|
|
|
1450
1401
|
onDone();
|
|
1451
1402
|
}
|
|
1452
1403
|
} else {
|
|
1404
|
+
const prevScreen = screenStack[screenStack.length - 2];
|
|
1405
|
+
if (prevScreen === "modelParams") {
|
|
1406
|
+
const formFields = getFormFieldsForModelParams();
|
|
1407
|
+
const submitIndex = formFields.findIndex((f) => f.name === "submit");
|
|
1408
|
+
setActiveFieldIndex(Math.max(0, submitIndex - 1));
|
|
1409
|
+
}
|
|
1453
1410
|
setScreenStack((prev) => prev.slice(0, -1));
|
|
1454
1411
|
}
|
|
1455
1412
|
};
|
|
1456
|
-
useEscapeNavigation(handleBack, abortController);
|
|
1457
1413
|
function handleCursorOffsetChange(offset) {
|
|
1458
1414
|
setCursorOffset(offset);
|
|
1459
1415
|
}
|
|
@@ -1468,7 +1424,13 @@ function ModelSelector({
|
|
|
1468
1424
|
function handleModelSearchCursorOffsetChange(offset) {
|
|
1469
1425
|
setModelSearchCursorOffset(offset);
|
|
1470
1426
|
}
|
|
1427
|
+
const textScreens = ["apiKey", "baseUrl", "resourceName", "modelInput"];
|
|
1471
1428
|
useInput((input, key) => {
|
|
1429
|
+
if (!textScreens.includes(currentScreen)) return;
|
|
1430
|
+
if (key.escape) {
|
|
1431
|
+
handleBack();
|
|
1432
|
+
return;
|
|
1433
|
+
}
|
|
1472
1434
|
if (currentScreen === "apiKey" && key.return) {
|
|
1473
1435
|
if (apiKey) {
|
|
1474
1436
|
handleApiKeySubmit(apiKey);
|
|
@@ -1480,8 +1442,7 @@ function ModelSelector({
|
|
|
1480
1442
|
navigateTo("modelInput");
|
|
1481
1443
|
return;
|
|
1482
1444
|
}
|
|
1483
|
-
fetchModelsWithRetry().catch((
|
|
1484
|
-
console.error("Final error after retries:", error);
|
|
1445
|
+
fetchModelsWithRetry().catch(() => {
|
|
1485
1446
|
});
|
|
1486
1447
|
return;
|
|
1487
1448
|
}
|
|
@@ -1505,76 +1466,6 @@ function ModelSelector({
|
|
|
1505
1466
|
}
|
|
1506
1467
|
return;
|
|
1507
1468
|
}
|
|
1508
|
-
if (currentScreen === "confirmation" && key.return) {
|
|
1509
|
-
handleConfirmation().catch((error) => {
|
|
1510
|
-
console.error("Error in handleConfirmation:", error);
|
|
1511
|
-
setValidationError(
|
|
1512
|
-
error instanceof Error ? error.message : "Unexpected error occurred"
|
|
1513
|
-
);
|
|
1514
|
-
});
|
|
1515
|
-
return;
|
|
1516
|
-
}
|
|
1517
|
-
if (currentScreen === "connectionTest") {
|
|
1518
|
-
if (key.return) {
|
|
1519
|
-
if (!isTestingConnection && !connectionTestResult) {
|
|
1520
|
-
handleConnectionTest();
|
|
1521
|
-
} else if (connectionTestResult && connectionTestResult.success) {
|
|
1522
|
-
navigateTo("confirmation");
|
|
1523
|
-
} else if (connectionTestResult && !connectionTestResult.success) {
|
|
1524
|
-
handleConnectionTest();
|
|
1525
|
-
}
|
|
1526
|
-
return;
|
|
1527
|
-
}
|
|
1528
|
-
}
|
|
1529
|
-
if (currentScreen === "contextLength") {
|
|
1530
|
-
if (key.return) {
|
|
1531
|
-
handleContextLengthSubmit();
|
|
1532
|
-
return;
|
|
1533
|
-
}
|
|
1534
|
-
if (key.upArrow) {
|
|
1535
|
-
const currentIndex = CONTEXT_LENGTH_OPTIONS.findIndex(
|
|
1536
|
-
(opt) => opt.value === contextLength
|
|
1537
|
-
);
|
|
1538
|
-
const newIndex = currentIndex > 0 ? currentIndex - 1 : currentIndex === -1 ? CONTEXT_LENGTH_OPTIONS.findIndex(
|
|
1539
|
-
(opt) => opt.value === DEFAULT_CONTEXT_LENGTH
|
|
1540
|
-
) || 0 : CONTEXT_LENGTH_OPTIONS.length - 1;
|
|
1541
|
-
setContextLength(CONTEXT_LENGTH_OPTIONS[newIndex].value);
|
|
1542
|
-
return;
|
|
1543
|
-
}
|
|
1544
|
-
if (key.downArrow) {
|
|
1545
|
-
const currentIndex = CONTEXT_LENGTH_OPTIONS.findIndex(
|
|
1546
|
-
(opt) => opt.value === contextLength
|
|
1547
|
-
);
|
|
1548
|
-
const newIndex = currentIndex === -1 ? CONTEXT_LENGTH_OPTIONS.findIndex(
|
|
1549
|
-
(opt) => opt.value === DEFAULT_CONTEXT_LENGTH
|
|
1550
|
-
) || 0 : (currentIndex + 1) % CONTEXT_LENGTH_OPTIONS.length;
|
|
1551
|
-
setContextLength(CONTEXT_LENGTH_OPTIONS[newIndex].value);
|
|
1552
|
-
return;
|
|
1553
|
-
}
|
|
1554
|
-
}
|
|
1555
|
-
if (currentScreen === "apiKey" && (key.ctrl && input === "v" || key.meta && input === "v")) {
|
|
1556
|
-
setModelLoadError(
|
|
1557
|
-
"Please use your terminal's paste functionality or type the API key manually"
|
|
1558
|
-
);
|
|
1559
|
-
return;
|
|
1560
|
-
}
|
|
1561
|
-
if (currentScreen === "modelParams" && key.tab) {
|
|
1562
|
-
const formFields = getFormFieldsForModelParams();
|
|
1563
|
-
setActiveFieldIndex((current) => (current + 1) % formFields.length);
|
|
1564
|
-
return;
|
|
1565
|
-
}
|
|
1566
|
-
if (currentScreen === "modelParams" && key.return) {
|
|
1567
|
-
const formFields = getFormFieldsForModelParams();
|
|
1568
|
-
const currentField = formFields[activeFieldIndex];
|
|
1569
|
-
if (currentField.name === "submit" || activeFieldIndex === formFields.length - 1) {
|
|
1570
|
-
handleModelParamsSubmit();
|
|
1571
|
-
} else if (currentField.component === "select") {
|
|
1572
|
-
setActiveFieldIndex(
|
|
1573
|
-
(current) => Math.min(current + 1, formFields.length - 1)
|
|
1574
|
-
);
|
|
1575
|
-
}
|
|
1576
|
-
return;
|
|
1577
|
-
}
|
|
1578
1469
|
});
|
|
1579
1470
|
function getFormFieldsForModelParams() {
|
|
1580
1471
|
return [
|
|
@@ -1607,433 +1498,460 @@ function ModelSelector({
|
|
|
1607
1498
|
];
|
|
1608
1499
|
}
|
|
1609
1500
|
if (currentScreen === "apiKey") {
|
|
1610
|
-
const
|
|
1611
|
-
|
|
1612
|
-
|
|
1501
|
+
const providerLabel = getProviderLabel(selectedProvider, 0).split(" (")[0];
|
|
1502
|
+
const apiKeyUrls = {
|
|
1503
|
+
kimi: "https://platform.moonshot.cn/console/api-keys",
|
|
1504
|
+
deepseek: "https://platform.deepseek.com/api_keys",
|
|
1505
|
+
siliconflow: "https://cloud.siliconflow.cn/i/oJWsm6io",
|
|
1506
|
+
qwen: "https://bailian.console.aliyun.com/?tab=model#/api-key",
|
|
1507
|
+
glm: "https://open.bigmodel.cn (API Keys section)",
|
|
1508
|
+
minimax: "https://www.minimax.io/platform/user-center/basic-information",
|
|
1509
|
+
"baidu-qianfan": "https://console.bce.baidu.com/iam/#/iam/accesslist",
|
|
1510
|
+
openai: "https://platform.openai.com/api-keys"
|
|
1511
|
+
};
|
|
1512
|
+
let apiKeyUrl = apiKeyUrls[selectedProvider] || "";
|
|
1513
|
+
if (selectedProvider === "anthropic") {
|
|
1514
|
+
apiKeyUrl = anthropicProviderType === "official" ? "https://console.anthropic.com/settings/keys" : anthropicProviderType === "bigdream" ? "https://api-key.info/register?aff=MSl4" : anthropicProviderType === "opendev" ? "https://api.openai-next.com/register/?aff_code=4xo7" : "your custom API provider";
|
|
1515
|
+
}
|
|
1516
|
+
const supportsManualInput = selectedProvider === "anthropic" || selectedProvider === "kimi" || selectedProvider === "deepseek" || selectedProvider === "qwen" || selectedProvider === "glm" || selectedProvider === "minimax" || selectedProvider === "baidu-qianfan" || selectedProvider === "siliconflow" || selectedProvider === "custom-openai";
|
|
1517
|
+
const tabHintText = supportsManualInput ? t("modelSelector.apiKeyTabHintManual") : t("modelSelector.apiKeyTabHintSkip");
|
|
1518
|
+
const apiKeyHint = apiKeyUrl ? /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Get your API key from:", " ", /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.info }, apiKeyUrl)) : void 0;
|
|
1519
|
+
return /* @__PURE__ */ React.createElement(
|
|
1520
|
+
BrandTextInput,
|
|
1613
1521
|
{
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
columns: 500,
|
|
1631
|
-
cursorOffset,
|
|
1632
|
-
onChangeCursorOffset: handleCursorOffsetChange,
|
|
1633
|
-
showCursor: true
|
|
1634
|
-
}
|
|
1635
|
-
)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: apiKey ? theme.suggestion : SEMANTIC_COLORS.dim }, "[Submit API Key]"), /* @__PURE__ */ React.createElement(Text, null, " ", "- Press Enter or click to continue with this API key"))), isLoadingModels && /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Loading available models...")), modelLoadError && /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.error }, "Error: ", modelLoadError)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Enter"), " to continue,", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Tab"), " to", " ", selectedProvider === "anthropic" || selectedProvider === "kimi" || selectedProvider === "deepseek" || selectedProvider === "qwen" || selectedProvider === "glm" || selectedProvider === "minimax" || selectedProvider === "baidu-qianfan" || selectedProvider === "siliconflow" || selectedProvider === "custom-openai" ? "skip to manual model input" : "skip using a key", ", or ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back")))
|
|
1636
|
-
));
|
|
1522
|
+
title: `${t("modelSelector.apiKeyTitle")} \u2014 ${providerLabel}`,
|
|
1523
|
+
description: t("modelSelector.apiKeyDesc"),
|
|
1524
|
+
placeholder: "sk-...",
|
|
1525
|
+
value: apiKey,
|
|
1526
|
+
onChange: handleApiKeyChange,
|
|
1527
|
+
onSubmit: handleApiKeySubmit,
|
|
1528
|
+
mask: "*",
|
|
1529
|
+
error: modelLoadError ? `Error: ${modelLoadError}` : null,
|
|
1530
|
+
isLoading: isLoadingModels,
|
|
1531
|
+
loadingText: "Loading available models...",
|
|
1532
|
+
hint: apiKeyHint,
|
|
1533
|
+
footerHint: `Enter continue \xB7 Tab ${tabHintText} \xB7 Esc back`,
|
|
1534
|
+
cursorOffset,
|
|
1535
|
+
onChangeCursorOffset: handleCursorOffsetChange
|
|
1536
|
+
}
|
|
1537
|
+
);
|
|
1637
1538
|
}
|
|
1638
1539
|
if (currentScreen === "model") {
|
|
1639
|
-
const
|
|
1640
|
-
|
|
1641
|
-
|
|
1540
|
+
const providerLabel = getProviderLabel(
|
|
1541
|
+
selectedProvider,
|
|
1542
|
+
availableModels.length
|
|
1543
|
+
).split(" (")[0];
|
|
1544
|
+
const modelSelectorItems = modelOptions.map((opt) => ({
|
|
1545
|
+
id: opt.value,
|
|
1546
|
+
label: opt.label
|
|
1547
|
+
}));
|
|
1548
|
+
const subtitle = modelOptions.length > 0 ? `${modelOptions.length}/${availableModels.length} models` : availableModels.length > 0 ? t("modelSelector.noModelsMatch") : t("modelSelector.noModelsAvailable");
|
|
1549
|
+
return /* @__PURE__ */ React.createElement(
|
|
1550
|
+
SimpleSelector,
|
|
1642
1551
|
{
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
/* @__PURE__ */ React.createElement(Text, { bold: true }, "Model Selection", " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
|
|
1651
|
-
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Select a model from", " ", getProviderLabel(
|
|
1652
|
-
selectedProvider,
|
|
1653
|
-
availableModels.length
|
|
1654
|
-
).split(" (")[0], " ", "for ", modelTypeText, ":"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: 70 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "This model profile can be assigned to different pointers (main, task, reasoning, quick) for various use cases.")), /* @__PURE__ */ React.createElement(Box, { marginY: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Search models:"), /* @__PURE__ */ React.createElement(
|
|
1655
|
-
TextInput,
|
|
1656
|
-
{
|
|
1657
|
-
placeholder: "Type to filter models...",
|
|
1658
|
-
value: modelSearchQuery,
|
|
1659
|
-
onChange: handleModelSearchChange,
|
|
1660
|
-
columns: 100,
|
|
1661
|
-
cursorOffset: modelSearchCursorOffset,
|
|
1662
|
-
onChangeCursorOffset: handleModelSearchCursorOffsetChange,
|
|
1663
|
-
showCursor: true,
|
|
1664
|
-
focus: true
|
|
1665
|
-
}
|
|
1666
|
-
)), modelOptions.length > 0 ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
1667
|
-
Select,
|
|
1668
|
-
{
|
|
1669
|
-
options: modelOptions,
|
|
1670
|
-
onChange: handleModelSelection
|
|
1671
|
-
}
|
|
1672
|
-
), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Showing ", modelOptions.length, " of ", availableModels.length, " ", "models")) : /* @__PURE__ */ React.createElement(Box, null, availableModels.length > 0 ? /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.running }, "No models match your search. Try a different query.") : /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.running }, "No models available for this provider.")), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back to API key input")))
|
|
1673
|
-
));
|
|
1552
|
+
title: `${t("modelSelector.modelSelectionTitle")} \u2014 ${providerLabel}`,
|
|
1553
|
+
subtitle,
|
|
1554
|
+
items: modelSelectorItems,
|
|
1555
|
+
onSelect: (item) => handleModelSelection(item.id),
|
|
1556
|
+
onClose: handleBack
|
|
1557
|
+
}
|
|
1558
|
+
);
|
|
1674
1559
|
}
|
|
1675
1560
|
if (currentScreen === "modelParams") {
|
|
1676
1561
|
const formFields = getFormFieldsForModelParams();
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
{
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
},
|
|
1687
|
-
/* @__PURE__ */ React.createElement(Text, { bold: true }, "Model Parameters", " ", exitState.pending ? `(press ${exitState.keyName} again to exit)` : ""),
|
|
1688
|
-
/* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Configure parameters for ", selectedModel, ":"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: 70 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, "Use ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Tab"), " to navigate between fields. Press", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Enter"), " to submit.")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, formFields.map((field, index) => /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginY: 1, key: field.name }, field.component !== "button" ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
1689
|
-
Text,
|
|
1690
|
-
{
|
|
1691
|
-
bold: true,
|
|
1692
|
-
color: activeFieldIndex === index ? theme.success : void 0
|
|
1693
|
-
},
|
|
1694
|
-
field.label
|
|
1695
|
-
), field.description && /* @__PURE__ */ React.createElement(Text, { color: theme.secondaryText }, field.description)) : /* @__PURE__ */ React.createElement(
|
|
1696
|
-
Text,
|
|
1697
|
-
{
|
|
1698
|
-
bold: true,
|
|
1699
|
-
color: activeFieldIndex === index ? theme.success : void 0
|
|
1700
|
-
},
|
|
1701
|
-
field.label
|
|
1702
|
-
), /* @__PURE__ */ React.createElement(Box, { marginY: 1 }, activeFieldIndex === index ? field.component === "select" ? field.name === "maxTokens" ? /* @__PURE__ */ React.createElement(
|
|
1703
|
-
Select,
|
|
1562
|
+
const currentField = formFields[activeFieldIndex];
|
|
1563
|
+
if (currentField?.name === "maxTokens") {
|
|
1564
|
+
const maxTokensItems = MAX_TOKENS_OPTIONS.map((opt) => ({
|
|
1565
|
+
id: opt.value.toString(),
|
|
1566
|
+
label: opt.label,
|
|
1567
|
+
isCurrent: opt.value === parseInt(maxTokens)
|
|
1568
|
+
}));
|
|
1569
|
+
return /* @__PURE__ */ React.createElement(
|
|
1570
|
+
SimpleSelector,
|
|
1704
1571
|
{
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1572
|
+
title: `${t("modelSelector.modelParamsTitle")} \u2014 ${t("modelSelector.maxTokens")}`,
|
|
1573
|
+
subtitle: selectedModel,
|
|
1574
|
+
items: maxTokensItems,
|
|
1575
|
+
onSelect: (item) => {
|
|
1576
|
+
const numValue = parseInt(item.id);
|
|
1708
1577
|
setMaxTokens(numValue.toString());
|
|
1709
1578
|
setSelectedMaxTokensPreset(numValue);
|
|
1710
|
-
setMaxTokensCursorOffset(
|
|
1711
|
-
|
|
1712
|
-
);
|
|
1713
|
-
setTimeout(() => {
|
|
1714
|
-
setActiveFieldIndex(index + 1);
|
|
1715
|
-
}, 100);
|
|
1579
|
+
setMaxTokensCursorOffset(numValue.toString().length);
|
|
1580
|
+
setActiveFieldIndex(activeFieldIndex + 1);
|
|
1716
1581
|
},
|
|
1717
|
-
|
|
1582
|
+
onClose: handleBack
|
|
1718
1583
|
}
|
|
1719
|
-
)
|
|
1720
|
-
|
|
1584
|
+
);
|
|
1585
|
+
}
|
|
1586
|
+
if (currentField?.name === "reasoningEffort") {
|
|
1587
|
+
const effortItems = reasoningEffortOptions.map((opt) => ({
|
|
1588
|
+
id: opt.value,
|
|
1589
|
+
label: opt.label,
|
|
1590
|
+
isCurrent: opt.value === reasoningEffort
|
|
1591
|
+
}));
|
|
1592
|
+
return /* @__PURE__ */ React.createElement(
|
|
1593
|
+
SimpleSelector,
|
|
1721
1594
|
{
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1595
|
+
title: `${t("modelSelector.modelParamsTitle")} \u2014 ${t("modelSelector.reasoningEffort")}`,
|
|
1596
|
+
subtitle: selectedModel,
|
|
1597
|
+
items: effortItems,
|
|
1598
|
+
onSelect: (item) => {
|
|
1599
|
+
setReasoningEffort(item.id);
|
|
1600
|
+
setActiveFieldIndex(activeFieldIndex + 1);
|
|
1728
1601
|
},
|
|
1729
|
-
|
|
1602
|
+
onClose: () => {
|
|
1603
|
+
setActiveFieldIndex(0);
|
|
1604
|
+
}
|
|
1730
1605
|
}
|
|
1731
|
-
)
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1606
|
+
);
|
|
1607
|
+
}
|
|
1608
|
+
handleModelParamsSubmit();
|
|
1609
|
+
return null;
|
|
1735
1610
|
}
|
|
1736
1611
|
if (currentScreen === "resourceName") {
|
|
1737
|
-
return /* @__PURE__ */ React.createElement(
|
|
1738
|
-
|
|
1612
|
+
return /* @__PURE__ */ React.createElement(
|
|
1613
|
+
BrandTextInput,
|
|
1739
1614
|
{
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
placeholder: "myazureresource",
|
|
1752
|
-
value: resourceName,
|
|
1753
|
-
onChange: setResourceName,
|
|
1754
|
-
onSubmit: handleResourceNameSubmit,
|
|
1755
|
-
columns: 100,
|
|
1756
|
-
cursorOffset: resourceNameCursorOffset,
|
|
1757
|
-
onChangeCursorOffset: setResourceNameCursorOffset,
|
|
1758
|
-
showCursor: true
|
|
1759
|
-
}
|
|
1760
|
-
)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(
|
|
1761
|
-
Text,
|
|
1762
|
-
{
|
|
1763
|
-
color: resourceName ? theme.suggestion : SEMANTIC_COLORS.dim
|
|
1764
|
-
},
|
|
1765
|
-
"[Submit Resource Name]"
|
|
1766
|
-
), /* @__PURE__ */ React.createElement(Text, null, " - Press Enter or click to continue"))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Enter"), " to continue or", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back")))
|
|
1767
|
-
));
|
|
1615
|
+
title: t("modelSelector.resourceNameTitle"),
|
|
1616
|
+
description: t("modelSelector.resourceNameDesc"),
|
|
1617
|
+
placeholder: "myazureresource",
|
|
1618
|
+
value: resourceName,
|
|
1619
|
+
onChange: setResourceName,
|
|
1620
|
+
onSubmit: handleResourceNameSubmit,
|
|
1621
|
+
footerHint: t("modelSelector.footerEnterContinue"),
|
|
1622
|
+
cursorOffset: resourceNameCursorOffset,
|
|
1623
|
+
onChangeCursorOffset: setResourceNameCursorOffset
|
|
1624
|
+
}
|
|
1625
|
+
);
|
|
1768
1626
|
}
|
|
1769
1627
|
if (currentScreen === "baseUrl") {
|
|
1770
1628
|
const isCustomOpenAI = selectedProvider === "custom-openai";
|
|
1771
1629
|
if (isCustomOpenAI) {
|
|
1772
|
-
return /* @__PURE__ */ React.createElement(
|
|
1773
|
-
|
|
1630
|
+
return /* @__PURE__ */ React.createElement(
|
|
1631
|
+
BrandTextInput,
|
|
1774
1632
|
{
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
onSubmit: handleCustomBaseUrlSubmit,
|
|
1790
|
-
columns: 100,
|
|
1791
|
-
cursorOffset: customBaseUrlCursorOffset,
|
|
1792
|
-
onChangeCursorOffset: setCustomBaseUrlCursorOffset,
|
|
1793
|
-
showCursor: !isLoadingModels,
|
|
1794
|
-
focus: !isLoadingModels
|
|
1795
|
-
}
|
|
1796
|
-
)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(
|
|
1797
|
-
Text,
|
|
1798
|
-
{
|
|
1799
|
-
color: isLoadingModels ? theme.secondaryText : theme.suggestion
|
|
1800
|
-
},
|
|
1801
|
-
"[Submit Base URL]"
|
|
1802
|
-
), /* @__PURE__ */ React.createElement(Text, null, " - Press Enter or click to continue"))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Enter"), " to continue or ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back")))
|
|
1803
|
-
));
|
|
1633
|
+
title: t("modelSelector.customApiTitle"),
|
|
1634
|
+
description: t("modelSelector.customApiDesc"),
|
|
1635
|
+
placeholder: "https://api.example.com/v1",
|
|
1636
|
+
value: customBaseUrl,
|
|
1637
|
+
onChange: setCustomBaseUrl,
|
|
1638
|
+
onSubmit: handleCustomBaseUrlSubmit,
|
|
1639
|
+
isLoading: isLoadingModels,
|
|
1640
|
+
loadingText: "Connecting...",
|
|
1641
|
+
error: modelLoadError ? `Error: ${modelLoadError}` : null,
|
|
1642
|
+
footerHint: t("modelSelector.footerEnterContinue"),
|
|
1643
|
+
cursorOffset: customBaseUrlCursorOffset,
|
|
1644
|
+
onChangeCursorOffset: setCustomBaseUrlCursorOffset
|
|
1645
|
+
}
|
|
1646
|
+
);
|
|
1804
1647
|
}
|
|
1805
1648
|
const providerName = providers[selectedProvider]?.name || selectedProvider;
|
|
1806
1649
|
const defaultUrl = providers[selectedProvider]?.baseURL || "";
|
|
1807
|
-
|
|
1808
|
-
|
|
1650
|
+
const desc = selectedProvider === "ollama" ? t("modelSelector.baseUrlOllamaDesc") : `${t("modelSelector.baseUrlDesc")} You can modify this URL or press Enter to use the default.`;
|
|
1651
|
+
return /* @__PURE__ */ React.createElement(
|
|
1652
|
+
BrandTextInput,
|
|
1809
1653
|
{
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
onSubmit: handleProviderBaseUrlSubmit,
|
|
1825
|
-
columns: 100,
|
|
1826
|
-
cursorOffset: providerBaseUrlCursorOffset,
|
|
1827
|
-
onChangeCursorOffset: setProviderBaseUrlCursorOffset,
|
|
1828
|
-
showCursor: !isLoadingModels,
|
|
1829
|
-
focus: !isLoadingModels
|
|
1830
|
-
}
|
|
1831
|
-
)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(
|
|
1832
|
-
Text,
|
|
1833
|
-
{
|
|
1834
|
-
color: isLoadingModels ? theme.secondaryText : theme.suggestion
|
|
1835
|
-
},
|
|
1836
|
-
"[Submit Base URL]"
|
|
1837
|
-
), /* @__PURE__ */ React.createElement(Text, null, " - Press Enter or click to continue"))), isLoadingModels && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, selectedProvider === "ollama" ? "Connecting to Ollama server..." : `Connecting to ${providerName}...`)), modelLoadError && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.error }, "Error: ", modelLoadError)), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Press ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Enter"), " to continue or", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, "Esc"), " to go back")))
|
|
1838
|
-
));
|
|
1654
|
+
title: `${t("modelSelector.baseUrlTitle")} \u2014 ${providerName}`,
|
|
1655
|
+
description: desc,
|
|
1656
|
+
placeholder: defaultUrl,
|
|
1657
|
+
value: providerBaseUrl,
|
|
1658
|
+
onChange: setProviderBaseUrl,
|
|
1659
|
+
onSubmit: handleProviderBaseUrlSubmit,
|
|
1660
|
+
isLoading: isLoadingModels,
|
|
1661
|
+
loadingText: selectedProvider === "ollama" ? "Connecting to Ollama server..." : `Connecting to ${providerName}...`,
|
|
1662
|
+
error: modelLoadError ? `Error: ${modelLoadError}` : null,
|
|
1663
|
+
footerHint: t("modelSelector.footerEnterContinue"),
|
|
1664
|
+
cursorOffset: providerBaseUrlCursorOffset,
|
|
1665
|
+
onChangeCursorOffset: setProviderBaseUrlCursorOffset
|
|
1666
|
+
}
|
|
1667
|
+
);
|
|
1839
1668
|
}
|
|
1840
1669
|
if (currentScreen === "modelInput") {
|
|
1841
|
-
const
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
if (selectedProvider === "azure") {
|
|
1847
|
-
screenTitle = "Azure Model Setup";
|
|
1848
|
-
description = `Enter your Azure OpenAI deployment name for ${modelTypeText}:`;
|
|
1849
|
-
examples = 'For example: "gpt-4", "gpt-35-turbo", etc.';
|
|
1850
|
-
placeholder = "gpt-4";
|
|
1851
|
-
} else if (selectedProvider === "anthropic") {
|
|
1852
|
-
screenTitle = "Claude Model Setup";
|
|
1853
|
-
description = `Enter the Claude model name for ${modelTypeText}:`;
|
|
1854
|
-
examples = 'For example: "claude-3-5-sonnet-latest", "claude-3-5-haiku-latest", etc.';
|
|
1855
|
-
placeholder = "claude-3-5-sonnet-latest";
|
|
1856
|
-
} else if (selectedProvider === "bigdream") {
|
|
1857
|
-
screenTitle = "BigDream Model Setup";
|
|
1858
|
-
description = `Enter the BigDream model name for ${modelTypeText}:`;
|
|
1859
|
-
examples = 'For example: "claude-3-5-sonnet-latest", "claude-3-5-haiku-latest", etc.';
|
|
1860
|
-
placeholder = "claude-3-5-sonnet-latest";
|
|
1861
|
-
} else if (selectedProvider === "kimi") {
|
|
1862
|
-
screenTitle = "Kimi Model Setup";
|
|
1863
|
-
description = `Enter the Kimi model name for ${modelTypeText}:`;
|
|
1864
|
-
examples = 'For example: "kimi-k2-0711-preview"';
|
|
1865
|
-
placeholder = "kimi-k2-0711-preview";
|
|
1866
|
-
} else if (selectedProvider === "deepseek") {
|
|
1867
|
-
screenTitle = "DeepSeek Model Setup";
|
|
1868
|
-
description = `Enter the DeepSeek model name for ${modelTypeText}:`;
|
|
1869
|
-
examples = 'For example: "deepseek-chat", "deepseek-coder", "deepseek-reasoner", etc.';
|
|
1870
|
-
placeholder = "deepseek-chat";
|
|
1871
|
-
} else if (selectedProvider === "siliconflow") {
|
|
1872
|
-
screenTitle = "SiliconFlow Model Setup";
|
|
1873
|
-
description = `Enter the SiliconFlow model name for ${modelTypeText}:`;
|
|
1874
|
-
examples = 'For example: "Qwen/Qwen2.5-72B-Instruct", "meta-llama/Meta-Llama-3.1-8B-Instruct", etc.';
|
|
1875
|
-
placeholder = "Qwen/Qwen2.5-72B-Instruct";
|
|
1876
|
-
} else if (selectedProvider === "qwen") {
|
|
1877
|
-
screenTitle = "Qwen Model Setup";
|
|
1878
|
-
description = `Enter the Qwen model name for ${modelTypeText}:`;
|
|
1879
|
-
examples = 'For example: "qwen-plus", "qwen-turbo", "qwen-max", etc.';
|
|
1880
|
-
placeholder = "qwen-plus";
|
|
1881
|
-
} else if (selectedProvider === "glm") {
|
|
1882
|
-
screenTitle = "GLM Model Setup";
|
|
1883
|
-
description = `Enter the GLM model name for ${modelTypeText}:`;
|
|
1884
|
-
examples = 'For example: "glm-4", "glm-4v", "glm-3-turbo", etc.';
|
|
1885
|
-
placeholder = "glm-4";
|
|
1886
|
-
} else if (selectedProvider === "minimax") {
|
|
1887
|
-
screenTitle = "MiniMax Model Setup";
|
|
1888
|
-
description = `Enter the MiniMax model name for ${modelTypeText}:`;
|
|
1889
|
-
examples = 'For example: "abab6.5s-chat", "abab6.5g-chat", "abab5.5s-chat", etc.';
|
|
1890
|
-
placeholder = "abab6.5s-chat";
|
|
1891
|
-
} else if (selectedProvider === "baidu-qianfan") {
|
|
1892
|
-
screenTitle = "Baidu Qianfan Model Setup";
|
|
1893
|
-
description = `Enter the Baidu Qianfan model name for ${modelTypeText}:`;
|
|
1894
|
-
examples = 'For example: "ERNIE-4.0-8K", "ERNIE-3.5-8K", "ERNIE-Speed-128K", etc.';
|
|
1895
|
-
placeholder = "ERNIE-4.0-8K";
|
|
1896
|
-
} else if (selectedProvider === "custom-openai") {
|
|
1897
|
-
screenTitle = "Custom API Model Setup";
|
|
1898
|
-
description = `Enter the model name for ${modelTypeText}:`;
|
|
1899
|
-
examples = "Enter the exact model name as supported by your API endpoint.";
|
|
1900
|
-
placeholder = "model-name";
|
|
1901
|
-
}
|
|
1902
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(
|
|
1903
|
-
Box,
|
|
1904
|
-
{
|
|
1905
|
-
flexDirection: "column",
|
|
1906
|
-
gap: 1,
|
|
1907
|
-
borderStyle: "round",
|
|
1908
|
-
borderColor: theme.secondaryBorder,
|
|
1909
|
-
paddingX: 2,
|
|
1910
|
-
paddingY: 1
|
|
1670
|
+
const modelInputConfig = {
|
|
1671
|
+
azure: {
|
|
1672
|
+
title: "Azure Model Setup",
|
|
1673
|
+
placeholder: "gpt-4",
|
|
1674
|
+
examples: 'e.g. "gpt-4", "gpt-35-turbo"'
|
|
1911
1675
|
},
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
"
|
|
1931
|
-
|
|
1932
|
-
|
|
1676
|
+
anthropic: {
|
|
1677
|
+
title: "Claude Model Setup",
|
|
1678
|
+
placeholder: "claude-3-5-sonnet-latest",
|
|
1679
|
+
examples: 'e.g. "claude-3-5-sonnet-latest", "claude-3-5-haiku-latest"'
|
|
1680
|
+
},
|
|
1681
|
+
bigdream: {
|
|
1682
|
+
title: "BigDream Model Setup",
|
|
1683
|
+
placeholder: "claude-3-5-sonnet-latest",
|
|
1684
|
+
examples: 'e.g. "claude-3-5-sonnet-latest", "claude-3-5-haiku-latest"'
|
|
1685
|
+
},
|
|
1686
|
+
kimi: {
|
|
1687
|
+
title: "Kimi Model Setup",
|
|
1688
|
+
placeholder: "kimi-k2-0711-preview",
|
|
1689
|
+
examples: 'e.g. "kimi-k2-0711-preview"'
|
|
1690
|
+
},
|
|
1691
|
+
deepseek: {
|
|
1692
|
+
title: "DeepSeek Model Setup",
|
|
1693
|
+
placeholder: "deepseek-chat",
|
|
1694
|
+
examples: 'e.g. "deepseek-chat", "deepseek-coder", "deepseek-reasoner"'
|
|
1695
|
+
},
|
|
1696
|
+
siliconflow: {
|
|
1697
|
+
title: "SiliconFlow Model Setup",
|
|
1698
|
+
placeholder: "Qwen/Qwen2.5-72B-Instruct",
|
|
1699
|
+
examples: 'e.g. "Qwen/Qwen2.5-72B-Instruct"'
|
|
1700
|
+
},
|
|
1701
|
+
qwen: {
|
|
1702
|
+
title: "Qwen Model Setup",
|
|
1703
|
+
placeholder: "qwen-plus",
|
|
1704
|
+
examples: 'e.g. "qwen-plus", "qwen-turbo", "qwen-max"'
|
|
1705
|
+
},
|
|
1706
|
+
glm: {
|
|
1707
|
+
title: "GLM Model Setup",
|
|
1708
|
+
placeholder: "glm-4",
|
|
1709
|
+
examples: 'e.g. "glm-4", "glm-4v", "glm-3-turbo"'
|
|
1710
|
+
},
|
|
1711
|
+
minimax: {
|
|
1712
|
+
title: "MiniMax Model Setup",
|
|
1713
|
+
placeholder: "abab6.5s-chat",
|
|
1714
|
+
examples: 'e.g. "abab6.5s-chat", "abab6.5g-chat"'
|
|
1715
|
+
},
|
|
1716
|
+
"baidu-qianfan": {
|
|
1717
|
+
title: "Baidu Qianfan Model Setup",
|
|
1718
|
+
placeholder: "ERNIE-4.0-8K",
|
|
1719
|
+
examples: 'e.g. "ERNIE-4.0-8K", "ERNIE-3.5-8K"'
|
|
1720
|
+
},
|
|
1721
|
+
"custom-openai": {
|
|
1722
|
+
title: "Custom API Model Setup",
|
|
1723
|
+
placeholder: "model-name",
|
|
1724
|
+
examples: "Enter the exact model name supported by your API endpoint."
|
|
1725
|
+
}
|
|
1726
|
+
};
|
|
1727
|
+
const cfg = modelInputConfig[selectedProvider] || {
|
|
1728
|
+
title: t("modelSelector.modelInputTitle"),
|
|
1729
|
+
placeholder: "gpt-4",
|
|
1730
|
+
examples: 'e.g. "gpt-4", "gpt-3.5-turbo"'
|
|
1731
|
+
};
|
|
1732
|
+
return /* @__PURE__ */ React.createElement(
|
|
1733
|
+
BrandTextInput,
|
|
1734
|
+
{
|
|
1735
|
+
title: cfg.title,
|
|
1736
|
+
description: cfg.examples,
|
|
1737
|
+
placeholder: cfg.placeholder,
|
|
1738
|
+
value: customModelName,
|
|
1739
|
+
onChange: setCustomModelName,
|
|
1740
|
+
onSubmit: handleCustomModelSubmit,
|
|
1741
|
+
footerHint: t("modelSelector.footerEnterContinue"),
|
|
1742
|
+
cursorOffset: customModelNameCursorOffset,
|
|
1743
|
+
onChangeCursorOffset: setCustomModelNameCursorOffset
|
|
1744
|
+
}
|
|
1745
|
+
);
|
|
1933
1746
|
}
|
|
1934
1747
|
if (currentScreen === "contextLength") {
|
|
1935
|
-
const
|
|
1936
|
-
|
|
1937
|
-
|
|
1748
|
+
const contextItems = CONTEXT_LENGTH_OPTIONS.map((opt) => ({
|
|
1749
|
+
id: opt.value.toString(),
|
|
1750
|
+
label: opt.value === DEFAULT_CONTEXT_LENGTH ? `${opt.label} (${t("modelSelector.recommended")})` : opt.label,
|
|
1751
|
+
isCurrent: opt.value === contextLength
|
|
1752
|
+
}));
|
|
1753
|
+
return /* @__PURE__ */ React.createElement(
|
|
1754
|
+
SimpleSelector,
|
|
1938
1755
|
{
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
return /* @__PURE__ */ React.createElement(Box, { key: option.value, flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, { color: isSelected ? "blue" : void 0 }, isSelected ? "\u2192 " : " ", option.label, option.value === DEFAULT_CONTEXT_LENGTH ? " (recommended)" : ""));
|
|
1950
|
-
})), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Selected:", " ", /* @__PURE__ */ React.createElement(Text, { color: theme.suggestion }, selectedOption.label))))
|
|
1951
|
-
), /* @__PURE__ */ React.createElement(Box, { marginLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "\u2191/\u2193 to select \xB7 Enter to continue \xB7 Esc to go back")));
|
|
1756
|
+
title: t("modelSelector.contextLengthTitle"),
|
|
1757
|
+
subtitle: t("modelSelector.contextLengthDesc"),
|
|
1758
|
+
items: contextItems,
|
|
1759
|
+
onSelect: (item) => {
|
|
1760
|
+
setContextLength(parseInt(item.id));
|
|
1761
|
+
handleContextLengthSubmit();
|
|
1762
|
+
},
|
|
1763
|
+
onClose: handleBack
|
|
1764
|
+
}
|
|
1765
|
+
);
|
|
1952
1766
|
}
|
|
1953
1767
|
if (currentScreen === "connectionTest") {
|
|
1954
1768
|
const providerDisplayName = getProviderLabel(selectedProvider, 0).split(
|
|
1955
1769
|
" ("
|
|
1956
1770
|
)[0];
|
|
1957
|
-
|
|
1958
|
-
Box,
|
|
1771
|
+
const testSections = [
|
|
1959
1772
|
{
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1773
|
+
title: t("modelSelector.connectionTestDesc"),
|
|
1774
|
+
items: [
|
|
1775
|
+
{ label: "Provider", value: providerDisplayName },
|
|
1776
|
+
{ label: "Model", value: selectedModel },
|
|
1777
|
+
...connectionTestResult ? [
|
|
1778
|
+
{
|
|
1779
|
+
label: "Status",
|
|
1780
|
+
value: connectionTestResult.message,
|
|
1781
|
+
valueColor: connectionTestResult.success ? SEMANTIC_COLORS.success : SEMANTIC_COLORS.error
|
|
1782
|
+
},
|
|
1783
|
+
...connectionTestResult.endpoint ? [
|
|
1784
|
+
{
|
|
1785
|
+
label: "Endpoint",
|
|
1786
|
+
value: connectionTestResult.endpoint
|
|
1787
|
+
}
|
|
1788
|
+
] : [],
|
|
1789
|
+
...connectionTestResult.details ? [
|
|
1790
|
+
{
|
|
1791
|
+
label: "Details",
|
|
1792
|
+
value: connectionTestResult.details
|
|
1793
|
+
}
|
|
1794
|
+
] : []
|
|
1795
|
+
] : []
|
|
1796
|
+
]
|
|
1797
|
+
}
|
|
1798
|
+
];
|
|
1799
|
+
const testActions = [];
|
|
1800
|
+
if (!isTestingConnection && !connectionTestResult) {
|
|
1801
|
+
testActions.push({
|
|
1802
|
+
key: "return",
|
|
1803
|
+
keyLabel: "Enter",
|
|
1804
|
+
description: t("modelSelector.connectionTestStart"),
|
|
1805
|
+
onPress: () => handleConnectionTest()
|
|
1806
|
+
});
|
|
1807
|
+
} else if (connectionTestResult && connectionTestResult.success) {
|
|
1808
|
+
testActions.push({
|
|
1809
|
+
key: "return",
|
|
1810
|
+
keyLabel: "Enter",
|
|
1811
|
+
description: t("modelSelector.continue"),
|
|
1812
|
+
onPress: () => navigateTo("confirmation")
|
|
1813
|
+
});
|
|
1814
|
+
} else if (connectionTestResult && !connectionTestResult.success) {
|
|
1815
|
+
testActions.push({
|
|
1816
|
+
key: "return",
|
|
1817
|
+
keyLabel: "Enter",
|
|
1818
|
+
description: t("modelSelector.connectionTestRetry"),
|
|
1819
|
+
onPress: () => handleConnectionTest()
|
|
1820
|
+
});
|
|
1821
|
+
}
|
|
1822
|
+
const testOverlay = isTestingConnection ? {
|
|
1823
|
+
type: "loading",
|
|
1824
|
+
message: t("modelSelector.connectionTestRunning")
|
|
1825
|
+
} : connectionTestResult?.success ? {
|
|
1826
|
+
type: "success",
|
|
1827
|
+
message: t("modelSelector.connectionTestAutoProceeding")
|
|
1828
|
+
} : null;
|
|
1829
|
+
return /* @__PURE__ */ React.createElement(
|
|
1830
|
+
InfoPanel,
|
|
1831
|
+
{
|
|
1832
|
+
title: `${t("modelSelector.connectionTestTitle")} \u2014 ${providerDisplayName}`,
|
|
1833
|
+
sections: testSections,
|
|
1834
|
+
actions: testActions,
|
|
1835
|
+
onClose: handleBack,
|
|
1836
|
+
statusOverlay: testOverlay
|
|
1837
|
+
}
|
|
1838
|
+
);
|
|
1976
1839
|
}
|
|
1977
1840
|
if (currentScreen === "confirmation") {
|
|
1978
1841
|
const providerDisplayName = getProviderLabel(selectedProvider, 0).split(
|
|
1979
1842
|
" ("
|
|
1980
1843
|
)[0];
|
|
1981
1844
|
const showsApiKey = selectedProvider !== "ollama";
|
|
1982
|
-
|
|
1983
|
-
|
|
1845
|
+
const configItems = [
|
|
1846
|
+
{ label: "Provider", value: providerDisplayName },
|
|
1847
|
+
...selectedProvider === "azure" ? [{ label: "Resource Name", value: resourceName }] : [],
|
|
1848
|
+
...selectedProvider === "ollama" ? [{ label: "Server URL", value: ollamaBaseUrl }] : [],
|
|
1849
|
+
...selectedProvider === "custom-openai" ? [{ label: "API Base URL", value: customBaseUrl }] : [],
|
|
1850
|
+
{ label: "Model", value: selectedModel },
|
|
1851
|
+
...apiKey && showsApiKey ? [{ label: "API Key", value: `****${apiKey.slice(-4)}` }] : [],
|
|
1852
|
+
...maxTokens ? [{ label: "Max Tokens", value: maxTokens }] : [],
|
|
1984
1853
|
{
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
borderStyle: "round",
|
|
1988
|
-
borderColor: theme.secondaryBorder,
|
|
1989
|
-
paddingX: 2,
|
|
1990
|
-
paddingY: 1
|
|
1854
|
+
label: "Context Length",
|
|
1855
|
+
value: CONTEXT_LENGTH_OPTIONS.find((opt) => opt.value === contextLength)?.label || `${contextLength.toLocaleString()} tokens`
|
|
1991
1856
|
},
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1857
|
+
...supportsReasoningEffort ? [{ label: "Reasoning Effort", value: reasoningEffort }] : []
|
|
1858
|
+
];
|
|
1859
|
+
const confirmSections = [
|
|
1860
|
+
{
|
|
1861
|
+
title: t("modelSelector.confirmationDesc"),
|
|
1862
|
+
items: configItems
|
|
1863
|
+
}
|
|
1864
|
+
];
|
|
1865
|
+
if (validationError) {
|
|
1866
|
+
confirmSections.unshift({
|
|
1867
|
+
title: t("modelSelector.configError"),
|
|
1868
|
+
items: [
|
|
1869
|
+
{
|
|
1870
|
+
label: "Error",
|
|
1871
|
+
value: validationError,
|
|
1872
|
+
valueColor: SEMANTIC_COLORS.error
|
|
1873
|
+
}
|
|
1874
|
+
]
|
|
1875
|
+
});
|
|
1876
|
+
}
|
|
1877
|
+
const confirmActions = [
|
|
1878
|
+
{
|
|
1879
|
+
key: "return",
|
|
1880
|
+
keyLabel: "Enter",
|
|
1881
|
+
description: t("modelSelector.confirmationSave"),
|
|
1882
|
+
onPress: () => {
|
|
1883
|
+
handleConfirmation().catch((error) => {
|
|
1884
|
+
setValidationError(
|
|
1885
|
+
error instanceof Error ? error.message : "Unexpected error occurred"
|
|
1886
|
+
);
|
|
1887
|
+
});
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1890
|
+
];
|
|
1891
|
+
return /* @__PURE__ */ React.createElement(
|
|
1892
|
+
InfoPanel,
|
|
1893
|
+
{
|
|
1894
|
+
title: t("modelSelector.confirmationTitle"),
|
|
1895
|
+
sections: confirmSections,
|
|
1896
|
+
actions: confirmActions,
|
|
1897
|
+
onClose: handleBack
|
|
1898
|
+
}
|
|
1899
|
+
);
|
|
1997
1900
|
}
|
|
1998
1901
|
if (currentScreen === "anthropicSubMenu") {
|
|
1999
|
-
const
|
|
2000
|
-
{ label: "Official Anthropic API", value: "official" },
|
|
2001
|
-
{ label: "BigDream (Community Proxy)", value: "bigdream" },
|
|
2002
|
-
{ label: "OpenDev (Community Proxy)", value: "opendev" },
|
|
2003
|
-
{ label: "Custom Anthropic-Compatible API", value: "custom" }
|
|
2004
|
-
];
|
|
2005
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React.createElement(
|
|
2006
|
-
Box,
|
|
1902
|
+
const anthropicItems = [
|
|
2007
1903
|
{
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
borderColor: theme.secondaryBorder,
|
|
2012
|
-
paddingX: 2,
|
|
2013
|
-
paddingY: 1
|
|
1904
|
+
id: "official",
|
|
1905
|
+
label: t("modelSelector.anthropicOfficial"),
|
|
1906
|
+
description: t("modelSelector.anthropicOfficialDesc")
|
|
2014
1907
|
},
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
1908
|
+
{
|
|
1909
|
+
id: "bigdream",
|
|
1910
|
+
label: t("modelSelector.anthropicBigdream"),
|
|
1911
|
+
description: t("modelSelector.anthropicBigdreamDesc")
|
|
1912
|
+
},
|
|
1913
|
+
{
|
|
1914
|
+
id: "opendev",
|
|
1915
|
+
label: t("modelSelector.anthropicOpendev"),
|
|
1916
|
+
description: t("modelSelector.anthropicOpendevDesc")
|
|
1917
|
+
},
|
|
1918
|
+
{
|
|
1919
|
+
id: "custom",
|
|
1920
|
+
label: t("modelSelector.anthropicCustom"),
|
|
1921
|
+
description: t("modelSelector.anthropicCustomDesc")
|
|
1922
|
+
}
|
|
1923
|
+
];
|
|
1924
|
+
return /* @__PURE__ */ React.createElement(
|
|
1925
|
+
SimpleSelector,
|
|
1926
|
+
{
|
|
1927
|
+
title: t("modelSelector.anthropicSubMenu"),
|
|
1928
|
+
subtitle: t("modelSelector.anthropicSubMenuDesc"),
|
|
1929
|
+
items: anthropicItems,
|
|
1930
|
+
onSelect: (item) => handleAnthropicProviderSelection(
|
|
1931
|
+
item.id
|
|
1932
|
+
),
|
|
1933
|
+
onClose: handleBack
|
|
1934
|
+
}
|
|
1935
|
+
);
|
|
2024
1936
|
}
|
|
1937
|
+
const providerSelectorItems = providerOptions.map((opt) => ({
|
|
1938
|
+
id: opt.value,
|
|
1939
|
+
label: opt.label
|
|
1940
|
+
}));
|
|
2025
1941
|
return /* @__PURE__ */ React.createElement(
|
|
2026
|
-
|
|
1942
|
+
SimpleSelector,
|
|
2027
1943
|
{
|
|
2028
|
-
title: "
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
1944
|
+
title: t("modelSelector.providerSelection"),
|
|
1945
|
+
subtitle: t("modelSelector.providerSelectionDesc"),
|
|
1946
|
+
items: providerSelectorItems,
|
|
1947
|
+
onSelect: (item) => handleProviderSelection(item.id),
|
|
1948
|
+
onClose: () => {
|
|
1949
|
+
if (onCancel) {
|
|
1950
|
+
onCancel();
|
|
1951
|
+
} else {
|
|
1952
|
+
onDone();
|
|
2035
1953
|
}
|
|
2036
|
-
|
|
1954
|
+
}
|
|
2037
1955
|
}
|
|
2038
1956
|
);
|
|
2039
1957
|
}
|