chatlab-cli 0.30.2 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chat-command-VBDMWOKL.mjs → chat-command-CHV7RLBH.mjs} +9 -8
- package/dist/{chat-command-VBDMWOKL.mjs.map → chat-command-CHV7RLBH.mjs.map} +1 -1
- package/dist/{chunk-326OCJOT.mjs → chunk-DA5T64RY.mjs} +2 -2
- package/dist/{chunk-M2PXDX4G.mjs → chunk-DBBL74RK.mjs} +31 -22
- package/dist/chunk-DBBL74RK.mjs.map +1 -0
- package/dist/{chunk-KBSAVUFV.mjs → chunk-EXD2SXWL.mjs} +89 -15
- package/dist/chunk-EXD2SXWL.mjs.map +1 -0
- package/dist/{chunk-D3DPCDII.mjs → chunk-JH5RAJT2.mjs} +83 -34
- package/dist/chunk-JH5RAJT2.mjs.map +1 -0
- package/dist/{chunk-5EE2EFPE.mjs → chunk-RD335EMA.mjs} +4 -4
- package/dist/{chunk-WV5GSRQM.mjs → chunk-RDCUGC24.mjs} +5 -15
- package/dist/chunk-RDCUGC24.mjs.map +1 -0
- package/dist/{chunk-TEX44HNL.mjs → chunk-SNCXU2QL.mjs} +5 -15
- package/dist/chunk-SNCXU2QL.mjs.map +1 -0
- package/dist/{chunk-36JGKW6K.mjs → chunk-T64GA5HP.mjs} +1134 -364
- package/dist/chunk-T64GA5HP.mjs.map +1 -0
- package/dist/{chunk-LVEJHB3X.mjs → chunk-UWWFOEGF.mjs} +494 -97
- package/dist/chunk-UWWFOEGF.mjs.map +1 -0
- package/dist/{chunk-ULNRUS55.mjs → chunk-WQCY45U2.mjs} +3 -3
- package/dist/chunk-YAQLYL52.mjs +14 -0
- package/dist/chunk-YAQLYL52.mjs.map +1 -0
- package/dist/{chunk-TCZHG3G7.mjs → chunk-YPQ72HMX.mjs} +2 -2
- package/dist/cli.mjs +8 -7
- package/dist/contacts-worker.mjs +2 -2
- package/dist/global-insight-worker.mjs +179 -0
- package/dist/global-insight-worker.mjs.map +1 -0
- package/dist/{http-L4AMELPZ.mjs → http-3B5ARN7A.mjs} +12 -11
- package/dist/{import-WWCSXGVS.mjs → import-2DZGNSEX.mjs} +10 -7
- package/dist/index.mjs +12 -11
- package/dist/{mcp-A4M3LT5O.mjs → mcp-44I6FUUQ.mjs} +12 -11
- package/dist/{mcp-A4M3LT5O.mjs.map → mcp-44I6FUUQ.mjs.map} +1 -1
- package/dist/people-relationships-worker.mjs +2 -2
- package/dist/semantic-index-worker.mjs +1 -1
- package/dist/{src-MPNBTFOE.mjs → src-R3QX6L3L.mjs} +26 -6
- package/dist/{stream-import-HIE7PNL4.mjs → stream-import-VUEL2TTU.mjs} +10 -7
- package/dist/{worker-runtime-BJXO24XX.mjs → worker-runtime-GJAOIIZW.mjs} +6 -5
- package/dist/{worker-runtime-BJXO24XX.mjs.map → worker-runtime-GJAOIIZW.mjs.map} +1 -1
- package/dist-web/assets/ActionToolsPanel-fAio70bI.css +1 -0
- package/dist-web/assets/ActionToolsPanel.vue_vue_type_script_setup_true_lang-CdJT0t2f.js +110 -0
- package/dist-web/assets/{BufferResource-q3rzaWWd.js → BufferResource-BPGkshPa.js} +1 -1
- package/dist-web/assets/{CanvasRenderer-BRk1y8tp.js → CanvasRenderer-DTKkZhq4.js} +1 -1
- package/dist-web/assets/{EChartWordcloud-Clg60FMo.js → EChartWordcloud-DU3ZYdgz.js} +1 -1
- package/dist-web/assets/{Filter-BJwode73.js → Filter-CHXKzS2l.js} +1 -1
- package/dist-web/assets/{LoadingState.vue_vue_type_script_setup_true_lang-D_dJuLWJ.js → LoadingState.vue_vue_type_script_setup_true_lang-DACMroOe.js} +1 -1
- package/dist-web/assets/MessageExportModal-h-zl0dx1.js +1 -0
- package/dist-web/assets/PageHeader-CK0hTsdx.js +1 -0
- package/dist-web/assets/PageHeader-XIXMTomn.css +1 -0
- package/dist-web/assets/{RelationshipGalaxyCanvas-CORMD7vL.js → RelationshipGalaxyCanvas-Dwdy5flh.js} +3 -3
- package/dist-web/assets/{RelationshipGalaxyThreeCanvas-B_w_P4ob.js → RelationshipGalaxyThreeCanvas-CtY4TGen.js} +1 -1
- package/dist-web/assets/{RenderTargetSystem-CGhV9R9E.js → RenderTargetSystem-BE56mKRG.js} +1 -1
- package/dist-web/assets/ThemeCard.vue_vue_type_script_setup_true_lang-BoZyssJF.js +1 -0
- package/dist-web/assets/TimeSelect.vue_vue_type_script_setup_true_lang-27hMyAUE.js +1 -0
- package/dist-web/assets/{WebGLRenderer-CAokTE5X.js → WebGLRenderer-Dm18dxOf.js} +1 -1
- package/dist-web/assets/{WebGPURenderer-DzP4ggSy.js → WebGPURenderer-BF6TF-is.js} +1 -1
- package/dist-web/assets/annual-summary-time-range-DVLXK1r4.js +1 -0
- package/dist-web/assets/base-CFPyD9Gy.js +1 -0
- package/dist-web/assets/{browserAll-CAZCK6dd.js → browserAll-Cn_CfkXl.js} +1 -1
- package/dist-web/assets/dateFormat-BcqNKTQ1.js +1 -0
- package/dist-web/assets/{electron-CkPDbAaS.js → electron-B6xOabTq.js} +1 -1
- package/dist-web/assets/electron-hcWiB7Gg.js +1 -0
- package/dist-web/assets/fetch-BPkgnY0R.js +1 -0
- package/dist-web/assets/{fetch-LX9jrJCC.js → fetch-BRXmDI_2.js} +1 -1
- package/dist-web/assets/{fetch-Apd5OLJw.js → fetch-BUm1isWe.js} +1 -1
- package/dist-web/assets/{fetch-B8rik0TM.js → fetch-CBOJwwJp.js} +3 -3
- package/dist-web/assets/{fetch-wqMSiaK3.js → fetch-CEhUu1Yu.js} +1 -1
- package/dist-web/assets/fetch-C_EfVFJi.js +3 -0
- package/dist-web/assets/{fetch-DQ9UNNAy.js → fetch-DL_u25Ui.js} +1 -1
- package/dist-web/assets/{fetch-BIEXkvDq.js → fetch-DMLq3xPG.js} +1 -1
- package/dist-web/assets/{fetch--UbRoBT7.js → fetch-DylpNKCR.js} +1 -1
- package/dist-web/assets/fetch-etgwVKIw.js +1 -0
- package/dist-web/assets/index-0x1QPzKZ.js +1 -0
- package/dist-web/assets/index-B5S9FnfP.js +1 -0
- package/dist-web/assets/index-BS6loLHW.js +1 -0
- package/dist-web/assets/index-BfO_LpDv.css +1 -0
- package/dist-web/assets/index-BrTlAl8b.js +1 -0
- package/dist-web/assets/index-ByUaiVQK.css +1 -0
- package/dist-web/assets/{index-S-YQRH1E.js → index-C3TnydSt.js} +1 -1
- package/dist-web/assets/index-CAWO10k1.js +2 -0
- package/dist-web/assets/index-C_0GHEcb.css +1 -0
- package/dist-web/assets/index-Chm17wNe.js +2 -0
- package/dist-web/assets/index-DAr_2DlV.js +173 -0
- package/dist-web/assets/index-Em6upenM.js +64 -0
- package/dist-web/assets/index-FoTy2Cce.js +1 -0
- package/dist-web/assets/index-YADL4XIp.js +22 -0
- package/dist-web/assets/index-ZsZwPLWy.css +1 -0
- package/dist-web/assets/index-_6lck7Bv.css +1 -0
- package/dist-web/assets/index-aMIgqj43.js +1 -0
- package/dist-web/assets/index-y7cxH1Et.css +1 -0
- package/dist-web/assets/index-zZVsV5HB.js +1 -0
- package/dist-web/assets/{people-page-header-Mupn-U_b.js → people-page-header-BdKM1qhX.js} +1 -1
- package/dist-web/assets/types-CZnACqaB.js +1 -0
- package/dist-web/assets/{vendor-echarts-hJVnODyU.js → vendor-echarts-B-i_56Av.js} +1 -1
- package/dist-web/assets/{vendor-echarts-wordcloud-k5ih2Jl4.js → vendor-echarts-wordcloud-Ca8n6qS6.js} +1 -1
- package/dist-web/assets/{vendor-nuxt-ui-DaLxYaC4.js → vendor-nuxt-ui-CS1uxE9C.js} +2 -2
- package/dist-web/assets/{vendor-reka-ui-CzM4kDQ7.js → vendor-reka-ui-Cta6JPvN.js} +1 -1
- package/dist-web/assets/{web-DbKs6-1b.js → web-BUZ-dZy0.js} +1 -1
- package/dist-web/assets/{webworkerAll-Bhv-hBqR.js → webworkerAll-BKGP--A4.js} +1 -1
- package/dist-web/index.html +4 -4
- package/package.json +1 -1
- package/dist/chunk-36JGKW6K.mjs.map +0 -1
- package/dist/chunk-D3DPCDII.mjs.map +0 -1
- package/dist/chunk-KBSAVUFV.mjs.map +0 -1
- package/dist/chunk-LVEJHB3X.mjs.map +0 -1
- package/dist/chunk-M2PXDX4G.mjs.map +0 -1
- package/dist/chunk-TEX44HNL.mjs.map +0 -1
- package/dist/chunk-WV5GSRQM.mjs.map +0 -1
- package/dist-web/assets/DebugToolsPanel-D_lFIW6j.css +0 -1
- package/dist-web/assets/DebugToolsPanel.vue_vue_type_script_setup_true_lang-F4n0zNX2.js +0 -110
- package/dist-web/assets/MessageExportModal-CGcdMOyw.js +0 -1
- package/dist-web/assets/PageHeader-Bbn87QZS.css +0 -1
- package/dist-web/assets/PageHeader-CZaqOdBQ.js +0 -1
- package/dist-web/assets/electron-D9vE5t3H.js +0 -1
- package/dist-web/assets/fetch-1pB-HbYw.js +0 -3
- package/dist-web/assets/fetch-CF_3ZqRa.js +0 -1
- package/dist-web/assets/fetch-FSNxSnAp.js +0 -1
- package/dist-web/assets/index---rXG1hZ.css +0 -1
- package/dist-web/assets/index-B01uUoHE.js +0 -1
- package/dist-web/assets/index-B4l3rHie.css +0 -1
- package/dist-web/assets/index-BSIyyt0z.js +0 -1
- package/dist-web/assets/index-Bh8z441f.js +0 -2
- package/dist-web/assets/index-C0rya8v4.js +0 -1
- package/dist-web/assets/index-C1p9CbmN.css +0 -1
- package/dist-web/assets/index-COpza1A4.css +0 -1
- package/dist-web/assets/index-CZbZv2fh.js +0 -64
- package/dist-web/assets/index-CqUuHQBQ.js +0 -22
- package/dist-web/assets/index-CzeTP5MJ.js +0 -173
- package/dist-web/assets/index-DgNxTM_8.js +0 -2
- package/dist-web/assets/index-DosG7LmJ.css +0 -1
- /package/dist/{chunk-326OCJOT.mjs.map → chunk-DA5T64RY.mjs.map} +0 -0
- /package/dist/{chunk-5EE2EFPE.mjs.map → chunk-RD335EMA.mjs.map} +0 -0
- /package/dist/{chunk-ULNRUS55.mjs.map → chunk-WQCY45U2.mjs.map} +0 -0
- /package/dist/{chunk-TCZHG3G7.mjs.map → chunk-YPQ72HMX.mjs.map} +0 -0
- /package/dist/{http-L4AMELPZ.mjs.map → http-3B5ARN7A.mjs.map} +0 -0
- /package/dist/{import-WWCSXGVS.mjs.map → import-2DZGNSEX.mjs.map} +0 -0
- /package/dist/{src-MPNBTFOE.mjs.map → src-R3QX6L3L.mjs.map} +0 -0
- /package/dist/{stream-import-HIE7PNL4.mjs.map → stream-import-VUEL2TTU.mjs.map} +0 -0
|
@@ -6,13 +6,14 @@ const __filename = __fileURLToPath(import.meta.url);
|
|
|
6
6
|
const __dirname = __pathDirname(__filename);
|
|
7
7
|
import {
|
|
8
8
|
createCliRunAgentStream
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-RD335EMA.mjs";
|
|
10
|
+
import "./chunk-YPQ72HMX.mjs";
|
|
11
|
+
import "./chunk-WQCY45U2.mjs";
|
|
12
|
+
import "./chunk-T64GA5HP.mjs";
|
|
13
|
+
import "./chunk-SNCXU2QL.mjs";
|
|
14
|
+
import "./chunk-RDCUGC24.mjs";
|
|
15
|
+
import "./chunk-YAQLYL52.mjs";
|
|
16
|
+
import "./chunk-UWWFOEGF.mjs";
|
|
16
17
|
import "./chunk-GFHSSCCR.mjs";
|
|
17
18
|
|
|
18
19
|
// src/ai/chat-command.ts
|
|
@@ -305,4 +306,4 @@ export {
|
|
|
305
306
|
runChatCommand,
|
|
306
307
|
runChatTurn
|
|
307
308
|
};
|
|
308
|
-
//# sourceMappingURL=chat-command-
|
|
309
|
+
//# sourceMappingURL=chat-command-CHV7RLBH.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ai/chat-command.ts"],"sourcesContent":["import { createInterface } from 'node:readline/promises'\nimport type { Readable, Writable } from 'node:stream'\nimport type {\n DatabaseManager,\n AIChatManager,\n AgentStreamChunk,\n ContentBlock,\n PlanContentBlock,\n PlanDraftContentBlock,\n TokenUsageData,\n} from '@openchatlab/node-runtime'\nimport type { ChartPayload, PathProvider } from '@openchatlab/core'\nimport { createCliRunAgentStream } from './agent-stream-runner'\n\nexport interface ChatCommandOptions {\n sessionId?: string\n aiChatId?: string\n question?: string\n json?: boolean\n stream?: boolean\n locale?: string\n includeEvents?: boolean\n}\n\nexport interface ChatCommandDeps {\n dbManager: DatabaseManager\n pathProvider: PathProvider\n aiChatManager: AIChatManager\n stdout?: Pick<Writable, 'write'>\n stderr?: Pick<Writable, 'write'>\n stdin?: Readable\n createRunAgentStream?: typeof createCliRunAgentStream\n}\n\nexport interface ResolvedAIChatTarget {\n sessionId: string\n aiChatId: string\n assistantId: string\n created: boolean\n}\n\nexport interface ChatTurnResult {\n sessionId: string\n aiChatId: string\n question: string\n answer: string\n events?: AgentStreamChunk[]\n contentBlocks?: ContentBlock[]\n usage: {\n durationMs: number\n tokenUsage: TokenUsageData | null\n }\n}\n\nfunction write(stream: Pick<Writable, 'write'>, text: string): void {\n stream.write(text)\n}\n\nfunction buildTitle(question?: string): string {\n const trimmed = question?.trim()\n if (!trimmed) return 'CLI Chat'\n return trimmed.length > 50 ? `${trimmed.slice(0, 50)}...` : trimmed\n}\n\nfunction createAgentStreamError(error: unknown): Error {\n if (error instanceof Error) return error\n if (typeof error === 'string' && error) return new Error(error)\n if (typeof error === 'object' && error !== null) {\n const record = error as { name?: unknown; message?: unknown; stack?: unknown }\n const streamError = new Error(\n typeof record.message === 'string' && record.message ? record.message : 'Agent stream failed'\n )\n if (typeof record.name === 'string' && record.name) streamError.name = record.name\n if (typeof record.stack === 'string' && record.stack) streamError.stack = record.stack\n return streamError\n }\n return new Error('Agent stream failed')\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction isChartPayload(value: unknown): value is ChartPayload {\n return isRecord(value) && value.version === 1 && isRecord(value.spec) && isRecord(value.dataset)\n}\n\nfunction extractChartPayloads(toolResult: unknown): ChartPayload[] {\n if (!isRecord(toolResult)) return []\n const details = isRecord(toolResult.details) ? toolResult.details : toolResult\n const charts: ChartPayload[] = []\n if (isChartPayload(details.chart)) charts.push(details.chart)\n if (Array.isArray(details.charts)) {\n for (const chart of details.charts) {\n if (isChartPayload(chart)) charts.push(chart)\n }\n }\n return charts\n}\n\nfunction toPersistedChartPayload(chart: ChartPayload): ChartPayload {\n return {\n ...chart,\n dataset: {\n ...chart.dataset,\n rows: [],\n },\n }\n}\n\nfunction resolveSingleSessionId(dbManager: DatabaseManager): string {\n const sessionIds = dbManager.listSessionIds()\n if (sessionIds.length === 1) return sessionIds[0]!\n if (sessionIds.length === 0) {\n throw new Error('No chat sessions found. Import data first or run `chatlab sessions` to verify available sessions.')\n }\n throw new Error('Missing --session-id. Run `chatlab sessions` to choose a session ID.')\n}\n\nfunction assertSessionExists(dbManager: DatabaseManager, sessionId: string): void {\n const db = dbManager.open(sessionId)\n if (!db) {\n throw new Error(`Session ${sessionId} not found`)\n }\n}\n\nexport function resolveAIChatTarget(\n options: Pick<ChatCommandOptions, 'sessionId' | 'aiChatId' | 'question'>,\n deps: Pick<ChatCommandDeps, 'dbManager' | 'aiChatManager'>\n): ResolvedAIChatTarget {\n if (options.aiChatId) {\n const aiChat = deps.aiChatManager.getAIChat(options.aiChatId)\n if (!aiChat) {\n throw new Error(`AI chat ${options.aiChatId} not found`)\n }\n if (options.sessionId && options.sessionId !== aiChat.sessionId) {\n throw new Error(`AI chat ${options.aiChatId} belongs to session ${aiChat.sessionId}, not ${options.sessionId}`)\n }\n assertSessionExists(deps.dbManager, aiChat.sessionId)\n return { sessionId: aiChat.sessionId, aiChatId: aiChat.id, assistantId: aiChat.assistantId, created: false }\n }\n\n const sessionId = options.sessionId ?? resolveSingleSessionId(deps.dbManager)\n assertSessionExists(deps.dbManager, sessionId)\n const aiChat = deps.aiChatManager.createAIChat(sessionId, buildTitle(options.question), 'general_cn')\n return { sessionId, aiChatId: aiChat.id, assistantId: aiChat.assistantId, created: true }\n}\n\nexport async function runChatTurn(\n options: Required<Pick<ChatCommandOptions, 'question'>> &\n Pick<ChatCommandOptions, 'sessionId' | 'aiChatId' | 'json' | 'stream' | 'locale' | 'includeEvents'>,\n deps: ChatCommandDeps\n): Promise<ChatTurnResult> {\n const stdout = deps.stdout ?? process.stdout\n const target = resolveAIChatTarget(options, deps)\n const startedAt = Date.now()\n let answer = ''\n let tokenUsage: TokenUsageData | null = null\n let streamError: Error | null = null\n const events: AgentStreamChunk[] = []\n const contentBlocks: ContentBlock[] = []\n let hasReplayContentBlocks = false\n\n const runAgentStream = (deps.createRunAgentStream ?? createCliRunAgentStream)(deps.dbManager, deps.aiChatManager)\n\n // 中文注释:CLI 历史回放依赖 contentBlocks 的时序;只要出现计划/思考块,\n // 就同步保留后续正文 text block,避免 UI 使用 blocks 渲染时丢失最终回答。\n const appendTextBlock = (text: string) => {\n if (!text) return\n const lastBlock = contentBlocks[contentBlocks.length - 1]\n if (lastBlock?.type === 'text') {\n lastBlock.text += text\n } else {\n contentBlocks.push({ type: 'text', text })\n }\n }\n\n const appendThinkBlock = (text: string, tag = 'thinking', durationMs?: number) => {\n if (!text && durationMs === undefined) return\n const lastBlock = contentBlocks[contentBlocks.length - 1]\n let targetBlock: ContentBlock | undefined\n\n if (lastBlock?.type === 'think' && lastBlock.tag === tag) {\n lastBlock.text += text\n targetBlock = lastBlock\n } else if (text.trim().length > 0) {\n targetBlock = { type: 'think', tag, text }\n contentBlocks.push(targetBlock)\n } else if (durationMs !== undefined) {\n for (let index = contentBlocks.length - 1; index >= 0; index--) {\n const block = contentBlocks[index]\n if (block.type === 'think' && block.tag === tag) {\n targetBlock = block\n break\n }\n }\n }\n\n if (durationMs !== undefined && targetBlock?.type === 'think') {\n targetBlock.durationMs = durationMs\n }\n if (targetBlock?.type === 'think') {\n hasReplayContentBlocks = true\n }\n }\n\n const appendChartBlocks = (charts: ChartPayload[]) => {\n if (charts.length === 0) return\n // 中文注释:图表 block 需要持久化给 CLI 生成的 AI 对话回放;\n // 原始 SQL 行数据可能较大,保存时只保留渲染数据和字段元信息。\n contentBlocks.push(...charts.map((chart) => ({ type: 'chart' as const, chart: toPersistedChartPayload(chart) })))\n hasReplayContentBlocks = true\n }\n\n const appendPlanDraftBlock = (delta: string) => {\n if (!delta) return\n const lastBlock = contentBlocks[contentBlocks.length - 1]\n if (lastBlock?.type === 'plan_draft') {\n lastBlock.text += delta\n } else {\n contentBlocks.push({ type: 'plan_draft', version: 1, status: 'streaming', text: delta } as PlanDraftContentBlock)\n }\n hasReplayContentBlocks = true\n }\n\n const removePlanDraftBlocks = () => {\n for (let index = contentBlocks.length - 1; index >= 0; index--) {\n if (contentBlocks[index]?.type === 'plan_draft') {\n contentBlocks.splice(index, 1)\n }\n }\n }\n\n const appendFinalPlanBlock = (plan: PlanContentBlock) => {\n const planBlock = JSON.parse(JSON.stringify(plan)) as PlanContentBlock\n for (let index = contentBlocks.length - 1; index >= 0; index--) {\n const block = contentBlocks[index]\n if (block?.type === 'plan_draft') {\n const displayText = block.text.trim()\n if (displayText) planBlock.displayText = displayText\n contentBlocks[index] = planBlock\n hasReplayContentBlocks = true\n return\n }\n }\n contentBlocks.push(planBlock)\n hasReplayContentBlocks = true\n }\n\n await runAgentStream(\n {\n userMessage: options.question,\n sessionId: target.sessionId,\n aiChatId: target.aiChatId,\n assistantId: target.assistantId,\n chatType: 'group',\n locale: options.locale ?? 'zh-CN',\n enableAutoSkill: true,\n chartAutoMode: 'suggest',\n },\n (chunk: AgentStreamChunk) => {\n if (options.includeEvents) {\n events.push(JSON.parse(JSON.stringify(chunk)) as AgentStreamChunk)\n }\n if (chunk.type === 'error') {\n removePlanDraftBlocks()\n streamError = createAgentStreamError(chunk.error)\n return\n }\n if (chunk.type === 'plan_delta' && chunk.planDelta) {\n appendPlanDraftBlock(chunk.planDelta)\n return\n }\n if (chunk.type === 'plan' && chunk.plan) {\n appendFinalPlanBlock(chunk.plan)\n return\n }\n if (chunk.type === 'plan_skipped') {\n removePlanDraftBlocks()\n return\n }\n if (chunk.type === 'think') {\n appendThinkBlock(chunk.content ?? '', chunk.thinkTag, chunk.thinkDurationMs)\n return\n }\n if (chunk.type === 'tool_result' && chunk.toolName === 'render_chart') {\n appendChartBlocks(extractChartPayloads(chunk.toolResult))\n return\n }\n if (chunk.type === 'content' && chunk.content) {\n answer += chunk.content\n appendTextBlock(chunk.content)\n if (!options.json && options.stream !== false) write(stdout, chunk.content)\n }\n if (chunk.type === 'done' && chunk.usage) {\n tokenUsage = chunk.usage\n for (let index = contentBlocks.length - 1; index >= 0; index--) {\n const block = contentBlocks[index]\n if (block.type === 'plan') {\n block.status = 'done'\n break\n }\n }\n }\n },\n new AbortController().signal\n )\n\n if (streamError) throw streamError\n\n if (!options.json && options.stream !== false && answer && !answer.endsWith('\\n')) {\n write(stdout, '\\n')\n }\n\n deps.aiChatManager.addMessage(target.aiChatId, 'user', options.question)\n deps.aiChatManager.addMessage(\n target.aiChatId,\n 'assistant',\n answer,\n undefined,\n undefined,\n hasReplayContentBlocks ? contentBlocks : undefined,\n tokenUsage ?? undefined\n )\n\n return {\n sessionId: target.sessionId,\n aiChatId: target.aiChatId,\n question: options.question,\n answer,\n ...(options.includeEvents ? { events } : {}),\n ...(hasReplayContentBlocks ? { contentBlocks } : {}),\n usage: {\n durationMs: Date.now() - startedAt,\n tokenUsage,\n },\n }\n}\n\nexport async function runChatCommand(options: ChatCommandOptions, deps: ChatCommandDeps): Promise<void> {\n const stdout = deps.stdout ?? process.stdout\n const stderr = deps.stderr ?? process.stderr\n\n if (options.question?.trim()) {\n const result = await runChatTurn({ ...options, question: options.question.trim() }, deps)\n if (options.json) {\n write(stdout, `${JSON.stringify(result, null, 2)}\\n`)\n } else if (options.stream === false) {\n write(stdout, `${result.answer}\\n`)\n }\n return\n }\n\n const rl = createInterface({\n input: deps.stdin ?? process.stdin,\n output: stdout as Writable,\n })\n\n try {\n let aiChatId = options.aiChatId\n while (true) {\n const question = (await rl.question('chatlab> ')).trim()\n if (!question || question === 'exit' || question === 'quit') break\n try {\n const result = await runChatTurn({ ...options, aiChatId, question, json: false, stream: true }, deps)\n aiChatId = result.aiChatId\n } catch (error) {\n write(stderr, `${error instanceof Error ? error.message : String(error)}\\n`)\n }\n }\n } finally {\n rl.close()\n }\n}\n"],"mappings":"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","names":["aiChat"]}
|
|
1
|
+
{"version":3,"sources":["../src/ai/chat-command.ts"],"sourcesContent":["import { createInterface } from 'node:readline/promises'\nimport type { Readable, Writable } from 'node:stream'\nimport type {\n DatabaseManager,\n AIChatManager,\n AgentStreamChunk,\n ContentBlock,\n PlanContentBlock,\n PlanDraftContentBlock,\n TokenUsageData,\n} from '@openchatlab/node-runtime'\nimport type { ChartPayload, PathProvider } from '@openchatlab/core'\nimport { createCliRunAgentStream } from './agent-stream-runner'\n\nexport interface ChatCommandOptions {\n sessionId?: string\n aiChatId?: string\n question?: string\n json?: boolean\n stream?: boolean\n locale?: string\n includeEvents?: boolean\n}\n\nexport interface ChatCommandDeps {\n dbManager: DatabaseManager\n pathProvider: PathProvider\n aiChatManager: AIChatManager\n stdout?: Pick<Writable, 'write'>\n stderr?: Pick<Writable, 'write'>\n stdin?: Readable\n createRunAgentStream?: typeof createCliRunAgentStream\n}\n\nexport interface ResolvedAIChatTarget {\n sessionId: string\n aiChatId: string\n assistantId: string\n created: boolean\n}\n\nexport interface ChatTurnResult {\n sessionId: string\n aiChatId: string\n question: string\n answer: string\n events?: AgentStreamChunk[]\n contentBlocks?: ContentBlock[]\n usage: {\n durationMs: number\n tokenUsage: TokenUsageData | null\n }\n}\n\nfunction write(stream: Pick<Writable, 'write'>, text: string): void {\n stream.write(text)\n}\n\nfunction buildTitle(question?: string): string {\n const trimmed = question?.trim()\n if (!trimmed) return 'CLI Chat'\n return trimmed.length > 50 ? `${trimmed.slice(0, 50)}...` : trimmed\n}\n\nfunction createAgentStreamError(error: unknown): Error {\n if (error instanceof Error) return error\n if (typeof error === 'string' && error) return new Error(error)\n if (typeof error === 'object' && error !== null) {\n const record = error as { name?: unknown; message?: unknown; stack?: unknown }\n const streamError = new Error(\n typeof record.message === 'string' && record.message ? record.message : 'Agent stream failed'\n )\n if (typeof record.name === 'string' && record.name) streamError.name = record.name\n if (typeof record.stack === 'string' && record.stack) streamError.stack = record.stack\n return streamError\n }\n return new Error('Agent stream failed')\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction isChartPayload(value: unknown): value is ChartPayload {\n return isRecord(value) && value.version === 1 && isRecord(value.spec) && isRecord(value.dataset)\n}\n\nfunction extractChartPayloads(toolResult: unknown): ChartPayload[] {\n if (!isRecord(toolResult)) return []\n const details = isRecord(toolResult.details) ? toolResult.details : toolResult\n const charts: ChartPayload[] = []\n if (isChartPayload(details.chart)) charts.push(details.chart)\n if (Array.isArray(details.charts)) {\n for (const chart of details.charts) {\n if (isChartPayload(chart)) charts.push(chart)\n }\n }\n return charts\n}\n\nfunction toPersistedChartPayload(chart: ChartPayload): ChartPayload {\n return {\n ...chart,\n dataset: {\n ...chart.dataset,\n rows: [],\n },\n }\n}\n\nfunction resolveSingleSessionId(dbManager: DatabaseManager): string {\n const sessionIds = dbManager.listSessionIds()\n if (sessionIds.length === 1) return sessionIds[0]!\n if (sessionIds.length === 0) {\n throw new Error('No chat sessions found. Import data first or run `chatlab sessions` to verify available sessions.')\n }\n throw new Error('Missing --session-id. Run `chatlab sessions` to choose a session ID.')\n}\n\nfunction assertSessionExists(dbManager: DatabaseManager, sessionId: string): void {\n const db = dbManager.open(sessionId)\n if (!db) {\n throw new Error(`Session ${sessionId} not found`)\n }\n}\n\nexport function resolveAIChatTarget(\n options: Pick<ChatCommandOptions, 'sessionId' | 'aiChatId' | 'question'>,\n deps: Pick<ChatCommandDeps, 'dbManager' | 'aiChatManager'>\n): ResolvedAIChatTarget {\n if (options.aiChatId) {\n const aiChat = deps.aiChatManager.getAIChat(options.aiChatId)\n if (!aiChat) {\n throw new Error(`AI chat ${options.aiChatId} not found`)\n }\n if (options.sessionId && options.sessionId !== aiChat.sessionId) {\n throw new Error(`AI chat ${options.aiChatId} belongs to session ${aiChat.sessionId}, not ${options.sessionId}`)\n }\n assertSessionExists(deps.dbManager, aiChat.sessionId)\n return { sessionId: aiChat.sessionId, aiChatId: aiChat.id, assistantId: aiChat.assistantId, created: false }\n }\n\n const sessionId = options.sessionId ?? resolveSingleSessionId(deps.dbManager)\n assertSessionExists(deps.dbManager, sessionId)\n const aiChat = deps.aiChatManager.createAIChat(sessionId, buildTitle(options.question), 'general_cn')\n return { sessionId, aiChatId: aiChat.id, assistantId: aiChat.assistantId, created: true }\n}\n\nexport async function runChatTurn(\n options: Required<Pick<ChatCommandOptions, 'question'>> &\n Pick<ChatCommandOptions, 'sessionId' | 'aiChatId' | 'json' | 'stream' | 'locale' | 'includeEvents'>,\n deps: ChatCommandDeps\n): Promise<ChatTurnResult> {\n const stdout = deps.stdout ?? process.stdout\n const target = resolveAIChatTarget(options, deps)\n const startedAt = Date.now()\n let answer = ''\n let tokenUsage: TokenUsageData | null = null\n let streamError: Error | null = null\n const events: AgentStreamChunk[] = []\n const contentBlocks: ContentBlock[] = []\n let hasReplayContentBlocks = false\n\n const runAgentStream = (deps.createRunAgentStream ?? createCliRunAgentStream)(deps.dbManager, deps.aiChatManager)\n\n // 中文注释:CLI 历史回放依赖 contentBlocks 的时序;只要出现计划/思考块,\n // 就同步保留后续正文 text block,避免 UI 使用 blocks 渲染时丢失最终回答。\n const appendTextBlock = (text: string) => {\n if (!text) return\n const lastBlock = contentBlocks[contentBlocks.length - 1]\n if (lastBlock?.type === 'text') {\n lastBlock.text += text\n } else {\n contentBlocks.push({ type: 'text', text })\n }\n }\n\n const appendThinkBlock = (text: string, tag = 'thinking', durationMs?: number) => {\n if (!text && durationMs === undefined) return\n const lastBlock = contentBlocks[contentBlocks.length - 1]\n let targetBlock: ContentBlock | undefined\n\n if (lastBlock?.type === 'think' && lastBlock.tag === tag) {\n lastBlock.text += text\n targetBlock = lastBlock\n } else if (text.trim().length > 0) {\n targetBlock = { type: 'think', tag, text }\n contentBlocks.push(targetBlock)\n } else if (durationMs !== undefined) {\n for (let index = contentBlocks.length - 1; index >= 0; index--) {\n const block = contentBlocks[index]\n if (block.type === 'think' && block.tag === tag) {\n targetBlock = block\n break\n }\n }\n }\n\n if (durationMs !== undefined && targetBlock?.type === 'think') {\n targetBlock.durationMs = durationMs\n }\n if (targetBlock?.type === 'think') {\n hasReplayContentBlocks = true\n }\n }\n\n const appendChartBlocks = (charts: ChartPayload[]) => {\n if (charts.length === 0) return\n // 中文注释:图表 block 需要持久化给 CLI 生成的 AI 对话回放;\n // 原始 SQL 行数据可能较大,保存时只保留渲染数据和字段元信息。\n contentBlocks.push(...charts.map((chart) => ({ type: 'chart' as const, chart: toPersistedChartPayload(chart) })))\n hasReplayContentBlocks = true\n }\n\n const appendPlanDraftBlock = (delta: string) => {\n if (!delta) return\n const lastBlock = contentBlocks[contentBlocks.length - 1]\n if (lastBlock?.type === 'plan_draft') {\n lastBlock.text += delta\n } else {\n contentBlocks.push({ type: 'plan_draft', version: 1, status: 'streaming', text: delta } as PlanDraftContentBlock)\n }\n hasReplayContentBlocks = true\n }\n\n const removePlanDraftBlocks = () => {\n for (let index = contentBlocks.length - 1; index >= 0; index--) {\n if (contentBlocks[index]?.type === 'plan_draft') {\n contentBlocks.splice(index, 1)\n }\n }\n }\n\n const appendFinalPlanBlock = (plan: PlanContentBlock) => {\n const planBlock = JSON.parse(JSON.stringify(plan)) as PlanContentBlock\n for (let index = contentBlocks.length - 1; index >= 0; index--) {\n const block = contentBlocks[index]\n if (block?.type === 'plan_draft') {\n const displayText = block.text.trim()\n if (displayText) planBlock.displayText = displayText\n contentBlocks[index] = planBlock\n hasReplayContentBlocks = true\n return\n }\n }\n contentBlocks.push(planBlock)\n hasReplayContentBlocks = true\n }\n\n await runAgentStream(\n {\n userMessage: options.question,\n sessionId: target.sessionId,\n aiChatId: target.aiChatId,\n assistantId: target.assistantId,\n chatType: 'group',\n locale: options.locale ?? 'zh-CN',\n enableAutoSkill: true,\n chartAutoMode: 'suggest',\n },\n (chunk: AgentStreamChunk) => {\n if (options.includeEvents) {\n events.push(JSON.parse(JSON.stringify(chunk)) as AgentStreamChunk)\n }\n if (chunk.type === 'error') {\n removePlanDraftBlocks()\n streamError = createAgentStreamError(chunk.error)\n return\n }\n if (chunk.type === 'plan_delta' && chunk.planDelta) {\n appendPlanDraftBlock(chunk.planDelta)\n return\n }\n if (chunk.type === 'plan' && chunk.plan) {\n appendFinalPlanBlock(chunk.plan)\n return\n }\n if (chunk.type === 'plan_skipped') {\n removePlanDraftBlocks()\n return\n }\n if (chunk.type === 'think') {\n appendThinkBlock(chunk.content ?? '', chunk.thinkTag, chunk.thinkDurationMs)\n return\n }\n if (chunk.type === 'tool_result' && chunk.toolName === 'render_chart') {\n appendChartBlocks(extractChartPayloads(chunk.toolResult))\n return\n }\n if (chunk.type === 'content' && chunk.content) {\n answer += chunk.content\n appendTextBlock(chunk.content)\n if (!options.json && options.stream !== false) write(stdout, chunk.content)\n }\n if (chunk.type === 'done' && chunk.usage) {\n tokenUsage = chunk.usage\n for (let index = contentBlocks.length - 1; index >= 0; index--) {\n const block = contentBlocks[index]\n if (block.type === 'plan') {\n block.status = 'done'\n break\n }\n }\n }\n },\n new AbortController().signal\n )\n\n if (streamError) throw streamError\n\n if (!options.json && options.stream !== false && answer && !answer.endsWith('\\n')) {\n write(stdout, '\\n')\n }\n\n deps.aiChatManager.addMessage(target.aiChatId, 'user', options.question)\n deps.aiChatManager.addMessage(\n target.aiChatId,\n 'assistant',\n answer,\n undefined,\n undefined,\n hasReplayContentBlocks ? contentBlocks : undefined,\n tokenUsage ?? undefined\n )\n\n return {\n sessionId: target.sessionId,\n aiChatId: target.aiChatId,\n question: options.question,\n answer,\n ...(options.includeEvents ? { events } : {}),\n ...(hasReplayContentBlocks ? { contentBlocks } : {}),\n usage: {\n durationMs: Date.now() - startedAt,\n tokenUsage,\n },\n }\n}\n\nexport async function runChatCommand(options: ChatCommandOptions, deps: ChatCommandDeps): Promise<void> {\n const stdout = deps.stdout ?? process.stdout\n const stderr = deps.stderr ?? process.stderr\n\n if (options.question?.trim()) {\n const result = await runChatTurn({ ...options, question: options.question.trim() }, deps)\n if (options.json) {\n write(stdout, `${JSON.stringify(result, null, 2)}\\n`)\n } else if (options.stream === false) {\n write(stdout, `${result.answer}\\n`)\n }\n return\n }\n\n const rl = createInterface({\n input: deps.stdin ?? process.stdin,\n output: stdout as Writable,\n })\n\n try {\n let aiChatId = options.aiChatId\n while (true) {\n const question = (await rl.question('chatlab> ')).trim()\n if (!question || question === 'exit' || question === 'quit') break\n try {\n const result = await runChatTurn({ ...options, aiChatId, question, json: false, stream: true }, deps)\n aiChatId = result.aiChatId\n } catch (error) {\n write(stderr, `${error instanceof Error ? error.message : String(error)}\\n`)\n }\n }\n } finally {\n rl.close()\n }\n}\n"],"mappings":"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","names":["aiChat"]}
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import {
|
|
11
11
|
DataDirCompatibilityError,
|
|
12
12
|
assertDataDirCompatible
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-UWWFOEGF.mjs";
|
|
14
14
|
|
|
15
15
|
// src/runtime-compat.ts
|
|
16
16
|
function assertCliDataDirCompatible(pathProvider, kind, options) {
|
|
@@ -37,4 +37,4 @@ function formatCliDataDirCompatibilityError(error, runtime) {
|
|
|
37
37
|
export {
|
|
38
38
|
assertCliDataDirCompatible
|
|
39
39
|
};
|
|
40
|
-
//# sourceMappingURL=chunk-
|
|
40
|
+
//# sourceMappingURL=chunk-DA5T64RY.mjs.map
|
|
@@ -6,22 +6,20 @@ const __filename = __fileURLToPath(import.meta.url);
|
|
|
6
6
|
const __dirname = __pathDirname(__filename);
|
|
7
7
|
import {
|
|
8
8
|
assertCliDataDirCompatible
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-DA5T64RY.mjs";
|
|
10
10
|
import {
|
|
11
11
|
getVersion
|
|
12
12
|
} from "./chunk-5ADKYYNA.mjs";
|
|
13
|
-
import {
|
|
14
|
-
resolveCliPath
|
|
15
|
-
} from "./chunk-FJ35V3TE.mjs";
|
|
16
13
|
import {
|
|
17
14
|
NodePathProvider,
|
|
18
15
|
PreferencesManager,
|
|
19
16
|
applyPendingNodeDataDirMigrationIfNeeded,
|
|
20
17
|
getSystemLogsDir,
|
|
21
18
|
hasPendingElectronDataWarning
|
|
22
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-WQCY45U2.mjs";
|
|
23
20
|
import {
|
|
24
21
|
AIChatManager,
|
|
22
|
+
IMPORT_IN_PROGRESS_ERROR_KEY,
|
|
25
23
|
applyPreprocessingPipeline,
|
|
26
24
|
computeWordFrequency,
|
|
27
25
|
desensitizeText,
|
|
@@ -29,7 +27,10 @@ import {
|
|
|
29
27
|
matchesBlacklist,
|
|
30
28
|
mergeRulesForLocale,
|
|
31
29
|
preprocessMessages
|
|
32
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-T64GA5HP.mjs";
|
|
31
|
+
import {
|
|
32
|
+
resolveCliPath
|
|
33
|
+
} from "./chunk-FJ35V3TE.mjs";
|
|
33
34
|
import {
|
|
34
35
|
ConfigSetError,
|
|
35
36
|
DEFAULT_API_PORT,
|
|
@@ -65,7 +66,7 @@ import {
|
|
|
65
66
|
searchMessagesLike,
|
|
66
67
|
setConfigField,
|
|
67
68
|
verifyCliDataPath
|
|
68
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-UWWFOEGF.mjs";
|
|
69
70
|
|
|
70
71
|
// src/cli.ts
|
|
71
72
|
import * as fs2 from "fs";
|
|
@@ -2070,12 +2071,12 @@ program.command("update").description("Update ChatLab CLI to the latest version"
|
|
|
2070
2071
|
});
|
|
2071
2072
|
registerQueryCommands(program);
|
|
2072
2073
|
registerManifestCommand(program, getVersion());
|
|
2073
|
-
program.command("import <file>").description("Import a chat history file (14+ formats: QQ/WeChat/Telegram/WhatsApp/LINE/Discord/Instagram, etc.)").option("--session-id <id>", "
|
|
2074
|
+
program.command("import <file>").description("Import a chat history file (14+ formats: QQ/WeChat/Telegram/WhatsApp/LINE/Discord/Instagram, etc.)").option("--session-id <id>", "Force an existing session target, or create with this ID if missing").option("--format <id>", "Specify format ID (skip auto-detection)").action(async (file, options) => {
|
|
2074
2075
|
if (!fs2.existsSync(file)) {
|
|
2075
2076
|
console.error(`File not found: ${file}`);
|
|
2076
2077
|
process.exit(1);
|
|
2077
2078
|
}
|
|
2078
|
-
const {
|
|
2079
|
+
const { autoImport, detectFormat } = await import("./import-2DZGNSEX.mjs");
|
|
2079
2080
|
const { dbManager, pathProvider } = initRuntime();
|
|
2080
2081
|
const nativeBinding = resolveNativeBinding();
|
|
2081
2082
|
logNativeParserStatus();
|
|
@@ -2088,8 +2089,9 @@ program.command("import <file>").description("Import a chat history file (14+ fo
|
|
|
2088
2089
|
console.log(`Importing: ${file}`);
|
|
2089
2090
|
if (format) console.log(` Format: ${format.name} (${format.platform})`);
|
|
2090
2091
|
try {
|
|
2091
|
-
const result = await
|
|
2092
|
+
const result = await autoImport(dbManager, file, {
|
|
2092
2093
|
formatId: options.format,
|
|
2094
|
+
sessionId: options.sessionId,
|
|
2093
2095
|
nativeBinding,
|
|
2094
2096
|
onProgress: (p) => {
|
|
2095
2097
|
process.stdout.write(`\r ${p.stage}: ${p.progress}%`);
|
|
@@ -2100,11 +2102,17 @@ program.command("import <file>").description("Import a chat history file (14+ fo
|
|
|
2100
2102
|
|
|
2101
2103
|
Import succeeded!`);
|
|
2102
2104
|
console.log(` Session ID: ${result.sessionId}`);
|
|
2103
|
-
console.log(`
|
|
2104
|
-
console.log(`
|
|
2105
|
+
console.log(` Mode: ${result.importMode ?? "unknown"}`);
|
|
2106
|
+
if (result.matchedBy) console.log(` Matched by: ${result.matchedBy}`);
|
|
2107
|
+
if (result.createReason) console.log(` Create reason: ${result.createReason}`);
|
|
2108
|
+
if (result.createReason === "ambiguous") {
|
|
2109
|
+
console.warn(" Warning: multiple existing sessions matched, so a new session was created.");
|
|
2110
|
+
}
|
|
2111
|
+
console.log(` New messages: ${result.newMessageCount ?? 0}`);
|
|
2112
|
+
console.log(` Duplicates skipped: ${result.duplicateCount ?? 0}`);
|
|
2105
2113
|
if (result.sessionId) {
|
|
2106
2114
|
try {
|
|
2107
|
-
const { PreferencesManager: PreferencesManager2, createDatabaseManagerAdapter, ownerProfileService } = await import("./src-
|
|
2115
|
+
const { PreferencesManager: PreferencesManager2, createDatabaseManagerAdapter, ownerProfileService } = await import("./src-R3QX6L3L.mjs");
|
|
2108
2116
|
const applied = ownerProfileService.tryApplyOwnerProfile(
|
|
2109
2117
|
createDatabaseManagerAdapter(dbManager),
|
|
2110
2118
|
new PreferencesManager2(pathProvider.getSystemDir()),
|
|
@@ -2118,22 +2126,23 @@ Import succeeded!`);
|
|
|
2118
2126
|
}
|
|
2119
2127
|
}
|
|
2120
2128
|
} else {
|
|
2129
|
+
const errorMessage = result.error === IMPORT_IN_PROGRESS_ERROR_KEY ? "Another import is already in progress. Please retry later." : result.error;
|
|
2121
2130
|
console.error(`
|
|
2122
2131
|
|
|
2123
|
-
Import failed: ${
|
|
2124
|
-
process.
|
|
2132
|
+
Import failed: ${errorMessage}`);
|
|
2133
|
+
process.exitCode = 1;
|
|
2125
2134
|
}
|
|
2126
2135
|
} catch (err) {
|
|
2127
2136
|
console.error(`
|
|
2128
2137
|
|
|
2129
2138
|
Import error: ${err instanceof Error ? err.message : err}`);
|
|
2130
|
-
process.
|
|
2139
|
+
process.exitCode = 1;
|
|
2131
2140
|
} finally {
|
|
2132
2141
|
dbManager.closeAll();
|
|
2133
2142
|
}
|
|
2134
2143
|
});
|
|
2135
2144
|
program.command("formats").description("List all supported chat history formats").action(async () => {
|
|
2136
|
-
const { getSupportedFormats } = await import("./import-
|
|
2145
|
+
const { getSupportedFormats } = await import("./import-2DZGNSEX.mjs");
|
|
2137
2146
|
const formats = getSupportedFormats();
|
|
2138
2147
|
console.log(`${formats.length} supported format(s):
|
|
2139
2148
|
`);
|
|
@@ -2142,11 +2151,11 @@ program.command("formats").description("List all supported chat history formats"
|
|
|
2142
2151
|
}
|
|
2143
2152
|
});
|
|
2144
2153
|
program.command("mcp").description("Start MCP Server (stdio transport, for ClaudeCode / Cursor / AI agents)").action(async () => {
|
|
2145
|
-
const { startCliMcpServer } = await import("./mcp-
|
|
2154
|
+
const { startCliMcpServer } = await import("./mcp-44I6FUUQ.mjs");
|
|
2146
2155
|
await startCliMcpServer();
|
|
2147
2156
|
});
|
|
2148
2157
|
program.command("chat").description("Ask ChatLab AI about an imported chat session").option("--session-id <id>", "Source chat session ID").option("--ai-chat-id <id>", "Existing AI chat ID to continue").option("-q, --question <text>", "Question to ask").option("--json", "Output structured JSON").option("--include-events", "Include all agent stream chunks in JSON output").option("--no-stream", "Disable streaming output").option("--locale <locale>", "AI response locale", "zh-CN").action(async (options) => {
|
|
2149
|
-
const { runChatCommand } = await import("./chat-command-
|
|
2158
|
+
const { runChatCommand } = await import("./chat-command-CHV7RLBH.mjs");
|
|
2150
2159
|
const { dbManager, pathProvider } = initRuntime();
|
|
2151
2160
|
const aiChatManager = new AIChatManager(pathProvider.getAiDataDir(), { nativeBinding: resolveNativeBinding() });
|
|
2152
2161
|
try {
|
|
@@ -2182,7 +2191,7 @@ program.command("start").description("Start ChatLab (HTTP API + Web UI)").option
|
|
|
2182
2191
|
});
|
|
2183
2192
|
return;
|
|
2184
2193
|
}
|
|
2185
|
-
const { startHttpServer } = await import("./http-
|
|
2194
|
+
const { startHttpServer } = await import("./http-3B5ARN7A.mjs");
|
|
2186
2195
|
const port = parseInt(options.port, 10);
|
|
2187
2196
|
let webRoot;
|
|
2188
2197
|
if (!options.headless) {
|
|
@@ -2229,7 +2238,7 @@ Press Ctrl+C to stop.
|
|
|
2229
2238
|
}
|
|
2230
2239
|
const shutdown = async () => {
|
|
2231
2240
|
console.log("\nShutting down...");
|
|
2232
|
-
const { stopHttpServer } = await import("./http-
|
|
2241
|
+
const { stopHttpServer } = await import("./http-3B5ARN7A.mjs");
|
|
2233
2242
|
await stopHttpServer();
|
|
2234
2243
|
process.exit(0);
|
|
2235
2244
|
};
|
|
@@ -2322,4 +2331,4 @@ if (isDirectRun) {
|
|
|
2322
2331
|
export {
|
|
2323
2332
|
run
|
|
2324
2333
|
};
|
|
2325
|
-
//# sourceMappingURL=chunk-
|
|
2334
|
+
//# sourceMappingURL=chunk-DBBL74RK.mjs.map
|