teleton 0.7.3 → 0.7.4

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.
@@ -1,3 +1,6 @@
1
+ import {
2
+ getModelsForProvider
3
+ } from "./chunk-QOQWUUA4.js";
1
4
  import {
2
5
  CONFIGURABLE_KEYS,
3
6
  WorkspaceSecurityError,
@@ -16,13 +19,16 @@ import {
16
19
  validateWritePath,
17
20
  writePluginSecret,
18
21
  writeRawConfig
19
- } from "./chunk-A4GCOHCE.js";
20
- import "./chunk-DAMCNMYL.js";
22
+ } from "./chunk-YFG2QHLA.js";
23
+ import "./chunk-BGC2IUM5.js";
21
24
  import "./chunk-TSKJCWQQ.js";
22
25
  import {
23
26
  getErrorMessage
24
27
  } from "./chunk-XBE4JB7C.js";
25
- import "./chunk-RMLQS3X6.js";
28
+ import {
29
+ getProviderMetadata,
30
+ validateApiKeyFormat
31
+ } from "./chunk-RMLQS3X6.js";
26
32
  import "./chunk-UCN6TI25.js";
27
33
  import "./chunk-XBKSS6DM.js";
28
34
  import "./chunk-RO62LO6Z.js";
@@ -214,7 +220,7 @@ function createToolsRoutes(deps) {
214
220
  try {
215
221
  const config = deps.agent.getConfig();
216
222
  const body = await c.req.json();
217
- const { enabled, topK } = body;
223
+ const { enabled, topK, alwaysInclude, skipUnlimitedProviders } = body;
218
224
  if (enabled !== void 0) {
219
225
  config.tool_rag.enabled = enabled;
220
226
  }
@@ -224,6 +230,28 @@ function createToolsRoutes(deps) {
224
230
  }
225
231
  config.tool_rag.top_k = topK;
226
232
  }
233
+ if (alwaysInclude !== void 0) {
234
+ if (!Array.isArray(alwaysInclude) || alwaysInclude.some((s) => typeof s !== "string" || s.length === 0)) {
235
+ return c.json(
236
+ { success: false, error: "alwaysInclude must be an array of non-empty strings" },
237
+ 400
238
+ );
239
+ }
240
+ config.tool_rag.always_include = alwaysInclude;
241
+ }
242
+ if (skipUnlimitedProviders !== void 0) {
243
+ config.tool_rag.skip_unlimited_providers = skipUnlimitedProviders;
244
+ }
245
+ const raw = readRawConfig(deps.configPath);
246
+ setNestedValue(raw, "tool_rag.enabled", config.tool_rag.enabled);
247
+ setNestedValue(raw, "tool_rag.top_k", config.tool_rag.top_k);
248
+ setNestedValue(raw, "tool_rag.always_include", config.tool_rag.always_include);
249
+ setNestedValue(
250
+ raw,
251
+ "tool_rag.skip_unlimited_providers",
252
+ config.tool_rag.skip_unlimited_providers
253
+ );
254
+ writeRawConfig(raw, deps.configPath);
227
255
  const toolIndex = deps.toolRegistry.getToolIndex();
228
256
  const response = {
229
257
  success: true,
@@ -231,7 +259,9 @@ function createToolsRoutes(deps) {
231
259
  enabled: config.tool_rag.enabled,
232
260
  indexed: toolIndex?.isIndexed ?? false,
233
261
  topK: config.tool_rag.top_k,
234
- totalTools: deps.toolRegistry.count
262
+ totalTools: deps.toolRegistry.count,
263
+ alwaysInclude: config.tool_rag.always_include,
264
+ skipUnlimitedProviders: config.tool_rag.skip_unlimited_providers
235
265
  }
236
266
  };
237
267
  return c.json(response);
@@ -509,6 +539,69 @@ function createMemoryRoutes(deps) {
509
539
  return c.json(response, 500);
510
540
  }
511
541
  });
542
+ app.get("/sources/:sourceKey", (c) => {
543
+ try {
544
+ const sourceKey = decodeURIComponent(c.req.param("sourceKey"));
545
+ const rows = deps.memory.db.prepare(
546
+ `
547
+ SELECT id, text, source, path, start_line, end_line, updated_at
548
+ FROM knowledge
549
+ WHERE COALESCE(path, source) = ?
550
+ ORDER BY start_line ASC, updated_at DESC
551
+ `
552
+ ).all(sourceKey);
553
+ const chunks = rows.map((row) => ({
554
+ id: row.id,
555
+ text: row.text,
556
+ source: row.path || row.source,
557
+ startLine: row.start_line,
558
+ endLine: row.end_line,
559
+ updatedAt: row.updated_at
560
+ }));
561
+ const response = {
562
+ success: true,
563
+ data: chunks
564
+ };
565
+ return c.json(response);
566
+ } catch (error) {
567
+ const response = {
568
+ success: false,
569
+ error: getErrorMessage(error)
570
+ };
571
+ return c.json(response, 500);
572
+ }
573
+ });
574
+ app.get("/sources", (c) => {
575
+ try {
576
+ const rows = deps.memory.db.prepare(
577
+ `
578
+ SELECT
579
+ COALESCE(path, source) AS source_key,
580
+ COUNT(*) AS entry_count,
581
+ MAX(updated_at) AS last_updated
582
+ FROM knowledge
583
+ GROUP BY source_key
584
+ ORDER BY last_updated DESC
585
+ `
586
+ ).all();
587
+ const sources = rows.map((row) => ({
588
+ source: row.source_key,
589
+ entryCount: row.entry_count,
590
+ lastUpdated: row.last_updated
591
+ }));
592
+ const response = {
593
+ success: true,
594
+ data: sources
595
+ };
596
+ return c.json(response);
597
+ } catch (error) {
598
+ const response = {
599
+ success: false,
600
+ error: getErrorMessage(error)
601
+ };
602
+ return c.json(response, 500);
603
+ }
604
+ });
512
605
  return app;
513
606
  }
514
607
 
@@ -750,6 +843,16 @@ function errorResponse(c, error, status = 500) {
750
843
  const response = { success: false, error: message };
751
844
  return c.json(response, code);
752
845
  }
