chatlab-cli 0.26.0 → 0.26.1

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.
Files changed (66) hide show
  1. package/dist/{chat-command-ZP4WJVWC.mjs → chat-command-T3Z4O4M5.mjs} +4 -4
  2. package/dist/{chunk-WXC6RZCX.mjs → chunk-3APSMVOM.mjs} +2 -2
  3. package/dist/{chunk-ILGSSXOG.mjs → chunk-6O2SW5GL.mjs} +5 -4
  4. package/dist/chunk-6O2SW5GL.mjs.map +1 -0
  5. package/dist/{chunk-SJIOPSMM.mjs → chunk-AZZYKUBR.mjs} +17 -39
  6. package/dist/chunk-AZZYKUBR.mjs.map +1 -0
  7. package/dist/{chunk-IRZRIHIT.mjs → chunk-FACKH2BR.mjs} +2 -2
  8. package/dist/{chunk-TC74HESZ.mjs → chunk-FAOZNMPK.mjs} +2 -2
  9. package/dist/{chunk-QY67NN65.mjs → chunk-GUGKY2GV.mjs} +329 -250
  10. package/dist/chunk-GUGKY2GV.mjs.map +1 -0
  11. package/dist/{chunk-UB4XBM4R.mjs → chunk-MZG2GLJR.mjs} +2 -2
  12. package/dist/{chunk-6G7AIF7I.mjs → chunk-SC77N66X.mjs} +9 -9
  13. package/dist/cli.mjs +3 -3
  14. package/dist/{http-J3IOFFIA.mjs → http-6LQUOYQ6.mjs} +8 -8
  15. package/dist/{import-POYG5LOX.mjs → import-B2MAIBAK.mjs} +4 -4
  16. package/dist/index.mjs +8 -8
  17. package/dist/{mcp-7HH7UMXT.mjs → mcp-ZMMYW46I.mjs} +4 -4
  18. package/dist/{stream-import-O3H3FGV2.mjs → stream-import-FHFBCEDV.mjs} +3 -3
  19. package/dist-web/assets/DebugToolsPanel.vue_vue_type_script_setup_true_lang-CgtTQTfN.js +182 -0
  20. package/dist-web/assets/MessageExportModal-B8DKeSAH.js +1 -0
  21. package/dist-web/assets/{electron-B3DFm1cC.js → electron-C-aMus7e.js} +1 -1
  22. package/dist-web/assets/{electron-BMM4Nfty.js → electron-dBbXcMDB.js} +1 -1
  23. package/dist-web/assets/{fetch-BGfaAqO9.js → fetch-B-LdQP9s.js} +1 -1
  24. package/dist-web/assets/{fetch-BaJDB31c.js → fetch-B26JuD67.js} +1 -1
  25. package/dist-web/assets/{fetch-BjDJgdN0.js → fetch-BLKibnXa.js} +1 -1
  26. package/dist-web/assets/{fetch-BFtuJaa1.js → fetch-BNNqdS2B.js} +1 -1
  27. package/dist-web/assets/fetch-BSJY7tRo.js +1 -0
  28. package/dist-web/assets/{fetch-C5CLcpQW.js → fetch-CV8jezsM.js} +1 -1
  29. package/dist-web/assets/{fetch-DQZvdHnG.js → fetch-CvnJ4Jgf.js} +1 -1
  30. package/dist-web/assets/{fetch-ArMjdMcy.js → fetch-DP3yNfJM.js} +1 -1
  31. package/dist-web/assets/{fetch-SYrb-sZe.js → fetch-phbrO2bY.js} +1 -1
  32. package/dist-web/assets/{fetch-Dhfbt1BQ.js → fetch-xB6cl_1L.js} +1 -1
  33. package/dist-web/assets/index-8Zcs8peI.css +1 -0
  34. package/dist-web/assets/index-B_lOzUD8.js +2 -0
  35. package/dist-web/assets/index-BvWcJc3c.js +173 -0
  36. package/dist-web/assets/{index-D7_ch4zf.js → index-CSDI5pAA.js} +2 -2
  37. package/dist-web/assets/{index-CGNgUIT-.css → index-CX2FucK5.css} +1 -1
  38. package/dist-web/assets/{index-DK9LEEzT.js → index-DJQFNVUJ.js} +1 -1
  39. package/dist-web/assets/index-DZ6Szt_y.js +163 -0
  40. package/dist-web/assets/index-DhpclWeF.js +11 -0
  41. package/dist-web/assets/index-Dhql4DJr.css +1 -0
  42. package/dist-web/assets/{web-zEXsvoZW.js → web-DUQU-v8U.js} +1 -1
  43. package/dist-web/index.html +2 -2
  44. package/package.json +1 -1
  45. package/dist/chunk-ILGSSXOG.mjs.map +0 -1
  46. package/dist/chunk-QY67NN65.mjs.map +0 -1
  47. package/dist/chunk-SJIOPSMM.mjs.map +0 -1
  48. package/dist-web/assets/DebugToolsPanel.vue_vue_type_script_setup_true_lang-BTJxEma5.js +0 -182
  49. package/dist-web/assets/MessageExportModal-C7NgEL8T.js +0 -1
  50. package/dist-web/assets/fetch-DnEP0uyF.js +0 -1
  51. package/dist-web/assets/index-C3A_Rjh-.css +0 -1
  52. package/dist-web/assets/index-CWfkrx37.js +0 -173
  53. package/dist-web/assets/index-D3N4NDFx.css +0 -1
  54. package/dist-web/assets/index-DqDa_on9.js +0 -9
  55. package/dist-web/assets/index-DrN1G9bl.js +0 -2
  56. package/dist-web/assets/index-MdYeovYo.js +0 -163
  57. /package/dist/{chat-command-ZP4WJVWC.mjs.map → chat-command-T3Z4O4M5.mjs.map} +0 -0
  58. /package/dist/{chunk-WXC6RZCX.mjs.map → chunk-3APSMVOM.mjs.map} +0 -0
  59. /package/dist/{chunk-IRZRIHIT.mjs.map → chunk-FACKH2BR.mjs.map} +0 -0
  60. /package/dist/{chunk-TC74HESZ.mjs.map → chunk-FAOZNMPK.mjs.map} +0 -0
  61. /package/dist/{chunk-UB4XBM4R.mjs.map → chunk-MZG2GLJR.mjs.map} +0 -0
  62. /package/dist/{chunk-6G7AIF7I.mjs.map → chunk-SC77N66X.mjs.map} +0 -0
  63. /package/dist/{http-J3IOFFIA.mjs.map → http-6LQUOYQ6.mjs.map} +0 -0
  64. /package/dist/{import-POYG5LOX.mjs.map → import-B2MAIBAK.mjs.map} +0 -0
  65. /package/dist/{mcp-7HH7UMXT.mjs.map → mcp-ZMMYW46I.mjs.map} +0 -0
  66. /package/dist/{stream-import-O3H3FGV2.mjs.map → stream-import-FHFBCEDV.mjs.map} +0 -0