846
+ var IMAGE_MIME_TYPES = {
847
+ ".png": "image/png",
848
+ ".jpg": "image/jpeg",
849
+ ".jpeg": "image/jpeg",
850
+ ".gif": "image/gif",
851
+ ".webp": "image/webp",
852
+ ".svg": "image/svg+xml",
853
+ ".bmp": "image/bmp",
854
+ ".ico": "image/x-icon"
855
+ };
753
856
  function getWorkspaceStats(dir) {
754
857
  let files = 0;
755
858
  let size = 0;
@@ -822,6 +925,45 @@ function createWorkspaceRoutes(_deps) {
822
925
  return errorResponse(c, error);
823
926
  }
824
927
  });
928
+ app.get("/raw", (c) => {
929
+ try {
930
+ const path = c.req.query("path");
931
+ if (!path) {
932
+ const response = { success: false, error: "Missing 'path' query parameter" };
933
+ return c.json(response, 400);
934
+ }
935
+ const validated = validateReadPath(path);
936
+ const mime = IMAGE_MIME_TYPES[validated.extension];
937
+ if (!mime) {
938
+ const response = {
939
+ success: false,
940
+ error: "Unsupported file type for raw preview"
941
+ };
942
+ return c.json(response, 415);
943
+ }
944
+ const stats = statSync(validated.absolutePath);
945
+ if (stats.size > 5 * 1024 * 1024) {
946
+ const response = {
947
+ success: false,
948
+ error: "Image too large for preview (max 5MB)"
949
+ };
950
+ return c.json(response, 413);
951
+ }
952
+ const buffer = readFileSync2(validated.absolutePath);
953
+ const headers = {
954
+ "Content-Type": mime,
955
+ "Content-Length": String(buffer.byteLength),
956
+ "Content-Disposition": "inline",
957
+ "Cache-Control": "private, max-age=60"
958
+ };
959
+ if (validated.extension === ".svg") {
960
+ headers["Content-Security-Policy"] = "sandbox";
961
+ }
962
+ return c.body(buffer, 200, headers);
963
+ } catch (error) {
964
+ return errorResponse(c, error);
965
+ }
966
+ });
825
967
  app.get("/read", (c) => {
826
968
  try {
827
969
  const path = c.req.query("path");
@@ -960,6 +1102,7 @@ function createWorkspaceRoutes(_deps) {
960
1102
  // src/webui/routes/tasks.ts
961
1103
  import { Hono as Hono9 } from "hono";
962
1104
  var VALID_STATUSES = ["pending", "in_progress", "done", "failed", "cancelled"];
1105
+ var TERMINAL_STATUSES = ["done", "failed", "cancelled"];
963
1106
  function createTasksRoutes(deps) {
964
1107
  const app = new Hono9();
965
1108
  function store() {
@@ -1032,6 +1175,32 @@ function createTasksRoutes(deps) {
1032
1175
  return c.json(response, 500);
1033
1176
  }
1034
1177
  });
1178
+ app.post("/clean", async (c) => {
1179
+ try {
1180
+ const body = await c.req.json().catch(() => ({ status: void 0 }));
1181
+ const status = body.status;
1182
+ if (!status || !TERMINAL_STATUSES.includes(status)) {
1183
+ const response2 = {
1184
+ success: false,
1185
+ error: `Invalid status. Must be one of: ${TERMINAL_STATUSES.join(", ")}`
1186
+ };
1187
+ return c.json(response2, 400);
1188
+ }
1189
+ const tasks = store().listTasks({ status });
1190
+ let deleted = 0;
1191
+ for (const t of tasks) {
1192
+ if (store().deleteTask(t.id)) deleted++;
1193
+ }
1194
+ const response = { success: true, data: { deleted } };
1195
+ return c.json(response);
1196
+ } catch (error) {
1197
+ const response = {
1198
+ success: false,
1199
+ error: getErrorMessage(error)
1200
+ };
1201
+ return c.json(response, 500);
1202
+ }
1203
+ });
1035
1204
  app.post("/clean-done", (c) => {
1036
1205
  try {
1037
1206
  const doneTasks = store().listTasks({ status: "done" });
@@ -1077,17 +1246,21 @@ function createConfigRoutes(deps) {
1077
1246
  try {
1078
1247
  const raw = readRawConfig(deps.configPath);
1079
1248
  const data = Object.entries(CONFIGURABLE_KEYS).map(([key, meta]) => {
1080
- const value = getNestedValue(raw, key);
1081
- const isSet = value != null && value !== "";
1249
+ const rawValue = getNestedValue(raw, key);
1250
+ const isSet = rawValue != null && rawValue !== "" && !(Array.isArray(rawValue) && rawValue.length === 0);
1251
+ const displayValue = isSet ? meta.type === "array" ? JSON.stringify(rawValue) : meta.mask(String(rawValue)) : null;
1082
1252
  return {
1083
1253
  key,
1254
+ label: meta.label,
1084
1255
  set: isSet,
1085
- value: isSet ? meta.mask(String(value)) : null,
1256
+ value: displayValue,
1086
1257
  sensitive: meta.sensitive,
1087
1258
  type: meta.type,
1088
1259
  category: meta.category,
1089
1260
  description: meta.description,
1090
- ...meta.options ? { options: meta.options } : {}
1261
+ ...meta.options ? { options: meta.options } : {},
1262
+ ...meta.optionLabels ? { optionLabels: meta.optionLabels } : {},
1263
+ ...meta.itemType ? { itemType: meta.itemType } : {}
1091
1264
  };
1092
1265
  });
1093
1266
  const response = { success: true, data };
@@ -1119,6 +1292,55 @@ function createConfigRoutes(deps) {
1119
1292
  return c.json({ success: false, error: "Invalid JSON body" }, 400);
1120
1293
  }
1121
1294
  const value = body.value;
1295
+ if (meta.type === "array") {
1296
+ if (!Array.isArray(value)) {
1297
+ return c.json(
1298
+ { success: false, error: "Value must be an array for array keys" },
1299
+ 400
1300
+ );
1301
+ }
1302
+ for (let i = 0; i < value.length; i++) {
1303
+ const itemStr = String(value[i]);
1304
+ const itemErr = meta.validate(itemStr);
1305
+ if (itemErr) {
1306
+ return c.json(
1307
+ {
1308
+ success: false,
1309
+ error: `Invalid item at index ${i} for ${key}: ${itemErr}`
1310
+ },
1311
+ 400
1312
+ );
1313
+ }
1314
+ }
1315
+ try {
1316
+ const parsed = value.map((item) => meta.parse(String(item)));
1317
+ const raw = readRawConfig(deps.configPath);
1318
+ setNestedValue(raw, key, parsed);
1319
+ writeRawConfig(raw, deps.configPath);
1320
+ const runtimeConfig = deps.agent.getConfig();
1321
+ setNestedValue(runtimeConfig, key, parsed);
1322
+ const result = {
1323
+ key,
1324
+ label: meta.label,
1325
+ set: parsed.length > 0,
1326
+ value: JSON.stringify(parsed),
1327
+ sensitive: meta.sensitive,
1328
+ type: meta.type,
1329
+ category: meta.category,
1330
+ description: meta.description,
1331
+ ...meta.itemType ? { itemType: meta.itemType } : {}
1332
+ };
1333
+ return c.json({ success: true, data: result });
1334
+ } catch (err) {
1335
+ return c.json(
1336
+ {
1337
+ success: false,
1338
+ error: err instanceof Error ? err.message : String(err)
1339
+ },
1340
+ 500
1341
+ );
1342
+ }
1343
+ }
1122
1344
  if (value == null || typeof value !== "string") {
1123
1345
  return c.json(
1124
1346
  { success: false, error: "Missing or invalid 'value' field" },
@@ -1136,11 +1358,24 @@ function createConfigRoutes(deps) {
1136
1358
  const parsed = meta.parse(value);
1137
1359
  const raw = readRawConfig(deps.configPath);
1138
1360
  setNestedValue(raw, key, parsed);
1361
+ if (key === "telegram.owner_id" && typeof parsed === "number") {
1362
+ const adminIds = getNestedValue(raw, "telegram.admin_ids") ?? [];
1363
+ if (!adminIds.includes(parsed)) {
1364
+ setNestedValue(raw, "telegram.admin_ids", [...adminIds, parsed]);
1365
+ }
1366
+ }
1139
1367
  writeRawConfig(raw, deps.configPath);
1140
1368
  const runtimeConfig = deps.agent.getConfig();
1141
1369
  setNestedValue(runtimeConfig, key, parsed);
1370
+ if (key === "telegram.owner_id" && typeof parsed === "number") {
1371
+ const rtAdminIds = getNestedValue(runtimeConfig, "telegram.admin_ids") ?? [];
1372
+ if (!rtAdminIds.includes(parsed)) {
1373
+ setNestedValue(runtimeConfig, "telegram.admin_ids", [...rtAdminIds, parsed]);
1374
+ }
1375
+ }
1142
1376
  const result = {
1143
1377
  key,
1378
+ label: meta.label,
1144
1379
  set: true,
1145
1380
  value: meta.mask(value),
1146
1381
  sensitive: meta.sensitive,
@@ -1178,13 +1413,15 @@ function createConfigRoutes(deps) {
1178
1413
  deleteNestedValue(runtimeConfig, key);
1179
1414
  const result = {
1180
1415
  key,
1416
+ label: meta.label,
1181
1417
  set: false,
1182
1418
  value: null,
1183
1419
  sensitive: meta.sensitive,
1184
1420
  type: meta.type,
1185
1421
  category: meta.category,
1186
1422
  description: meta.description,
1187
- ...meta.options ? { options: meta.options } : {}
1423
+ ...meta.options ? { options: meta.options } : {},
1424
+ ...meta.itemType ? { itemType: meta.itemType } : {}
1188
1425
  };
1189
1426
  return c.json({ success: true, data: result });
1190
1427
  } catch (err) {
@@ -1194,6 +1431,51 @@ function createConfigRoutes(deps) {
1194
1431
  );
1195
1432
  }
1196
1433
  });
1434
+ app.get("/models/:provider", (c) => {
1435
+ const provider = c.req.param("provider");
1436
+ const models = getModelsForProvider(provider);
1437
+ return c.json({ success: true, data: models });
1438
+ });
1439
+ app.get("/provider-meta/:provider", (c) => {
1440
+ const provider = c.req.param("provider");
1441
+ try {
1442
+ const meta = getProviderMetadata(provider);
1443
+ const needsKey = provider !== "claude-code" && provider !== "cocoon" && provider !== "local";
1444
+ return c.json({
1445
+ success: true,
1446
+ data: {
1447
+ needsKey,
1448
+ keyHint: meta.keyHint,
1449
+ keyPrefix: meta.keyPrefix,
1450
+ consoleUrl: meta.consoleUrl,
1451
+ displayName: meta.displayName
1452
+ }
1453
+ });
1454
+ } catch (err) {
1455
+ return c.json(
1456
+ { success: false, error: err instanceof Error ? err.message : String(err) },
1457
+ 400
1458
+ );
1459
+ }
1460
+ });
1461
+ app.post("/validate-api-key", async (c) => {
1462
+ try {
1463
+ const body = await c.req.json();
1464
+ if (!body.provider || !body.apiKey) {
1465
+ return c.json({ success: false, error: "Missing provider or apiKey" }, 400);
1466
+ }
1467
+ const error = validateApiKeyFormat(body.provider, body.apiKey);
1468
+ return c.json({
1469
+ success: true,
1470
+ data: { valid: !error, error: error ?? null }
1471
+ });
1472
+ } catch (err) {
1473
+ return c.json(
1474
+ { success: false, error: err instanceof Error ? err.message : String(err) },
1475
+ 400
1476
+ );
1477
+ }
1478
+ });
1197
1479
  return app;
1198
1480
  }
1199
1481
 
@@ -1,3 +1,6 @@
1
+ import {
2
+ getModelsForProvider
3
+ } from "./chunk-QOQWUUA4.js";
1
4
  import {
2
5
  ConfigSchema,
3
6
  DealsConfigSchema,
@@ -8,7 +11,7 @@ import {
8
11
  isNewWorkspace,
9
12
  saveWallet,
10
13
  walletExists
11
- } from "./chunk-DAMCNMYL.js";
14
+ } from "./chunk-BGC2IUM5.js";
12
15
  import {
13
16
  getClaudeCodeApiKey,
14
17
  isClaudeCodeTokenValid
@@ -285,111 +288,6 @@ var TelegramAuthManager = class {
285
288
 
286
289
  // src/webui/routes/setup.ts
287
290
  var log2 = createLogger("Setup");
288
- var MODEL_OPTIONS = {
289
- anthropic: [
290
- {
291
- value: "claude-opus-4-6",
292
- name: "Claude Opus 4.6",
293
- description: "Most capable, 1M ctx, $5/M"
294
- },
295
- {
296
- value: "claude-opus-4-5-20251101",
297
- name: "Claude Opus 4.5",
298
- description: "Previous gen, 200K ctx, $5/M"
299
- },
300
- { value: "claude-sonnet-4-0", name: "Claude Sonnet 4", description: "Balanced, $3/M" },
301
- {
302
- value: "claude-haiku-4-5-20251001",
303
- name: "Claude Haiku 4.5",
304
- description: "Fast & cheap, $1/M"
305
- },
306
- {
307
- value: "claude-haiku-4-5-20251001",
308
- name: "Claude Haiku 4.5",
309
- description: "Fast & cheap, $1/M"
310
- }
311
- ],
312
- openai: [
313
- { value: "gpt-5", name: "GPT-5", description: "Most capable, 400K ctx, $1.25/M" },
314
- { value: "gpt-4o", name: "GPT-4o", description: "Balanced, 128K ctx, $2.50/M" },
315
- { value: "gpt-4.1", name: "GPT-4.1", description: "1M ctx, $2/M" },
316
- { value: "gpt-4.1-mini", name: "GPT-4.1 Mini", description: "1M ctx, cheap, $0.40/M" },
317
- { value: "o3", name: "o3", description: "Reasoning, 200K ctx, $2/M" }
318
- ],
319
- google: [
320
- { value: "gemini-2.5-flash", name: "Gemini 2.5 Flash", description: "Fast, 1M ctx, $0.30/M" },
321
- {
322
- value: "gemini-2.5-pro",
323
- name: "Gemini 2.5 Pro",
324
- description: "Most capable, 1M ctx, $1.25/M"
325
- },
326
- { value: "gemini-2.0-flash", name: "Gemini 2.0 Flash", description: "Cheap, 1M ctx, $0.10/M" }
327
- ],
328
- xai: [
329
- { value: "grok-4-fast", name: "Grok 4 Fast", description: "Vision, 2M ctx, $0.20/M" },
330
- { value: "grok-4", name: "Grok 4", description: "Reasoning, 256K ctx, $3/M" },
331
- { value: "grok-3", name: "Grok 3", description: "Stable, 131K ctx, $3/M" }
332
- ],
333
- groq: [
334
- {
335
- value: "meta-llama/llama-4-maverick-17b-128e-instruct",
336
- name: "Llama 4 Maverick",
337
- description: "Vision, 131K ctx, $0.20/M"
338
- },
339
- { value: "qwen/qwen3-32b", name: "Qwen3 32B", description: "Reasoning, 131K ctx, $0.29/M" },
340
- {
341
- value: "deepseek-r1-distill-llama-70b",
342
- name: "DeepSeek R1 70B",
343
- description: "Reasoning, 131K ctx, $0.75/M"
344
- },
345
- {
346
- value: "llama-3.3-70b-versatile",
347
- name: "Llama 3.3 70B",
348
- description: "General purpose, 131K ctx, $0.59/M"
349
- }
350
- ],
351
- openrouter: [
352
- { value: "anthropic/claude-opus-4.5", name: "Claude Opus 4.5", description: "200K ctx, $5/M" },
353
- { value: "openai/gpt-5", name: "GPT-5", description: "400K ctx, $1.25/M" },
354
- { value: "google/gemini-2.5-flash", name: "Gemini 2.5 Flash", description: "1M ctx, $0.30/M" },
355
- {
356
- value: "deepseek/deepseek-r1",
357
- name: "DeepSeek R1",
358
- description: "Reasoning, 64K ctx, $0.70/M"
359
- },
360
- { value: "x-ai/grok-4", name: "Grok 4", description: "256K ctx, $3/M" }
361
- ],
362
- moonshot: [
363
- { value: "kimi-k2.5", name: "Kimi K2.5", description: "Free, 256K ctx, multimodal" },
364
- {
365
- value: "kimi-k2-thinking",
366
- name: "Kimi K2 Thinking",
367
- description: "Free, 256K ctx, reasoning"
368
- }
369
- ],
370
- mistral: [
371
- {
372
- value: "devstral-small-2507",
373
- name: "Devstral Small",
374
- description: "Coding, 128K ctx, $0.10/M"
375
- },
376
- {
377
- value: "devstral-medium-latest",
378
- name: "Devstral Medium",
379
- description: "Coding, 262K ctx, $0.40/M"
380
- },
381
- {
382
- value: "mistral-large-latest",
383
- name: "Mistral Large",
384
- description: "General, 128K ctx, $2/M"
385
- },
386
- {
387
- value: "magistral-small",
388
- name: "Magistral Small",
389
- description: "Reasoning, 128K ctx, $0.50/M"
390
- }
391
- ]
392
- };
393
291
  function maskKey(key) {
394
292
  if (key.length <= 10) return "***";
395
293
  return key.slice(0, 6) + "..." + key.slice(-4);
@@ -446,8 +344,7 @@ function createSetupRoutes() {
446
344
  });
447
345
  app.get("/models/:provider", (c) => {
448
346
  const provider = c.req.param("provider");
449
- const modelKey = provider === "claude-code" ? "anthropic" : provider;
450
- const models = MODEL_OPTIONS[modelKey] || [];
347
+ const models = getModelsForProvider(provider);
451
348
  const result = [
452
349
  ...models,
453
350
  {
@@ -760,7 +657,6 @@ function createSetupRoutes() {
760
657
  },
761
658
  storage: {
762
659
  sessions_file: `${workspace.root}/sessions.json`,
763
- pairing_file: `${workspace.root}/pairing.json`,
764
660
  memory_file: `${workspace.root}/memory.json`,
765
661
  history_limit: 100
766
662
  },
@@ -779,7 +675,7 @@ function createSetupRoutes() {
779
675
  logging: { level: "info", pretty: true },
780
676
  dev: { hot_reload: false },
781
677
  tool_rag: {
782
- enabled: true,
678
+ enabled: false,
783
679
  top_k: 25,
784
680
  always_include: [
785
681
  "telegram_send_message",
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  serializeEmbedding
3
- } from "./chunk-FNV5FF35.js";
3
+ } from "./chunk-EK7M5K26.js";
4
4
  import "./chunk-XBKSS6DM.js";
5
5
  import {
6
6
  TOOL_RAG_KEYWORD_WEIGHT,
@@ -0,0 +1 @@
1
+ *{box-sizing:border-box;margin:0;padding:0}:root{color-scheme:dark;--bg: #000000;--surface: rgba(255, 255, 255, .05);--surface-hover: rgba(255, 255, 255, .08);--surface-active: rgba(255, 255, 255, .12);--glass: rgba(255, 255, 255, .06);--glass-border: rgba(255, 255, 255, .1);--glass-border-strong: rgba(255, 255, 255, .15);--text: rgba(255, 255, 255, .92);--text-secondary: rgba(255, 255, 255, .55);--text-tertiary: rgba(255, 255, 255, .5);--text-on-accent: #ffffff;--accent: #0A84FF;--accent-dim: rgba(10, 132, 255, .15);--green: #30D158;--green-dim: rgba(48, 209, 88, .15);--orange: rgba(255, 255, 255, .55);--orange-dim: rgba(255, 255, 255, .06);--red: #FF453A;--red-dim: rgba(255, 69, 58, .15);--purple: #BF5AF2;--purple-dim: rgba(191, 90, 242, .15);--cyan: #64D2FF;--cyan-dim: rgba(100, 210, 255, .15);--separator: rgba(255, 255, 255, .08);--sidebar-bg: rgba(255, 255, 255, .03);--scrollbar: rgba(255, 255, 255, .1);--scrollbar-hover: rgba(255, 255, 255, .2);--shadow-sm: 0 1px 3px rgba(0, 0, 0, .3);--thumb-bg: #ffffff;--radius-sm: 10px;--radius-md: 14px;--radius-lg: 20px;--radius-xl: 26px;--font-xs: 11px;--font-sm: 12px;--font-md: 13px;--font-base: 14px;--font-lg: 16px;--font-xl: 20px;--font-mono: "SF Mono", "Fira Code", "Cascadia Code", monospace;--space-xs: 4px;--space-sm: 8px;--space-md: 12px;--space-lg: 16px;--space-xl: 24px;--space-2xl: 32px;--blur: 40px;--blur-heavy: 80px}html,body{height:100%}body{font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;background:var(--bg);color:var(--text);line-height:1.5;font-size:14px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#root{min-height:100vh}.container{display:flex;min-height:100vh}.sidebar{width:220px;padding:20px 12px;background:var(--sidebar-bg);border-right:1px solid var(--separator);display:flex;flex-direction:column;gap:4px;position:sticky;top:0;height:100vh;overflow-y:auto}.sidebar-brand{padding:4px 12px 20px;font-size:15px;font-weight:600;letter-spacing:-.2px;color:var(--text)}.sidebar nav{display:flex;flex-direction:column;gap:2px}.sidebar a{display:flex;align-items:center;gap:10px;padding:8px 12px;border-radius:var(--radius-sm);color:var(--text-secondary);text-decoration:none;font-size:13px;font-weight:500;transition:all .2s ease}.sidebar a:hover{color:var(--text);background:var(--surface);text-decoration:none}.sidebar a.active{color:var(--text);background:var(--surface-hover);text-decoration:none}.sidebar-link-disabled{display:flex;align-items:center;gap:10px;padding:8px 12px;border-radius:var(--radius-sm);color:var(--text-tertiary);font-size:13px;font-weight:500;opacity:.4;cursor:default;-webkit-user-select:none;user-select:none}.main{flex:1;padding:32px;max-width:1080px;min-width:0;margin:0 auto}.header{margin-bottom:28px}.header h1{font-size:22px;font-weight:600;letter-spacing:-.4px;margin-bottom:4px}.header p{color:var(--text-secondary);font-size:13px}.card{background:var(--glass);backdrop-filter:blur(var(--blur)) saturate(180%);-webkit-backdrop-filter:blur(var(--blur)) saturate(180%);border:1px solid var(--glass-border);border-radius:var(--radius-lg);padding:20px;margin-bottom:16px}.card h2{font-size:15px;font-weight:600;letter-spacing:-.2px}.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin-bottom:20px}.stat-card{background:var(--glass);backdrop-filter:blur(var(--blur)) saturate(180%);-webkit-backdrop-filter:blur(var(--blur)) saturate(180%);border:1px solid var(--glass-border);border-radius:var(--radius-md);padding:16px}.stat-card h3{font-size:12px;font-weight:500;color:var(--text-secondary);margin-bottom:6px;text-transform:uppercase;letter-spacing:.5px}.stat-card .value{font-size:24px;font-weight:600;letter-spacing:-.5px}button{font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;background:var(--accent);color:var(--text-on-accent);border:none;padding:8px 16px;border-radius:var(--radius-sm);cursor:pointer;font-size:13px;font-weight:500;transition:opacity .15s ease}button:hover{opacity:.85}button:disabled{opacity:.4;cursor:not-allowed}input,textarea,select{font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;background:var(--surface);border:1px solid var(--glass-border);color:var(--text);padding:10px 14px;border-radius:var(--radius-sm);font-size:13px;outline:none;transition:border-color .2s ease}select{-moz-appearance:none;appearance:none;-webkit-appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='rgba(255,255,255,0.55)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 12px center;padding-right:36px;cursor:pointer}.custom-select{position:relative}.custom-select-trigger{width:100%;display:flex;align-items:center;justify-content:space-between;background:var(--surface);border:1px solid var(--glass-border);color:var(--text);padding:10px 14px;border-radius:var(--radius-sm);font-size:13px;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;cursor:pointer;transition:border-color .2s ease}.custom-select-trigger:hover{border-color:var(--glass-border-strong);opacity:1}.custom-select-trigger:focus{border-color:var(--accent)}.custom-select-trigger svg{color:var(--text-secondary);flex-shrink:0}.custom-select-menu{background:var(--bg);border:1px solid var(--glass-border-strong);border-radius:var(--radius-sm);padding:4px;z-index:10000;box-shadow:0 8px 24px #00000080;max-height:200px;overflow-y:auto}.custom-select-option{padding:8px 12px;border-radius:6px;font-size:13px;color:var(--text-secondary);cursor:pointer;transition:all .1s ease}.custom-select-option:hover,.custom-select-option.focused,.custom-select-option.active{background:var(--surface-hover);color:var(--text)}.custom-select-option.active.focused{background:var(--surface-active);color:var(--text)}input:focus,textarea:focus,select:focus{border-color:var(--accent)}input::placeholder,textarea::placeholder{color:var(--text-tertiary)}textarea{width:100%;min-height:400px;font-family:SF Mono,Fira Code,Cascadia Code,monospace;font-size:13px;line-height:1.6;resize:vertical;border-radius:var(--radius-md)}a{color:var(--accent);text-decoration:none}a:hover{text-decoration:none;opacity:.8}.badge{display:inline-flex;align-items:center;padding:2px 7px;border-radius:4px;font-size:11px;font-weight:500;letter-spacing:.2px;background:var(--surface);color:var(--text-secondary);border:1px solid var(--separator)}.badge.count{color:var(--text)}.badge.warn{color:var(--text-secondary);border-color:#ffffff1f}.badge.error{color:var(--red);border-color:color-mix(in srgb,var(--red) 30%,transparent)}.badge.always{color:var(--green);border-color:color-mix(in srgb,var(--green) 30%,transparent)}.tabs{display:flex;gap:2px;padding:3px;background:var(--surface);border:1px solid var(--glass-border);border-radius:var(--radius-sm);margin-bottom:16px}.tab{position:relative;padding:7px 16px;background:none;border:none;color:var(--text-secondary);cursor:pointer;border-radius:8px;font-size:13px;font-weight:500;transition:all .2s ease;flex:1;text-align:center}.tab:hover{color:var(--text);opacity:1}.tab.active{color:var(--text);background:var(--surface-active);box-shadow:0 1px 3px #0003}.tab .tab-count{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;margin-left:6px;border-radius:9px;font-size:11px;font-weight:600;background:var(--glass);color:var(--text-tertiary)}.tab.active .tab-count{background:var(--surface-active);color:var(--text)}button.btn-ghost{background:var(--surface);color:var(--text-secondary);border:1px solid var(--glass-border)}button.btn-ghost:hover{background:var(--surface-hover);color:var(--text);opacity:1}button.btn-danger{background:var(--surface);color:var(--text);border:1px solid var(--glass-border)}button.btn-danger:hover{background:var(--surface-hover);opacity:1}button.btn-sm{padding:5px 10px;font-size:12px;border-radius:8px}.tag-pill{display:inline-flex;align-items:center;padding:3px 9px;border-radius:12px;font-size:11px;font-weight:500;background:var(--surface);color:var(--text-secondary);border:1px solid var(--glass-border);cursor:pointer;transition:all .15s ease}.tag-pill:hover,.tag-pill.active{background:var(--surface-hover);color:var(--text);border-color:var(--glass-border-strong)}.form-group{margin-bottom:16px}.form-group label:not(.label-inline):not(.card-toggle):not(.toggle){display:block;margin-bottom:6px;font-size:13px;font-weight:500;color:var(--text)}.alert{padding:10px 14px;border-radius:var(--radius-sm);margin-bottom:16px;font-size:13px}.alert.success,.alert.error{background:#ffffff0a;color:var(--text-secondary);border:1px solid rgba(255,255,255,.08)}.file-row{transition:background-color .15s ease}.file-row:hover{background-color:var(--sidebar-bg)}.icon-button{background:none;border:none;cursor:pointer;padding:4px 6px;font-size:15px;opacity:.5;filter:grayscale(1);transition:opacity .15s,filter .15s}.icon-button:hover{opacity:1;filter:none}.log-entry{font-family:SF Mono,Fira Code,Cascadia Code,monospace;font-size:12px;padding:5px 0;border-bottom:1px solid var(--separator);line-height:1.5}.log-entry:last-child{border-bottom:none}.accordion-header{position:relative;z-index:2;padding:14px 16px;cursor:pointer;display:flex;align-items:center;gap:12px;transition:background-color .15s ease}.accordion-header:hover{background-color:var(--sidebar-bg)}.accordion-chevron{font-size:10px;color:var(--text-secondary);width:12px;flex-shrink:0}.tool-row{position:relative;padding:10px 14px;background:var(--surface);border-radius:var(--radius-sm);display:flex;justify-content:space-between;align-items:center;transition:background .15s ease}.tool-row:hover{background:var(--surface-hover)}.tool-name{font-size:13px;font-weight:500;margin-bottom:2px}.tool-desc{font-size:12px;color:var(--text-secondary)}.plugin-meta{font-size:12px;color:var(--text-secondary);margin-bottom:8px}.result-item{padding:14px;background:var(--surface);border-radius:var(--radius-sm);margin-bottom:8px}.result-meta{font-size:12px;color:var(--text-secondary);margin-bottom:6px}.result-text{font-size:13px;line-height:1.6}.status-dot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:6px}.status-dot.connected{background:var(--green)}.status-dot.disconnected{background:var(--red)}.login-container{display:flex;align-items:center;justify-content:center;min-height:100vh;padding:2rem}.login-card{background:var(--glass);backdrop-filter:blur(var(--blur)) saturate(180%);-webkit-backdrop-filter:blur(var(--blur)) saturate(180%);border:1px solid var(--glass-border);border-radius:var(--radius-xl);padding:32px;max-width:380px;width:100%}.login-card h1{font-size:20px;font-weight:600;margin-bottom:8px;letter-spacing:-.3px}.login-card p{color:var(--text-secondary);font-size:13px;margin-bottom:24px;line-height:1.5}.section-title{font-size:13px;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.5px;margin-bottom:12px}.empty{color:var(--text-tertiary);font-size:13px;padding:20px 0;text-align:center}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--scrollbar);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:var(--scrollbar-hover)}.scope-seg{display:inline-flex;padding:3px;background:var(--glass);border-radius:10px;gap:2px}.scope-seg button{padding:4px 10px;font-size:11px;font-weight:500;background:none;color:var(--text-tertiary);border:none;border-radius:7px;cursor:pointer;transition:all .2s ease}.scope-seg button:hover:not(:disabled):not(.active){color:var(--text-secondary);opacity:1}.scope-seg button.active{background:var(--surface-active);color:var(--text)}.scope-seg.lg{padding:4px;border-radius:12px;gap:4px;width:100%}.scope-seg.lg button{flex:1;padding:10px 20px;font-size:14px;font-weight:600;border-radius:8px}.scope-seg.disabled{opacity:.4;pointer-events:none}.toggle{position:relative;width:42px;height:26px;flex-shrink:0;cursor:pointer}.toggle input{opacity:0;width:0;height:0;position:absolute}.toggle-track{position:absolute;top:0;right:0;bottom:0;left:0;background:var(--scrollbar);border-radius:13px;transition:background .25s ease}.toggle input:checked+.toggle-track{background:var(--accent)}.toggle-thumb{position:absolute;top:3px;left:3px;width:20px;height:20px;background:var(--thumb-bg);border-radius:50%;transition:transform .25s cubic-bezier(.4,0,.2,1);box-shadow:var(--shadow-sm)}.toggle input:checked~.toggle-thumb{transform:translate(16px)}.toggle input:disabled+.toggle-track{opacity:.4}.toggle input:disabled~.toggle-thumb{opacity:.4}.modal-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#0009;display:flex;align-items:center;justify-content:center;z-index:100}.modal{background:var(--bg);border:1px solid var(--glass-border-strong);border-radius:var(--radius-lg);padding:24px;max-width:480px;width:90%;max-height:80vh;overflow-y:auto;box-shadow:0 16px 48px #00000080}.loading{color:var(--text-tertiary);font-size:13px;padding:40px 0;text-align:center}.setup-container{max-width:720px;margin:0 auto;padding:40px 24px;min-height:100vh}.setup-header{margin-bottom:32px}.setup-header h1{font-size:22px;font-weight:600;letter-spacing:-.4px;margin-bottom:8px}.setup-content{margin-top:28px}.setup-nav{display:flex;gap:10px;margin-top:20px;padding-top:16px;border-top:1px solid var(--separator);max-width:720px}.step-indicator{display:flex;align-items:flex-start;padding:16px 0;margin-bottom:12px;max-width:720px}.step-cell{display:flex;flex-direction:column;align-items:flex-start;flex:1;min-width:0;position:relative}.step-cell:last-child{flex:0 0 auto}.step-cell-top{display:flex;align-items:center;width:100%}.step-dot{width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:600;flex-shrink:0;background:var(--surface);color:var(--text-tertiary);border:1px solid var(--glass-border);transition:all .2s ease}.step-dot.active{background:var(--surface-active);color:var(--text);border-color:var(--glass-border-strong)}.step-dot.completed{background:var(--green-dim);color:var(--green);border-color:#30d1584d}.step-line{flex:1;height:1px;background:var(--glass-border);margin:0 8px;min-width:8px}.step-line.completed{background:#30d1584d}.step-label{font-size:10px;color:var(--text-primary);opacity:.3;text-align:center;white-space:nowrap;margin-top:6px;width:28px;position:relative;left:0;transition:opacity .2s ease}.step-label{overflow:visible;width:max-content;transform:translate(calc(12px - 50%))}.step-label.active{opacity:1;font-weight:500;color:var(--accent)}.step-label.completed{opacity:.5}.provider-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px}.provider-card{background:var(--surface);border:1px solid var(--glass-border);border-radius:var(--radius-md);padding:14px;cursor:pointer;transition:all .15s ease}.provider-card:hover{background:var(--surface-hover);border-color:var(--glass-border-strong)}.provider-card.selected{border-color:#ffffff4d;background:#ffffff14}.provider-card h3{font-size:13px;font-weight:600;margin-bottom:4px}.provider-card .provider-meta{font-size:11px;color:var(--text-secondary)}.mnemonic-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(110px,1fr));gap:6px;margin:12px 0;list-style:none;padding:0}.mnemonic-word{display:flex;align-items:center;gap:6px;padding:6px 8px;background:var(--surface);border-radius:6px;font-size:12px;font-family:SF Mono,Fira Code,monospace}.mnemonic-word .num{color:var(--text-tertiary);font-size:10px;min-width:16px}.guide-dropdown{margin-bottom:20px;border-radius:var(--radius-sm);border:1px solid rgba(255,255,255,.08);background:#ffffff08}.guide-dropdown summary{padding:10px 14px;font-size:13px;font-weight:500;color:var(--text);cursor:pointer;list-style:none;display:flex;align-items:center;gap:8px}.guide-dropdown summary::-webkit-details-marker{display:none}.guide-dropdown summary:before{content:"▶";font-size:9px;color:var(--text-tertiary);transition:transform .2s ease}.guide-dropdown[open] summary:before{transform:rotate(90deg)}.guide-dropdown summary:hover{color:var(--text)}.guide-content{padding:0 14px 14px;font-size:13px;line-height:1.6;color:var(--text-secondary);border-top:1px solid rgba(255,255,255,.06)}.guide-section{margin-top:12px}.guide-section strong{color:var(--text);font-size:12px;text-transform:uppercase;letter-spacing:.5px}.guide-section ol{margin:6px 0 0 20px;padding:0}.guide-section ol li{margin-bottom:4px}.guide-section p{margin:6px 0 0}.guide-section code{background:#ffffff14;padding:1px 5px;border-radius:3px;font-size:12px}.warning-card{padding:14px 16px;border-radius:var(--radius-sm);margin-bottom:16px;font-size:13px;line-height:1.6;background:#ffffff0a;color:var(--text-secondary);border:1px solid rgba(255,255,255,.08)}.warning-card strong{color:var(--text)}.info-panel{padding:12px 14px;border-radius:var(--radius-sm);margin-bottom:16px;font-size:13px;line-height:1.5;background:#ffffff0a;color:var(--text-secondary);border:1px solid rgba(255,255,255,.08)}.code-input{text-align:center;font-size:24px;font-weight:600;letter-spacing:8px;padding:12px 20px;max-width:200px;font-family:SF Mono,Fira Code,monospace}.step-title{font-size:var(--font-lg);font-weight:600;letter-spacing:-.2px;margin-bottom:var(--space-xs)}.step-description{font-size:var(--font-md);color:#ffffffbf;margin-bottom:var(--space-lg)}.helper-text{font-size:var(--font-sm);color:var(--text-secondary);margin-top:var(--space-xs)}.helper-text.error{color:var(--red)}.helper-text.success{color:var(--green)}.form-row{display:flex;align-items:center;gap:var(--space-sm)}.label-inline{display:flex;align-items:flex-start;gap:12px;cursor:pointer}.info-box{padding:var(--space-md) 14px;border-radius:var(--radius-sm);font-size:var(--font-md);line-height:1.5;background:var(--surface);color:var(--text-secondary);border:1px solid var(--separator);margin-bottom:var(--space-lg)}.code-block{display:inline-block;padding:10px 20px;background:var(--surface);border-radius:var(--radius-sm);font-size:var(--font-base);font-family:var(--font-mono)}.mono{font-family:var(--font-mono)}.text-center{text-align:center}.text-muted{color:var(--text-secondary)}.w-full{width:100%}.card-toggle{display:flex;align-items:center;justify-content:space-between}.card-toggle.open{margin-bottom:var(--space-md)}.module-list{display:flex;flex-direction:column}.module-item{padding:14px 0;border-bottom:1px solid var(--glass-border)}.module-item:first-child{padding-top:0}.module-item:last-child{border-bottom:none}.module-header{display:flex;align-items:center;justify-content:space-between;gap:12px}.module-info{display:flex;flex-direction:column;gap:2px}.module-info strong{font-size:var(--font-md)}.module-desc{font-size:var(--font-sm);color:var(--text-tertiary)}.module-body{margin-top:var(--space-md);padding-top:var(--space-sm)}.review-list{display:flex;flex-direction:column;gap:var(--space-xs);font-size:var(--font-md)}.review-label{color:var(--text-secondary)}.review-unset{color:var(--text-tertiary);font-style:italic}.label-inline input[type=checkbox],.label-inline input[type=radio]{-moz-appearance:none;appearance:none;-webkit-appearance:none;width:18px;height:18px;padding:0;flex-shrink:0;border:1.5px solid var(--glass-border-strong);background:var(--surface);cursor:pointer;transition:all .15s ease;position:relative;margin-top:3px}.label-inline input[type=checkbox]{border-radius:5px}.label-inline input[type=radio]{border-radius:50%}.label-inline input[type=checkbox]:checked{background:var(--accent);border-color:var(--accent)}.label-inline input[type=checkbox]:checked:after{content:"";position:absolute;left:5px;top:2px;width:5px;height:9px;border:solid var(--text-on-accent);border-width:0 2px 2px 0;transform:rotate(45deg)}.label-inline input[type=radio]:checked{border-color:var(--accent);background:var(--surface)}.label-inline input[type=radio]:checked:after{content:"";position:absolute;top:4px;left:4px;width:8px;height:8px;border-radius:50%;background:var(--accent)}.label-inline input[type=checkbox]:focus-visible,.label-inline input[type=radio]:focus-visible{outline:2px solid var(--accent);outline-offset:2px}button.btn-lg{padding:12px 24px;font-size:var(--font-base);font-weight:600}.step-content{animation:step-fade-in .15s ease-out;max-width:720px}@keyframes step-fade-in{0%{opacity:0}to{opacity:1}}.provider-switch-zone{padding:14px 16px;background:var(--surface);border:1px solid var(--glass-border-strong);border-radius:var(--radius-sm);animation:step-fade-in .15s ease-out}.spinner{display:inline-block;width:14px;height:14px;border:2px solid var(--glass-border);border-top-color:currentColor;border-radius:50%;animation:spin .6s linear infinite;vertical-align:middle}.spinner.sm{width:12px;height:12px;border-width:1.5px}@keyframes spin{to{transform:rotate(360deg)}}@media(max-width:768px){.container{flex-direction:column}.sidebar{width:100%;height:auto;position:relative;flex-direction:row;overflow-x:auto;padding:12px;border-right:none;border-bottom:1px solid var(--separator)}.sidebar-brand{padding:0 12px 0 4px}.sidebar-brand img{height:32px!important}.sidebar nav{flex-direction:row;gap:2px}.sidebar a{white-space:nowrap;padding:6px 10px}.step-indicator{padding:12px 0;margin-bottom:8px}.step-dot{width:22px;height:22px;font-size:9px}.step-label{font-size:8px}.main{padding:20px 16px}button{min-height:44px;padding:10px 16px}button.btn-sm,button.btn-ghost{min-height:36px}input,textarea,select,.custom-select-trigger{min-height:44px;font-size:16px}}.pill-bar{display:inline-flex;gap:var(--space-sm);padding:var(--space-xs);background:var(--surface);border:1px solid var(--glass-border);border-radius:var(--radius-md);margin-bottom:var(--space-xl);overflow-x:auto}.pill-bar button{padding:var(--space-sm) var(--space-lg);border-radius:var(--radius-sm);border:none;background:transparent;color:var(--text-secondary);font-size:var(--font-md);font-weight:500;cursor:pointer;white-space:nowrap;transition:all .15s ease}.pill-bar button:hover{color:var(--text);background:var(--surface-hover)}.pill-bar button.active{background:var(--accent);color:var(--text-on-accent)}