@@ -6,9 +6,9 @@ const __filename = __fileURLToPath(import.meta.url);
6
6
  const __dirname = __pathDirname(__filename);
7
7
  import {
8
8
  createCliRunAgentStream
9
- } from "./chunk-ILGSSXOG.mjs";
10
- import "./chunk-IRZRIHIT.mjs";
11
- import "./chunk-QY67NN65.mjs";
9
+ } from "./chunk-6O2SW5GL.mjs";
10
+ import "./chunk-FACKH2BR.mjs";
11
+ import "./chunk-GUGKY2GV.mjs";
12
12
  import "./chunk-VSOWNKPA.mjs";
13
13
 
14
14
  // src/ai/chat-command.ts
@@ -301,4 +301,4 @@ export {
301
301
  runChatCommand,
302
302
  runChatTurn
303
303
  };
304
- //# sourceMappingURL=chat-command-ZP4WJVWC.mjs.map
304
+ //# sourceMappingURL=chat-command-T3Z4O4M5.mjs.map
@@ -10,7 +10,7 @@ import {
10
10
  buildMemberIdMap,
11
11
  generateMessageKey,
12
12
  writeParseResultToDb
13
- } from "./chunk-QY67NN65.mjs";
13
+ } from "./chunk-GUGKY2GV.mjs";
14
14
 
15
15
  // src/import/chatlab-reader.ts
16
16
  import * as fs from "fs";
@@ -384,4 +384,4 @@ export {
384
384
  parseFile,
385
385
  importData
386
386
  };
387
- //# sourceMappingURL=chunk-WXC6RZCX.mjs.map
387
+ //# sourceMappingURL=chunk-3APSMVOM.mjs.map
@@ -7,7 +7,7 @@ const __dirname = __pathDirname(__filename);
7
7
  import {
8
8
  AGENT_TOOL_REGISTRY,
9
9
  CoreDataProvider
10
- } from "./chunk-IRZRIHIT.mjs";
10
+ } from "./chunk-FACKH2BR.mjs";
11
11
  import {
12
12
  AgentEventHandler,
13
13
  AiLogger,
@@ -44,7 +44,7 @@ import {
44
44
  runAgentCore,
45
45
  shouldUseChartCapabilityForMessage,
46
46
  wrapWithChartSchemaGate
47
- } from "./chunk-QY67NN65.mjs";
47
+ } from "./chunk-GUGKY2GV.mjs";
48
48
 
49
49
  // src/ai/logger.ts
50
50
  var logger = null;
@@ -112,12 +112,13 @@ function adaptToolsForAgent(tools, getContext, options) {
112
112
  ...result.charts ? { charts: result.charts } : {}
113
113
  } : {};
114
114
  if (result.rawMessages && result.rawMessages.length > 0) {
115
+ const { rawMessages: _rawInData, ...extraDetails } = result.data ?? {};
115
116
  const pipelineResult = applyPreprocessingPipeline({
116
117
  rawMessages: result.rawMessages,
117
118
  locale: ctx.locale,
118
119
  maxToolResultTokens: tokenBudget,
119
120
  truncationStrategy: TOOL_TRUNCATION_STRATEGY[tool.name] ?? "keep_last",
120
- extraDetails: result.data ?? {},
121
+ extraDetails,
121
122
  logger: getServerAiLogger() ?? void 0
122
123
  });
123
124
  return {
@@ -546,4 +547,4 @@ export {
546
547
  closeServerAiLogger,
547
548
  createCliRunAgentStream
548
549
  };
549
- //# sourceMappingURL=chunk-ILGSSXOG.mjs.map
550
+ //# sourceMappingURL=chunk-6O2SW5GL.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ai/logger.ts","../src/ai/tool-adapter.ts","../src/ai/llm-config.ts","../src/ai/assistant-loader.ts","../src/ai/agent.ts","../src/ai/agent-stream-runner.ts"],"sourcesContent":["/**\n * Server 端 AI 日志\n *\n * 复用 @openchatlab/node-runtime 的 AiLogger,\n * 在 startHttpServer() 中通过 initServerAiLogger() 初始化。\n */\n\nimport { AiLogger } from '@openchatlab/node-runtime'\n\nlet logger: AiLogger | null = null\n\nexport function initServerAiLogger(logsDir: string): AiLogger {\n if (!logger) {\n logger = new AiLogger(logsDir)\n }\n return logger\n}\n\nexport function getServerAiLogger(): AiLogger | null {\n return logger\n}\n\nexport function closeServerAiLogger(): void {\n if (logger) {\n logger.close()\n logger = null\n }\n}\n","/**\n * 工具适配层\n *\n * 将 @openchatlab/tools 的 ToolDefinition 适配为 @earendil-works/pi-agent-core 的 AgentTool 格式。\n * 消息类工具返回 rawMessages 时自动执行预处理管道(清洗、去噪、脱敏、截断、格式化)。\n */\n\nimport type { ToolDefinition, ToolExecutionContext } from '@openchatlab/tools'\nimport { CoreDataProvider } from '@openchatlab/tools'\nimport type { DatabaseAdapter } from '@openchatlab/core'\nimport {\n applyPreprocessingPipeline,\n batchSegmentWithFrequency,\n type AgentTool,\n type AgentToolResult,\n type PreprocessableMessage,\n type TruncationStrategy,\n createChartSchemaGateState,\n wrapWithChartSchemaGate,\n} from '@openchatlab/node-runtime'\nimport { getServerAiLogger } from './logger'\n\nconst DEFAULT_MAX_TOOL_RESULT_TOKENS = 8000\n\nconst TOOL_TRUNCATION_STRATEGY: Record<string, TruncationStrategy> = {\n search_messages: 'keep_first',\n deep_search_messages: 'keep_first',\n get_recent_messages: 'keep_last',\n get_message_context: 'keep_last',\n get_segment_messages: 'keep_last',\n get_conversation_between: 'keep_last',\n}\n\nexport interface ServerToolContext {\n db: DatabaseAdapter\n sessionId: string\n locale?: string\n}\n\nfunction convertJsonSchemaToParameters(schema: ToolDefinition['inputSchema']) {\n const properties: Record<string, unknown> = {}\n for (const [key, prop] of Object.entries(schema.properties)) {\n properties[key] = { ...prop }\n }\n return {\n type: 'object' as const,\n properties,\n required: schema.required || [],\n }\n}\n\nexport interface AdaptToolsOptions {\n maxToolResultTokens?: number\n}\n\nexport function adaptToolsForAgent(\n tools: ToolDefinition[],\n getContext: () => ServerToolContext,\n options?: AdaptToolsOptions\n): AgentTool<any, any>[] {\n const tokenBudget = options?.maxToolResultTokens ?? DEFAULT_MAX_TOOL_RESULT_TOKENS\n const chartSchemaGateState = createChartSchemaGateState()\n\n return tools.map((tool) =>\n wrapWithChartSchemaGate(\n {\n name: tool.name,\n label: tool.name,\n description: tool.description,\n parameters: convertJsonSchemaToParameters(tool.inputSchema) as any,\n async execute(_toolCallId: string, params: unknown): Promise<AgentToolResult<unknown>> {\n const toolParams = (params && typeof params === 'object' ? params : {}) as Record<string, unknown>\n const ctx = getContext()\n const execCtx: ToolExecutionContext = {\n db: ctx.db,\n dataProvider: new CoreDataProvider(ctx.db),\n sessionId: ctx.sessionId,\n locale: ctx.locale,\n segmentText: (texts, locale, options) => batchSegmentWithFrequency(texts, locale as any, options as any),\n }\n try {\n const result = await tool.handler(toolParams, execCtx)\n const chartDetails =\n result.chart || result.charts\n ? {\n ...(result.chart ? { chart: result.chart } : {}),\n ...(result.charts ? { charts: result.charts } : {}),\n }\n : {}\n\n if (result.rawMessages && result.rawMessages.length > 0) {\n // tools may mirror rawMessages inside data; keep it out of extraDetails\n // so the pipeline only renders scalar metadata (same as the desktop adapter)\n const { rawMessages: _rawInData, ...extraDetails } = (result.data ?? {}) as Record<string, unknown>\n const pipelineResult = applyPreprocessingPipeline({\n rawMessages: result.rawMessages as PreprocessableMessage[],\n locale: ctx.locale,\n maxToolResultTokens: tokenBudget,\n truncationStrategy: TOOL_TRUNCATION_STRATEGY[tool.name] ?? 'keep_last',\n extraDetails,\n logger: getServerAiLogger() ?? undefined,\n })\n return {\n content: [{ type: 'text', text: pipelineResult.text }],\n details: Object.keys(chartDetails).length > 0 ? chartDetails : null,\n }\n }\n\n const baseDetails =\n typeof result.data === 'object' && result.data !== null\n ? (result.data as Record<string, unknown>)\n : result.data === undefined\n ? null\n : { value: result.data }\n\n return {\n content: [{ type: 'text', text: result.content }],\n details: Object.keys(chartDetails).length > 0 ? { ...(baseDetails ?? {}), ...chartDetails } : baseDetails,\n }\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error)\n return { content: [{ type: 'text', text: `Error: ${msg}` }], details: null }\n }\n },\n },\n chartSchemaGateState\n )\n )\n}\n","/**\n * 服务端 LLM 配置加载\n *\n * API Key 从 ~/.chatlab/auth-profiles.json 读取,\n * 匹配顺序:config.authProfile 精确匹配 > config.provider 兜底匹配。\n *\n * 模型/Provider 等配置仍从 llm-config.json 读取。\n */\n\nimport * as fs from 'fs'\nimport * as path from 'path'\nimport type { PiModel, PiApi } from '@openchatlab/node-runtime'\nimport { buildPiModel as buildPiModelCore, type PiModelConfig } from '@openchatlab/node-runtime'\nimport { resolveApiKey, writeAuthProfile } from '@openchatlab/config'\nimport { randomUUID } from 'crypto'\n\n// ==================== Types ====================\n\nexport interface AIServiceConfig {\n id: string\n name: string\n provider: string\n apiKey: string\n model?: string\n baseUrl?: string\n maxTokens?: number\n apiFormat?: string\n customModels?: Array<{ id: string; name: string }>\n authProfile?: string\n}\n\ninterface ModelSlot {\n configId: string\n modelId?: string\n}\n\ninterface AIConfigStore {\n configs: AIServiceConfig[]\n defaultAssistant: ModelSlot | null\n fastModel: ModelSlot | null\n}\n\n// ==================== Config Loading ====================\n\nexport function loadLlmConfig(aiDataDir: string): AIConfigStore {\n const configPath = path.join(aiDataDir, 'llm-config.json')\n if (!fs.existsSync(configPath)) {\n return { configs: [], defaultAssistant: null, fastModel: null }\n }\n\n try {\n const data = JSON.parse(fs.readFileSync(configPath, 'utf-8'))\n\n const configs = (data.configs || []).map((c: Record<string, unknown>) => {\n const provider = (c.provider as string) || ''\n const authProfile = c.authProfile as string | undefined\n const profileKey = resolveApiKey(provider, authProfile)\n const rawKey = (c.apiKey as string) || ''\n const fallbackKey = rawKey.startsWith('enc:') ? '' : rawKey\n return {\n ...c,\n apiKey: profileKey || fallbackKey,\n }\n })\n return {\n configs,\n defaultAssistant: data.defaultAssistant ?? null,\n fastModel: data.fastModel ?? null,\n }\n } catch {\n return { configs: [], defaultAssistant: null, fastModel: null }\n }\n}\n\nfunction resolveSlot(slot: ModelSlot | null | undefined, configs: AIServiceConfig[]): ModelSlot | null {\n if (slot && configs.some((c) => c.id === slot.configId)) return slot\n const fallback = configs[0]\n if (!fallback) return null\n return { configId: fallback.id, modelId: fallback.model }\n}\n\nexport function getDefaultAssistantConfig(aiDataDir: string): AIServiceConfig | null {\n const store = loadLlmConfig(aiDataDir)\n const slot = resolveSlot(store.defaultAssistant, store.configs)\n if (!slot) return null\n const config = store.configs.find((c) => c.id === slot.configId)\n if (!config) return null\n return { ...config, model: slot.modelId || config.model }\n}\n\n// ==================== Config Write Operations ====================\n\nconst MAX_CONFIG_COUNT = 99\n\nfunction saveLlmConfig(aiDataDir: string, store: AIConfigStore): void {\n const configPath = path.join(aiDataDir, 'llm-config.json')\n const toSave = {\n ...store,\n configs: store.configs.map((c) => {\n const { apiKey: _k, ...rest } = c\n return rest\n }),\n schemaVersion: 3,\n }\n fs.writeFileSync(configPath, JSON.stringify(toSave, null, 2), 'utf-8')\n}\n\nexport function addLlmConfig(\n aiDataDir: string,\n config: Omit<AIServiceConfig, 'id'>\n): { success: boolean; config?: AIServiceConfig; error?: string } {\n const store = loadLlmConfig(aiDataDir)\n\n if (store.configs.length >= MAX_CONFIG_COUNT) {\n return { success: false, error: `Maximum ${MAX_CONFIG_COUNT} configs reached` }\n }\n\n const newConfig: AIServiceConfig = {\n ...config,\n id: randomUUID(),\n }\n\n const storeForSave = loadRawConfigStore(aiDataDir)\n storeForSave.configs.push({\n ...newConfig,\n apiKey: '',\n })\n\n if (storeForSave.configs.length === 1) {\n storeForSave.defaultAssistant = { configId: newConfig.id, modelId: newConfig.model || '' }\n }\n\n if (config.apiKey) {\n const profileName = config.name?.toLowerCase().replace(/\\s+/g, '-') || config.provider\n writeAuthProfile(profileName, {\n type: 'api_key',\n provider: config.provider,\n key: config.apiKey,\n })\n ;(storeForSave.configs[storeForSave.configs.length - 1] as unknown as Record<string, unknown>).authProfile =\n profileName\n }\n\n saveLlmConfig(aiDataDir, storeForSave)\n return { success: true, config: { ...newConfig, apiKey: '' } }\n}\n\nexport function updateLlmConfig(\n aiDataDir: string,\n id: string,\n updates: Partial<Omit<AIServiceConfig, 'id'>>\n): { success: boolean; error?: string } {\n const storeForSave = loadRawConfigStore(aiDataDir)\n const index = storeForSave.configs.findIndex((c) => c.id === id)\n\n if (index === -1) {\n return { success: false, error: 'Config not found' }\n }\n\n const { apiKey: newApiKey, ...restUpdates } = updates\n const updated = {\n ...storeForSave.configs[index],\n ...restUpdates,\n }\n storeForSave.configs[index] = updated\n\n if (newApiKey) {\n const profileName = updated.name?.toLowerCase().replace(/\\s+/g, '-') || updated.provider\n writeAuthProfile(profileName, {\n type: 'api_key',\n provider: updated.provider,\n key: newApiKey,\n })\n ;(storeForSave.configs[index] as unknown as Record<string, unknown>).authProfile = profileName\n }\n\n saveLlmConfig(aiDataDir, storeForSave)\n return { success: true }\n}\n\nexport function deleteLlmConfig(aiDataDir: string, id: string): { success: boolean; error?: string } {\n const storeForSave = loadRawConfigStore(aiDataDir)\n const index = storeForSave.configs.findIndex((c) => c.id === id)\n\n if (index === -1) {\n return { success: false, error: 'Config not found' }\n }\n\n storeForSave.configs.splice(index, 1)\n\n const fallback = storeForSave.configs[0]\n if (storeForSave.defaultAssistant?.configId === id) {\n storeForSave.defaultAssistant = fallback ? { configId: fallback.id, modelId: fallback.model || '' } : null\n }\n if (storeForSave.fastModel?.configId === id) {\n storeForSave.fastModel = fallback ? { configId: fallback.id, modelId: fallback.model || '' } : null\n }\n\n saveLlmConfig(aiDataDir, storeForSave)\n return { success: true }\n}\n\nexport function setDefaultAssistantSlot(\n aiDataDir: string,\n configId: string,\n modelId: string\n): { success: boolean; error?: string } {\n const storeForSave = loadRawConfigStore(aiDataDir)\n const config = storeForSave.configs.find((c) => c.id === configId)\n\n if (!config) {\n return { success: false, error: 'Config not found' }\n }\n\n storeForSave.defaultAssistant = { configId, modelId }\n saveLlmConfig(aiDataDir, storeForSave)\n return { success: true }\n}\n\nexport function setFastModelSlot(aiDataDir: string, slot: ModelSlot | null): { success: boolean; error?: string } {\n const storeForSave = loadRawConfigStore(aiDataDir)\n\n if (slot !== null) {\n const config = storeForSave.configs.find((c) => c.id === slot.configId)\n if (!config) {\n return { success: false, error: 'Config not found' }\n }\n }\n\n storeForSave.fastModel = slot\n saveLlmConfig(aiDataDir, storeForSave)\n return { success: true }\n}\n\nfunction loadRawConfigStore(aiDataDir: string): AIConfigStore {\n const configPath = path.join(aiDataDir, 'llm-config.json')\n if (!fs.existsSync(configPath)) {\n return { configs: [], defaultAssistant: null, fastModel: null }\n }\n try {\n const data = JSON.parse(fs.readFileSync(configPath, 'utf-8'))\n return {\n configs: data.configs || [],\n defaultAssistant: data.defaultAssistant ?? null,\n fastModel: data.fastModel ?? null,\n }\n } catch {\n return { configs: [], defaultAssistant: null, fastModel: null }\n }\n}\n\n// ==================== PiModel Builder ====================\n\nexport function buildPiModel(config: AIServiceConfig): PiModel<PiApi> {\n return buildPiModelCore(config as PiModelConfig)\n}\n","/**\n * 助手配置加载器\n *\n * 从 ~/.chatlab/ai/assistants/*.md 加载助手系统提示词。\n */\n\nimport * as fs from 'fs'\nimport * as path from 'path'\nimport { parseAssistantFile } from '@openchatlab/node-runtime'\nimport type { AssistantConfig } from '@openchatlab/node-runtime'\n\nexport function loadAssistantConfig(aiDataDir: string, assistantId: string): AssistantConfig | null {\n const filePath = path.join(aiDataDir, 'assistants', `${assistantId}.md`)\n if (!fs.existsSync(filePath)) return null\n\n try {\n const content = fs.readFileSync(filePath, 'utf-8')\n return parseAssistantFile(content, filePath)\n } catch {\n return null\n }\n}\n","/**\n * 服务端 Agent\n *\n * 使用 @openchatlab/node-runtime 的 runAgentCore 编排对话流程,\n * 通过 AgentEventHandler 输出与 Electron 端一致的流式事件。\n */\n\nimport {\n DEFAULT_MAX_TOOL_ROUNDS,\n buildPlanGuidance,\n createAnalysisPlanner,\n createLlmRouteDecider,\n createPlanContentBlock,\n decideRequestRoute,\n runAgentCore,\n checkAndCompress,\n buildSystemPrompt,\n createAiTranslate,\n createCompressionLlmAdapter,\n AgentEventHandler,\n formatAIError,\n shouldUseChartCapabilityForMessage,\n getChartPlannerCapabilityForMessage,\n initTokenizer,\n type AgentStreamChunk,\n type PiMessage,\n type SimpleHistoryMessage,\n type AIChatManager,\n type CompressionConfig,\n type AgentTool,\n type DataSnapshot,\n type OwnerInfo,\n type MentionedMember,\n} from '@openchatlab/node-runtime'\nimport type { ChartAutoMode } from '@openchatlab/shared-types'\n\nimport { getDefaultAssistantConfig, buildPiModel } from './llm-config'\nimport { getServerAiLogger } from './logger'\n\nexport type { AgentStreamChunk }\n\nexport interface RunAgentOptions {\n userMessage: string\n aiChatId: string\n historyLeafMessageId?: string | null\n chatType?: 'group' | 'private'\n locale?: string\n assistantSystemPrompt?: string\n skillMenu?: string | null\n skillDef?: { name: string; prompt: string }\n compressionConfig?: CompressionConfig\n tools?: AgentTool[]\n aiDataDir: string\n aiChatManager: AIChatManager\n onEvent: (event: AgentStreamChunk) => void\n abortSignal?: AbortSignal\n ownerInfo?: OwnerInfo\n mentionedMembers?: MentionedMember[]\n dataSnapshot?: DataSnapshot\n thinkingLevel?: string\n chartAutoMode?: ChartAutoMode\n}\n\nexport async function runServerAgent(options: RunAgentOptions): Promise<void> {\n const {\n userMessage,\n aiChatId,\n historyLeafMessageId,\n chatType = 'group',\n locale = 'zh-CN',\n assistantSystemPrompt,\n skillMenu,\n skillDef,\n compressionConfig,\n tools = [],\n aiDataDir,\n aiChatManager,\n onEvent,\n abortSignal,\n ownerInfo,\n mentionedMembers,\n dataSnapshot,\n thinkingLevel,\n chartAutoMode = 'suggest',\n } = options\n\n const aiLogger = getServerAiLogger()\n\n // 确保 tokenizer rank 表已加载(compression + agent 路径均依赖)\n await initTokenizer()\n\n const llmConfig = getDefaultAssistantConfig(aiDataDir)\n if (!llmConfig) {\n onEvent({ type: 'error', error: { name: 'ConfigError', message: 'LLM service not configured' } })\n onEvent({ type: 'done', isFinished: true })\n return\n }\n\n const piModel = buildPiModel(llmConfig)\n const t = createAiTranslate(locale)\n\n let skillCtx: { skillDef?: { name: string; prompt: string }; skillMenu?: string } | undefined\n if (skillDef) {\n skillCtx = { skillDef }\n } else if (skillMenu) {\n skillCtx = { skillMenu }\n }\n\n const systemPrompt = buildSystemPrompt({\n t,\n chatType,\n assistantSystemPrompt,\n ownerInfo,\n locale,\n skillCtx,\n mentionedMembers,\n dataSnapshot,\n })\n\n const handler = new AgentEventHandler({\n onChunk: onEvent,\n context: {},\n systemPrompt,\n })\n\n if (compressionConfig?.enabled && historyLeafMessageId === undefined) {\n const llmAdapter = createCompressionLlmAdapter({\n piModel,\n apiKey: llmConfig.apiKey,\n onCompressing: () => handler.emitStatus('compressing', []),\n })\n const compressionResult = await checkAndCompress(\n aiChatId,\n compressionConfig,\n systemPrompt,\n llmAdapter,\n aiChatManager,\n aiLogger ?? undefined\n )\n if (compressionResult.compressed) {\n onEvent({\n type: 'compression_done',\n compressionResult: {\n summaryContent: compressionResult.summaryContent ?? '',\n tokensBefore: compressionResult.tokensBefore ?? 0,\n tokensAfter: compressionResult.tokensAfter ?? 0,\n timestamp: Date.now(),\n },\n })\n }\n } else if (compressionConfig?.enabled && historyLeafMessageId !== undefined) {\n aiLogger?.info?.('Compression', 'Skipping compression for edited branch request', {\n aiChatId,\n historyLeafMessageId,\n })\n }\n\n if (abortSignal?.aborted) {\n handler.emitStatus('aborted', [], { force: true })\n onEvent({ type: 'done', isFinished: true, usage: handler.cloneUsage() })\n return\n }\n\n let history: SimpleHistoryMessage[] = []\n try {\n history = aiChatManager.getHistoryForAgent(aiChatId, undefined, historyLeafMessageId)\n } catch {\n // empty history on failure\n }\n\n handler.emitStatus('preparing', [], { pendingUserMessage: userMessage, force: true })\n\n const steerMessage = t('ai.agent.answerWithoutTools')\n let cachedMessages: PiMessage[] = []\n const effectiveTools =\n chartAutoMode === 'explicit' && !shouldUseChartCapabilityForMessage(userMessage)\n ? tools.filter((tool) => tool.name !== 'render_chart')\n : tools\n\n try {\n const routeInput = {\n userMessage,\n chatType,\n locale,\n dataSnapshot,\n availableTools: effectiveTools.map((tool) => tool.name),\n availableCapabilities: [\n getChartPlannerCapabilityForMessage({\n userMessage,\n locale,\n availableTools: effectiveTools.map((tool) => tool.name),\n chartAutoMode,\n }),\n ].filter((capability) => capability !== null),\n skillSummary: skillDef?.name ?? (skillMenu ? 'auto_skill_menu' : undefined),\n }\n const routeStartedAt = Date.now()\n const routeDecision = await decideRequestRoute(routeInput, {\n llmRouter: createLlmRouteDecider({\n piModel,\n apiKey: llmConfig.apiKey,\n abortSignal,\n }),\n })\n aiLogger?.info('Router', 'Shadow route decision', {\n ...routeDecision,\n elapsedMs: Date.now() - routeStartedAt,\n availableToolCount: tools.length,\n shadowOnly: true,\n })\n onEvent({ type: 'route', routeDecision })\n\n let effectiveSystemPrompt = systemPrompt\n if (routeDecision.route === 'planned_execution') {\n const planStartedAt = Date.now()\n const planner = createAnalysisPlanner({\n piModel,\n apiKey: llmConfig.apiKey,\n onPlanDelta: (delta) => onEvent({ type: 'plan_delta', planDelta: delta }),\n onThinkingDelta: (delta) => onEvent({ type: 'think', content: delta, thinkTag: 'thinking' }),\n onThinkingEnd: (durationMs) =>\n onEvent({ type: 'think', content: '', thinkTag: 'thinking', thinkDurationMs: durationMs }),\n onValidationDelta: (delta) => onEvent({ type: 'think', content: delta, thinkTag: 'plan_validation' }),\n onValidationEnd: (durationMs) =>\n onEvent({ type: 'think', content: '', thinkTag: 'plan_validation', thinkDurationMs: durationMs }),\n })\n const plan = await planner(routeInput, abortSignal)\n if (plan) {\n const planBlock = createPlanContentBlock(plan)\n onEvent({ type: 'plan', plan: planBlock })\n effectiveSystemPrompt = `${systemPrompt}\\n\\n${buildPlanGuidance(plan)}`\n aiLogger?.info('Planner', 'Plan generated', {\n title: plan.title,\n steps: plan.steps.length,\n successCriteria: plan.successCriteria.length,\n elapsedMs: Date.now() - planStartedAt,\n })\n } else {\n aiLogger?.warn('Planner', 'Plan generation skipped or failed', {\n elapsedMs: Date.now() - planStartedAt,\n route: routeDecision.route,\n })\n onEvent({ type: 'plan_skipped' })\n }\n }\n\n const result = await runAgentCore({\n piModel,\n apiKey: llmConfig.apiKey,\n systemPrompt: effectiveSystemPrompt,\n tools: effectiveTools,\n history,\n userMessage,\n maxToolRounds: DEFAULT_MAX_TOOL_ROUNDS,\n abortSignal,\n steerMessage,\n thinkingLevel: thinkingLevel as import('@openchatlab/core').ThinkingLevel | undefined,\n onConvertToLlm: (filteredMessages) => {\n cachedMessages = filteredMessages as PiMessage[]\n },\n onEvent: (coreEvent) => handler.handleCoreEvent(coreEvent, cachedMessages),\n onDebugContext: (messages) => {\n try {\n aiChatManager.setPendingDebugContext(aiChatId, JSON.stringify(messages, null, 2))\n } catch {\n // silent\n }\n },\n })\n\n if (result.error) {\n const friendlyMessage = formatAIError(result.error)\n onEvent({ type: 'error', error: { name: 'AgentError', message: friendlyMessage } })\n }\n\n handler.emitStatus('completed', cachedMessages, { force: true })\n onEvent({ type: 'done', isFinished: true, usage: result.usage })\n } catch (error) {\n const friendlyMessage = formatAIError(error)\n aiLogger?.error('ServerAgent', 'Agent execution error', { error: String(error) })\n handler.emitStatus('error', cachedMessages, { force: true })\n onEvent({ type: 'error', error: { name: 'AgentError', message: friendlyMessage } })\n onEvent({ type: 'done', isFinished: true, usage: handler.cloneUsage() })\n }\n}\n","/**\n * CLI Agent stream runner — provides runAgentStream implementation\n * for the shared HTTP route context.\n */\n\nimport type { DatabaseManager, AIChatManager, AgentStreamChunk } from '@openchatlab/node-runtime'\nimport {\n CHART_CAPABILITY_CORE_TOOLS,\n SkillManager,\n buildSkillMenuWithBuiltinChart,\n createActivateSkillTool,\n createDataSnapshotFromOverview,\n getAllowedBuiltinToolsForChartAutoSkill,\n getChartCapabilitySkill,\n getSkillConfigWithBuiltinChart,\n resolveChartRuntimeForRequest,\n} from '@openchatlab/node-runtime'\nimport { getChatOverview, normalizeBuiltinToolNames } from '@openchatlab/core'\nimport type { ChartAutoMode } from '@openchatlab/shared-types'\nimport type { DataSnapshot } from '@openchatlab/node-runtime'\nimport type { AgentStreamRequest } from '@openchatlab/http-routes'\nimport { AGENT_TOOL_REGISTRY } from '@openchatlab/tools'\nimport { adaptToolsForAgent } from './tool-adapter'\nimport { getDefaultAssistantConfig, buildPiModel } from './llm-config'\nimport { loadAssistantConfig } from './assistant-loader'\nimport { runServerAgent } from './agent'\n\nfunction getAiDir(dbManager: DatabaseManager): string {\n const pathProvider = (dbManager as any)['pathProvider']\n if (!pathProvider) {\n throw Object.assign(new Error('PathProvider not available'), { statusCode: 500 })\n }\n return pathProvider.getAiDataDir()\n}\n\nconst RAW_SQL_TOOL_NAMES = new Set(['execute_sql'])\n\nexport function getAvailableToolDefs(isChartCapability: boolean, allowedToolSet: Set<string> | null) {\n if (isChartCapability) {\n const chartCoreTools = new Set<string>(CHART_CAPABILITY_CORE_TOOLS)\n return AGENT_TOOL_REGISTRY.filter(\n (tool) =>\n chartCoreTools.has(tool.name) ||\n (tool.category === 'analysis' && allowedToolSet?.has(tool.name) && !RAW_SQL_TOOL_NAMES.has(tool.name))\n )\n }\n\n return allowedToolSet\n ? AGENT_TOOL_REGISTRY.filter((tool) => tool.category !== 'analysis' || allowedToolSet.has(tool.name))\n : AGENT_TOOL_REGISTRY\n}\n\n// 区分“未配置白名单”和“配置为空白名单”:前者无限制,后者禁用 analysis 工具。\nexport function getAllowedToolSet(\n isChartCapability: boolean,\n allowedBuiltinTools?: readonly string[]\n): Set<string> | null {\n if (isChartCapability) {\n return new Set(normalizeBuiltinToolNames(allowedBuiltinTools ?? []))\n }\n return allowedBuiltinTools === undefined ? null : new Set(normalizeBuiltinToolNames(allowedBuiltinTools))\n}\n\nexport function createCliRunAgentStream(\n dbManager: DatabaseManager,\n aiChatManager: AIChatManager\n): (params: AgentStreamRequest, onEvent: (chunk: AgentStreamChunk) => void, abortSignal: AbortSignal) => Promise<void> {\n return async (params, onEvent, abortSignal) => {\n const {\n userMessage,\n aiChatId,\n historyLeafMessageId,\n sessionId,\n chatType,\n locale,\n assistantId,\n skillId,\n enableAutoSkill,\n chartAutoMode,\n compressionConfig,\n ownerInfo,\n mentionedMembers,\n thinkingLevel,\n } = params\n\n const aiDataDir = getAiDir(dbManager)\n\n let assistantSystemPrompt: string | undefined\n let assistantAllowedTools: string[] | undefined\n if (assistantId) {\n const assistantConfig = loadAssistantConfig(aiDataDir, assistantId)\n if (assistantConfig?.systemPrompt) {\n assistantSystemPrompt = assistantConfig.systemPrompt\n }\n assistantAllowedTools = assistantConfig?.allowedBuiltinTools\n }\n\n const llmConfig = getDefaultAssistantConfig(aiDataDir)\n const maxToolResultPercent = compressionConfig?.maxToolResultPercent ?? 50\n const contextWindow = llmConfig ? (buildPiModel(llmConfig).contextWindow ?? 128000) : 128000\n const maxToolResultTokens = Math.floor(contextWindow * (maxToolResultPercent / 100))\n\n const db = (dbManager as any).open?.(sessionId)\n const resolvedChartAutoMode: ChartAutoMode = chartAutoMode ?? 'suggest'\n const chartRuntime = resolveChartRuntimeForRequest({\n skillId,\n userMessage,\n locale,\n assistantAllowedTools,\n enableAutoDetection: enableAutoSkill === true,\n chartAutoMode: resolvedChartAutoMode,\n })\n const isChartCapability = chartRuntime.isChartCapability\n const autoSkillAllowedTools =\n !skillId && enableAutoSkill && resolvedChartAutoMode !== 'explicit'\n ? getAllowedBuiltinToolsForChartAutoSkill(assistantAllowedTools)\n : assistantAllowedTools\n const allowedToolSet = getAllowedToolSet(\n isChartCapability,\n isChartCapability ? chartRuntime.allowedBuiltinTools : autoSkillAllowedTools\n )\n const availableToolDefs = getAvailableToolDefs(isChartCapability, allowedToolSet)\n\n const agentTools = db\n ? adaptToolsForAgent(availableToolDefs, () => ({ db, sessionId, locale }), { maxToolResultTokens })\n : []\n\n const skillMgr = new SkillManager(aiDataDir)\n skillMgr.init()\n const toolNames = agentTools.map((t: { name: string }) => t.name)\n\n let resolvedSkillDef: { name: string; prompt: string } | undefined\n let resolvedSkillMenu: string | undefined\n if (isChartCapability) {\n const def = chartRuntime.skillDef ?? getChartCapabilitySkill(locale ?? 'zh-CN')\n resolvedSkillDef = { name: def.name, prompt: def.prompt }\n } else if (skillId) {\n const def = skillMgr.getSkillConfig(skillId)\n if (def) resolvedSkillDef = { name: def.name, prompt: def.prompt }\n } else if (enableAutoSkill) {\n const baseMenu = skillMgr.getSkillMenu(chatType ?? 'group', toolNames)\n const menu =\n resolvedChartAutoMode === 'aggressive' ? buildSkillMenuWithBuiltinChart(baseMenu, locale, toolNames) : baseMenu\n if (menu) resolvedSkillMenu = menu\n }\n\n if (resolvedSkillMenu) {\n const activateSkillTool = createActivateSkillTool({\n chatType: chatType ?? 'group',\n allowedTools: toolNames,\n coreToolNames: new Set<string>(CHART_CAPABILITY_CORE_TOOLS),\n locale,\n getSkillConfig: (id) =>\n resolvedChartAutoMode === 'aggressive'\n ? getSkillConfigWithBuiltinChart(id, locale, (skillConfigId) => skillMgr.getSkillConfig(skillConfigId))\n : skillMgr.getSkillConfig(id),\n })\n agentTools.push(activateSkillTool as any)\n }\n\n const resolvedCompression = compressionConfig?.enabled\n ? {\n enabled: true as const,\n tokenThresholdPercent: compressionConfig.tokenThresholdPercent ?? 75,\n bufferSizePercent: compressionConfig.bufferSizePercent ?? 20,\n maxToolResultPercent: compressionConfig.maxToolResultPercent,\n }\n : undefined\n\n let dataSnapshot: DataSnapshot | undefined\n if (db) {\n try {\n dataSnapshot = createDataSnapshotFromOverview(getChatOverview(db, 10))\n } catch {\n // non-fatal\n }\n }\n\n await runServerAgent({\n userMessage,\n aiChatId,\n historyLeafMessageId,\n chatType,\n locale,\n assistantSystemPrompt,\n skillMenu: resolvedSkillMenu,\n skillDef: resolvedSkillDef,\n compressionConfig: resolvedCompression,\n tools: agentTools,\n aiDataDir,\n aiChatManager,\n onEvent,\n abortSignal,\n ownerInfo,\n mentionedMembers,\n dataSnapshot,\n thinkingLevel,\n chartAutoMode: resolvedChartAutoMode,\n })\n }\n}\n"],"mappings":"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","names":["options","buildPiModel","fs","path","buildPiModel","buildPiModel"]}
@@ -7,16 +7,16 @@ const __dirname = __pathDirname(__filename);
7
7
  import {
8
8
  importData,
9
9
  parseFile
10
- } from "./chunk-WXC6RZCX.mjs";
10
+ } from "./chunk-3APSMVOM.mjs";
11
11
  import {
12
12
  analyzeIncrementalImport,
13
13
  analyzeNewImport,
14
14
  incrementalImport,
15
15
  streamImport
16
- } from "./chunk-TC74HESZ.mjs";
16
+ } from "./chunk-FAOZNMPK.mjs";
17
17
  import {
18
18
  assertCliDataDirCompatible
19
- } from "./chunk-UB4XBM4R.mjs";
19
+ } from "./chunk-MZG2GLJR.mjs";
20
20
  import {
21
21
  getVersion
22
22
  } from "./chunk-5ADKYYNA.mjs";
@@ -24,11 +24,11 @@ import {
24
24
  closeServerAiLogger,
25
25
  createCliRunAgentStream,
26
26
  initServerAiLogger
27
- } from "./chunk-ILGSSXOG.mjs";
27
+ } from "./chunk-6O2SW5GL.mjs";
28
28
  import {
29
29
  AGENT_TOOL_REGISTRY,
30
30
  CoreDataProvider
31
- } from "./chunk-IRZRIHIT.mjs";
31
+ } from "./chunk-FACKH2BR.mjs";
32
32
  import {
33
33
  AIChatManager,
34
34
  ALL_MIGRATIONS,
@@ -67,7 +67,6 @@ import {
67
67
  exportSessionToJson,
68
68
  export_service_exports,
69
69
  fetchRemoteModels,
70
- filterMessagesWithContext,
71
70
  findEntryFileInDirectory,
72
71
  getAvailableYears,
73
72
  getBuiltinModelsByProvider,
@@ -88,7 +87,6 @@ import {
88
87
  getMessageLengthDistribution,
89
88
  getMessageTypeStats,
90
89
  getMonthlyActivity,
91
- getMultipleSessionsMessages,
92
90
  getPendingNodeDataDirMigration,
93
91
  getRelationshipStats,
94
92
  getSchemaDetailed,
@@ -121,7 +119,7 @@ import {
121
119
  verifyCliDataPath,
122
120
  writeAuthProfile,
123
121
  writeConfigField
124
- } from "./chunk-QY67NN65.mjs";
122
+ } from "./chunk-GUGKY2GV.mjs";
125
123
  import {
126
124
  resolveCliPath
127
125
  } from "./chunk-FJ35V3TE.mjs";
@@ -780,26 +778,23 @@ function registerSessionIndexRoutes(server2, ctx) {
780
778
  // ../../packages/http-routes/src/routes/web/export.ts
781
779
  function registerExportRoutes(server2, ctx) {
782
780
  const { sessionAdapter: adapter } = ctx;
783
- server2.post("/_web/sessions/:id/export/markdown", async (request, reply) => {
781
+ server2.post("/_web/sessions/:id/export", async (request, reply) => {
784
782
  const { id } = request.params;
785
783
  const body = request.body;
786
784
  const sessionName = body?.sessionName || id;
787
- const { result, content } = export_service_exports.exportMarkdown(adapter, {
785
+ const format = body?.format || "txt";
786
+ const result = export_service_exports.exportFormatted(adapter, {
788
787
  sessionId: id,
789
788
  sessionName,
790
- filterMode: body.filterMode || "condition",
791
- keywords: body.keywords,
792
- timeFilter: body.timeFilter,
793
- senderIds: body.senderIds,
794
- contextSize: body.contextSize,
795
- segmentIds: body.segmentIds
789
+ format,
790
+ timeFilter: body.timeFilter
796
791
  });
797
792
  if (!result.success) {
798
- return reply.code(500).send({ error: result.error });
793
+ return reply.code(result.totalMessages === 0 ? 404 : 500).send({ error: result.error });
799
794
  }
800
- reply.header("Content-Type", "text/markdown; charset=utf-8");
801
- reply.header("Content-Disposition", `attachment; filename="${encodeURIComponent(sessionName)}_export.md"`);
802
- return reply.send(content);
795
+ reply.header("Content-Type", result.mimeType);
796
+ reply.header("Content-Disposition", `attachment; filename="${encodeURIComponent(result.filename)}"`);
797
+ return reply.send(result.content);
803
798
  });
804
799
  }
805
800
 
@@ -1165,22 +1160,6 @@ data: ${JSON.stringify(data)}
1165
1160
  });
1166
1161
  }
1167
1162
 
1168
- // ../../packages/http-routes/src/routes/web/ai-filter.ts
1169
- function registerAiFilterRoutes(server2, ctx) {
1170
- server2.post("/_web/ai/filter-messages", async (request, reply) => {
1171
- const { sessionId, keywords, timeFilter, senderIds, contextSize, page, pageSize } = request.body;
1172
- const db = ctx.dbManager.open(sessionId);
1173
- if (!db) return reply.code(404).send({ error: `Session not found: ${sessionId}` });
1174
- return filterMessagesWithContext(db, { keywords, timeFilter, senderIds, contextSize, page, pageSize });
1175
- });
1176
- server2.post("/_web/ai/multiple-sessions-messages", async (request, reply) => {
1177
- const { sessionId, segmentIds, page, pageSize } = request.body;
1178
- const db = ctx.dbManager.open(sessionId);
1179
- if (!db) return reply.code(404).send({ error: `Session not found: ${sessionId}` });
1180
- return getMultipleSessionsMessages(db, segmentIds, page, pageSize);
1181
- });
1182
- }
1183
-
1184
1163
  // ../../packages/http-routes/src/routes/web/ai-tools.ts
1185
1164
  var MAX_RESULT_CHARS = 5e5;
1186
1165
  var activeToolTests = /* @__PURE__ */ new Map();
@@ -1862,7 +1841,6 @@ function registerSharedRoutes(server2, ctx, options) {
1862
1841
  registerAiLlmRoutes(server2, ctx);
1863
1842
  registerAiLlmStreamRoutes(server2, ctx);
1864
1843
  registerAiAgentStreamRoutes(server2, ctx);
1865
- registerAiFilterRoutes(server2, ctx);
1866
1844
  registerAiToolRoutes(server2, ctx);
1867
1845
  registerAiChatRoutes(server2, ctx);
1868
1846
  registerAiSummaryRoutes(server2, ctx);
@@ -2340,7 +2318,7 @@ function registerWebRoutes(server2, dbManager2, options) {
2340
2318
  const resolvedPathProvider = options?.pathProvider ?? fallbackPathProvider;
2341
2319
  const ai = options?.aiContext;
2342
2320
  const cliStreamImport = async (dm, filePath) => {
2343
- const { streamImport: streamImport2 } = await import("./stream-import-O3H3FGV2.mjs");
2321
+ const { streamImport: streamImport2 } = await import("./stream-import-FHFBCEDV.mjs");
2344
2322
  const result = await streamImport2(dm, filePath);
2345
2323
  if (!result.sessionId) throw new Error("Import succeeded but no sessionId returned");
2346
2324
  return { sessionId: result.sessionId };
@@ -3505,4 +3483,4 @@ export {
3505
3483
  startHttpServer,
3506
3484
  stopHttpServer
3507
3485
  };
3508
- //# sourceMappingURL=chunk-SJIOPSMM.mjs.map
3486
+ //# sourceMappingURL=chunk-AZZYKUBR.mjs.map