zhitalk 0.0.4 → 0.0.6

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 (46) hide show
  1. package/README.md +2 -2
  2. package/dist/agent/agent.js +57 -63
  3. package/dist/agent/cli.js +39 -73
  4. package/dist/agent/colors.js +6 -44
  5. package/dist/agent/commands.js +22 -28
  6. package/dist/agent/config.js +20 -62
  7. package/dist/agent/context.js +8 -12
  8. package/dist/agent/db.js +17 -27
  9. package/dist/agent/hooks.d.ts +1 -1
  10. package/dist/agent/hooks.js +13 -22
  11. package/dist/agent/mcp/client.js +25 -29
  12. package/dist/agent/mcp/index.d.ts +1 -1
  13. package/dist/agent/mcp/index.js +8 -13
  14. package/dist/agent/mcp/wrapper.d.ts +2 -2
  15. package/dist/agent/mcp/wrapper.js +5 -8
  16. package/dist/agent/model.js +6 -10
  17. package/dist/agent/permission/exec.js +6 -9
  18. package/dist/agent/permission/is-dangerous-path.js +13 -19
  19. package/dist/agent/permission/is-safe-domains.js +1 -4
  20. package/dist/agent/permission/network.js +3 -6
  21. package/dist/agent/permission/read.js +3 -6
  22. package/dist/agent/permission/util.js +16 -26
  23. package/dist/agent/permission/write.js +5 -8
  24. package/dist/agent/prompt.js +9 -15
  25. package/dist/agent/skills.js +19 -24
  26. package/dist/agent/tools/agent_tool.js +2 -38
  27. package/dist/agent/tools/exec_tool.js +4 -7
  28. package/dist/agent/tools/load_skill_tool.js +3 -6
  29. package/dist/agent/tools/memory_create_tool.js +4 -10
  30. package/dist/agent/tools/memory_delete_tool.js +4 -10
  31. package/dist/agent/tools/memory_retrieve_tool.js +3 -6
  32. package/dist/agent/tools/profile_update_tool.js +11 -14
  33. package/dist/agent/tools/read_file_tool.js +3 -6
  34. package/dist/agent/tools/run_js_tool.js +3 -6
  35. package/dist/agent/tools/run_py_tool.js +4 -7
  36. package/dist/agent/tools/search.js +1 -4
  37. package/dist/agent/tools/web_fetch_tool.js +1 -4
  38. package/dist/agent/tools/web_search_tool.js +5 -8
  39. package/dist/agent/tools/write_file_tool.js +5 -8
  40. package/dist/agent/tools.js +76 -81
  41. package/dist/agent/utils.js +2 -6
  42. package/dist/index.js +29 -56
  43. package/dist/install.js +14 -50
  44. package/jest.config.js +11 -0
  45. package/package.json +7 -6
  46. package/pnpm-workspace.yaml +4 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # Zhitalk
1
+ # 智语 Zhitalk
2
2
 
3
- A personal AI Agent like OpenClaw, including tools, skills, memory, hook, sub-agent, MCP sever, etc. Run in the terminal.
3
+ [智语 Zhitalk](https://zhitalk.chat/) 是一个 AI Agent 个人助手,像 OpenClaw 小龙虾一样。 包含 tools skills memory hook subagent MCP-server Agent 功能。你可以和它聊天,给它分配任务,让它操作文件...
4
4
 
5
5
  ## Usage
6
6
 
@@ -1,41 +1,35 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.initAgent = initAgent;
4
- exports.runAgentStream = runAgentStream;
5
- exports.runSubAgent = runSubAgent;
6
- exports.compressContext = compressContext;
7
- const langgraph_checkpoint_sqlite_1 = require("@langchain/langgraph-checkpoint-sqlite");
8
- const messages_1 = require("@langchain/core/messages");
9
- const langgraph_1 = require("@langchain/langgraph");
10
- const langgraph_2 = require("@langchain/langgraph");
11
- const db_1 = require("./db");
12
- const tools_1 = require("./tools");
13
- const context_1 = require("./context");
14
- const prompt_1 = require("./prompt");
15
- const colors_1 = require("./colors");
16
- const read_1 = require("./permission/read");
17
- const write_1 = require("./permission/write");
18
- const exec_1 = require("./permission/exec");
19
- const network_1 = require("./permission/network");
20
- const hooks_1 = require("./hooks");
21
- const model_1 = require("./model");
1
+ import { SqliteSaver } from '@langchain/langgraph-checkpoint-sqlite';
2
+ import { SystemMessage, AIMessage, HumanMessage, ToolMessage, } from '@langchain/core/messages';
3
+ import { StateGraph, Annotation, START, END, interrupt, Command, } from '@langchain/langgraph';
4
+ import { messagesStateReducer } from '@langchain/langgraph';
5
+ import { DB_PATH } from './db.js';
6
+ import { tools, maybePersistedOutput, initTools } from './tools.js';
7
+ import { compressMessages } from './context.js';
8
+ import { systemPrompt } from './prompt.js';
9
+ import { formatToolLog } from './colors.js';
10
+ import { checkReadPermission } from './permission/read.js';
11
+ import { checkWritePermission } from './permission/write.js';
12
+ import { checkExecPermission } from './permission/exec.js';
13
+ import { checkNetworkPermission } from './permission/network.js';
14
+ import { runPreToolUseHooks, runPostToolUseHooks } from './hooks.js';
15
+ import { createModel } from './model.js';
22
16
  // ── 模型 ──────────────────────────────────────────────────
23
- const model = (0, model_1.createModel)({ streaming: true });
17
+ const model = createModel({ streaming: true });
24
18
  // ── State Schema ──────────────────────────────────────────
25
- const StateAnnotation = langgraph_1.Annotation.Root({
26
- messages: (0, langgraph_1.Annotation)({
27
- reducer: langgraph_2.messagesStateReducer,
19
+ const StateAnnotation = Annotation.Root({
20
+ messages: Annotation({
21
+ reducer: messagesStateReducer,
28
22
  default: () => [],
29
23
  }),
30
- contextSummary: (0, langgraph_1.Annotation)({
24
+ contextSummary: Annotation({
31
25
  reducer: (_prev, next) => next,
32
26
  default: () => null,
33
27
  }),
34
- compressionCount: (0, langgraph_1.Annotation)({
28
+ compressionCount: Annotation({
35
29
  reducer: (_prev, next) => next,
36
30
  default: () => 0,
37
31
  }),
38
- lastCompressedIndex: (0, langgraph_1.Annotation)({
32
+ lastCompressedIndex: Annotation({
39
33
  reducer: (_prev, next) => next,
40
34
  default: () => 0,
41
35
  }),
@@ -43,10 +37,10 @@ const StateAnnotation = langgraph_1.Annotation.Root({
43
37
  // ── Graph Nodes ───────────────────────────────────────────
44
38
  function shouldContinue(state) {
45
39
  const lastMessage = state.messages[state.messages.length - 1];
46
- if (messages_1.AIMessage.isInstance(lastMessage) && lastMessage.tool_calls?.length) {
40
+ if (AIMessage.isInstance(lastMessage) && lastMessage.tool_calls?.length) {
47
41
  return 'tools';
48
42
  }
49
- return langgraph_1.END;
43
+ return END;
50
44
  }
51
45
  function simplifyToolMessages(messages) {
52
46
  const toolIndices = [];
@@ -65,7 +59,7 @@ function simplifyToolMessages(messages) {
65
59
  const toolMsg = msg;
66
60
  if (toolMsg.name === 'read_file')
67
61
  return msg;
68
- return new messages_1.ToolMessage({
62
+ return new ToolMessage({
69
63
  content: `[Previous: used ${toolMsg.name}]`,
70
64
  tool_call_id: toolMsg.tool_call_id,
71
65
  name: toolMsg.name,
@@ -73,7 +67,7 @@ function simplifyToolMessages(messages) {
73
67
  });
74
68
  }
75
69
  // ── 记忆 ──────────────────────────────────────────────────
76
- const checkpointer = langgraph_checkpoint_sqlite_1.SqliteSaver.fromConnString(db_1.DB_PATH);
70
+ const checkpointer = SqliteSaver.fromConnString(DB_PATH);
77
71
  // ── Agent Graph 工厂 ──────────────────────────────────────
78
72
  function createAgentGraph(toolList) {
79
73
  const modelWithTheseTools = model.bindTools(toolList);
@@ -81,7 +75,7 @@ function createAgentGraph(toolList) {
81
75
  let modelMessages = state.messages ?? [];
82
76
  // compact context
83
77
  if (state.contextSummary && state.lastCompressedIndex > 0) {
84
- const summaryMsg = new messages_1.SystemMessage(`历史对话摘要:\n\n${state.contextSummary}`);
78
+ const summaryMsg = new SystemMessage(`历史对话摘要:\n\n${state.contextSummary}`);
85
79
  modelMessages = [
86
80
  summaryMsg,
87
81
  ...modelMessages.slice(state.lastCompressedIndex),
@@ -91,7 +85,7 @@ function createAgentGraph(toolList) {
91
85
  modelMessages = simplifyToolMessages(modelMessages);
92
86
  // keep recent 300 items
93
87
  modelMessages = modelMessages.slice(0, 300);
94
- const messages = [new messages_1.SystemMessage(prompt_1.systemPrompt), ...modelMessages];
88
+ const messages = [new SystemMessage(systemPrompt), ...modelMessages];
95
89
  const response = await modelWithTheseTools.invoke(messages, config);
96
90
  return { messages: [response] };
97
91
  }
@@ -102,12 +96,12 @@ function createAgentGraph(toolList) {
102
96
  .map((msg) => msg.tool_call_id));
103
97
  let aiMessage;
104
98
  for (let i = messages.length - 1; i >= 0; i--) {
105
- if (messages_1.AIMessage.isInstance(messages[i])) {
99
+ if (AIMessage.isInstance(messages[i])) {
106
100
  aiMessage = messages[i];
107
101
  break;
108
102
  }
109
103
  }
110
- if (!aiMessage || !messages_1.AIMessage.isInstance(aiMessage)) {
104
+ if (!aiMessage || !AIMessage.isInstance(aiMessage)) {
111
105
  throw new Error('ToolNode only accepts AIMessages as input.');
112
106
  }
113
107
  const toolCalls = aiMessage.tool_calls?.filter((call) => call.id == null || !toolMessageIds.has(call.id)) ?? [];
@@ -122,16 +116,16 @@ function createAgentGraph(toolList) {
122
116
  const level = tool?.permission_level;
123
117
  let decision;
124
118
  if (level === 'read') {
125
- decision = (0, read_1.checkReadPermission)(call);
119
+ decision = checkReadPermission(call);
126
120
  }
127
121
  else if (level === 'write') {
128
- decision = (0, write_1.checkWritePermission)(call);
122
+ decision = checkWritePermission(call);
129
123
  }
130
124
  else if (level === 'exec') {
131
- decision = (0, exec_1.checkExecPermission)(call);
125
+ decision = checkExecPermission(call);
132
126
  }
133
127
  else if (level === 'network') {
134
- decision = (0, network_1.checkNetworkPermission)(call);
128
+ decision = checkNetworkPermission(call);
135
129
  }
136
130
  else if (level === 'mcp') {
137
131
  decision = { action: 'confirm' };
@@ -143,7 +137,7 @@ function createAgentGraph(toolList) {
143
137
  allowCalls.push(call);
144
138
  }
145
139
  else if (decision.action === 'block') {
146
- blockMessages.push(new messages_1.ToolMessage({
140
+ blockMessages.push(new ToolMessage({
147
141
  content: decision.reason,
148
142
  tool_call_id: call.id ?? '',
149
143
  name: call.name,
@@ -156,18 +150,18 @@ function createAgentGraph(toolList) {
156
150
  async function executeCalls(calls) {
157
151
  return Promise.all(calls.map(async (call) => {
158
152
  const tool = toolList.find((t) => t.name === call.name);
159
- console.log((0, colors_1.formatToolLog)(call.name, JSON.stringify(call.args)));
153
+ console.log(formatToolLog(call.name, JSON.stringify(call.args)));
160
154
  try {
161
155
  const threadId = config?.configurable?.thread_id || '';
162
156
  // PreToolUse hook
163
- const preResult = await (0, hooks_1.runPreToolUseHooks)({
157
+ const preResult = await runPreToolUseHooks({
164
158
  toolName: call.name,
165
159
  toolArgs: call.args,
166
160
  toolCallId: call.id ?? '',
167
161
  threadId,
168
162
  });
169
163
  if (preResult.action === 'block') {
170
- return new messages_1.ToolMessage({
164
+ return new ToolMessage({
171
165
  content: preResult.reason,
172
166
  tool_call_id: call.id ?? '',
173
167
  name: call.name,
@@ -178,7 +172,7 @@ function createAgentGraph(toolList) {
178
172
  const output = await tool.invoke({ ...call, type: 'tool_call' }, config);
179
173
  let content = typeof output === 'string' ? output : JSON.stringify(output);
180
174
  // PostToolUse hook
181
- const postResult = await (0, hooks_1.runPostToolUseHooks)({
175
+ const postResult = await runPostToolUseHooks({
182
176
  toolName: call.name,
183
177
  toolArgs: call.args,
184
178
  toolOutput: content,
@@ -194,15 +188,15 @@ function createAgentGraph(toolList) {
194
188
  if (preResult.action === 'inject') {
195
189
  content = `[Hook injection]\n${preResult.message}\n\n${content}`;
196
190
  }
197
- const finalContent = await (0, tools_1.maybePersistedOutput)(content, call.id ?? '');
198
- return new messages_1.ToolMessage({
191
+ const finalContent = await maybePersistedOutput(content, call.id ?? '');
192
+ return new ToolMessage({
199
193
  content: finalContent,
200
194
  tool_call_id: call.id ?? '',
201
195
  name: call.name,
202
196
  });
203
197
  }
204
198
  catch (e) {
205
- return new messages_1.ToolMessage({
199
+ return new ToolMessage({
206
200
  content: `Error: ${e.message}\n Please fix your mistakes.`,
207
201
  tool_call_id: call.id ?? '',
208
202
  name: call.name,
@@ -214,9 +208,9 @@ function createAgentGraph(toolList) {
214
208
  if (confirmCalls.length === 0) {
215
209
  return { messages: [...allowOutputs, ...blockMessages] };
216
210
  }
217
- const result = (0, langgraph_1.interrupt)({ toolCalls: confirmCalls });
211
+ const result = interrupt({ toolCalls: confirmCalls });
218
212
  if (result !== 'approved') {
219
- const deniedMessages = confirmCalls.map((call) => new messages_1.ToolMessage({
213
+ const deniedMessages = confirmCalls.map((call) => new ToolMessage({
220
214
  content: 'Tool execution was denied by the user.',
221
215
  tool_call_id: call.id ?? '',
222
216
  name: call.name,
@@ -228,13 +222,13 @@ function createAgentGraph(toolList) {
228
222
  const confirmOutputs = await executeCalls(confirmCalls);
229
223
  return { messages: [...allowOutputs, ...blockMessages, ...confirmOutputs] };
230
224
  }
231
- const workflow = new langgraph_1.StateGraph(StateAnnotation)
225
+ const workflow = new StateGraph(StateAnnotation)
232
226
  .addNode('model_request', modelRequest)
233
227
  .addNode('tools', toolNode)
234
- .addEdge(langgraph_1.START, 'model_request')
228
+ .addEdge(START, 'model_request')
235
229
  .addConditionalEdges('model_request', shouldContinue, {
236
230
  tools: 'tools',
237
- [langgraph_1.END]: langgraph_1.END,
231
+ [END]: END,
238
232
  })
239
233
  .addEdge('tools', 'model_request');
240
234
  return workflow.compile({
@@ -244,10 +238,10 @@ function createAgentGraph(toolList) {
244
238
  // ── Agent 创建 ────────────────────────────────────────────
245
239
  let agent = null;
246
240
  let subAgent = null;
247
- async function initAgent() {
248
- await (0, tools_1.initTools)();
249
- agent = createAgentGraph(tools_1.tools);
250
- subAgent = createAgentGraph(tools_1.tools.filter((t) => t.name !== 'agent_tool'));
241
+ export async function initAgent() {
242
+ await initTools();
243
+ agent = createAgentGraph(tools);
244
+ subAgent = createAgentGraph(tools.filter((t) => t.name !== 'agent_tool'));
251
245
  }
252
246
  function getAgent() {
253
247
  if (!agent)
@@ -264,7 +258,7 @@ async function _runAgent(compiledAgent, userMessage, onToken, onToolConfirmation
264
258
  const config = { configurable: { thread_id: threadId } };
265
259
  let fullResponse = '';
266
260
  let usageMetadata;
267
- let input = { messages: [new messages_1.HumanMessage(userMessage)] };
261
+ let input = { messages: [new HumanMessage(userMessage)] };
268
262
  while (true) {
269
263
  const stream = await compiledAgent.stream(input, {
270
264
  ...config,
@@ -296,7 +290,7 @@ async function _runAgent(compiledAgent, userMessage, onToken, onToolConfirmation
296
290
  if (!interruptedTask)
297
291
  break;
298
292
  const confirmed = await onToolConfirmation(interruptedTask.interrupts[0].value.toolCalls);
299
- input = new langgraph_1.Command({ resume: confirmed ? 'approved' : 'denied' });
293
+ input = new Command({ resume: confirmed ? 'approved' : 'denied' });
300
294
  }
301
295
  return { response: fullResponse, usageMetadata };
302
296
  }
@@ -308,7 +302,7 @@ async function _runAgent(compiledAgent, userMessage, onToken, onToolConfirmation
308
302
  * @param {string} threadId - 会话 ID,相同 ID 自动续上历史记录
309
303
  * @returns {Promise<{ response: string; usageMetadata?: UsageMetadata }>} 完整的 AI 回复文本及 token 使用信息
310
304
  */
311
- async function runAgentStream(userMessage, onToken, onToolConfirmation, threadId = 'default-session', signal) {
305
+ export async function runAgentStream(userMessage, onToken, onToolConfirmation, threadId = 'default-session', signal) {
312
306
  return _runAgent(getAgent(), userMessage, onToken, onToolConfirmation, threadId, signal);
313
307
  }
314
308
  /**
@@ -316,14 +310,14 @@ async function runAgentStream(userMessage, onToken, onToolConfirmation, threadId
316
310
  * @param {string} prompt - 给 subagent 的任务提示
317
311
  * @returns {Promise<string>} subagent 的最终回复
318
312
  */
319
- async function runSubAgent(prompt) {
313
+ export async function runSubAgent(prompt) {
320
314
  const threadId = `subagent-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
321
315
  const result = await _runAgent(getSubAgent(), prompt.trim(), () => { }, // 不需要流式输出
322
316
  async () => true, // subagent 自动确认 tools
323
317
  threadId, undefined);
324
318
  return result.response;
325
319
  }
326
- async function compressContext(threadId) {
320
+ export async function compressContext(threadId) {
327
321
  const config = { configurable: { thread_id: threadId } };
328
322
  const currentState = await getAgent().getState(config);
329
323
  const messages = currentState.values.messages || [];
@@ -335,7 +329,7 @@ async function compressContext(threadId) {
335
329
  return { didCompress: false, count };
336
330
  }
337
331
  const toCompress = messages.slice(lastIndex, messages.length - recentKeep);
338
- const newSummary = await (0, context_1.compressMessages)(toCompress, existingSummary);
332
+ const newSummary = await compressMessages(toCompress, existingSummary);
339
333
  await getAgent().updateState(config, {
340
334
  contextSummary: newSummary,
341
335
  lastCompressedIndex: messages.length - recentKeep,
package/dist/agent/cli.js CHANGED
@@ -1,48 +1,14 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.interactiveChat = interactiveChat;
37
- const readline = __importStar(require("readline"));
38
- const fs_1 = require("fs");
39
- const path_1 = require("path");
40
- const agent_1 = require("./agent");
41
- const context_1 = require("./context");
42
- const colors_1 = require("./colors");
43
- const commands_1 = require("./commands");
44
- const hooks_1 = require("./hooks");
45
- const pkg = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, '../../package.json'), 'utf-8'));
1
+ import * as readline from 'readline';
2
+ import { readFileSync } from 'fs';
3
+ import { join, dirname } from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ import { runAgentStream, compressContext } from './agent.js';
6
+ import { getModelContextLimit } from './context.js';
7
+ import { color, formatToolLog } from './colors.js';
8
+ import { threadId, commands } from './commands.js';
9
+ import { runSessionStartHooks } from './hooks.js';
10
+ const __dirname = dirname(fileURLToPath(import.meta.url));
11
+ const pkg = JSON.parse(readFileSync(join(__dirname, '../../package.json'), 'utf-8'));
46
12
  function createInterface() {
47
13
  return readline.createInterface({
48
14
  input: process.stdin,
@@ -50,14 +16,14 @@ function createInterface() {
50
16
  });
51
17
  }
52
18
  async function printBanner() {
53
- const figlet = (await Promise.resolve().then(() => __importStar(require('figlet')))).default;
54
- const { default: boxen } = await Promise.resolve().then(() => __importStar(require('boxen')));
55
- console.log(colors_1.color.banner(figlet.textSync(pkg.name, { font: 'Slant' })));
19
+ const figlet = (await import('figlet')).default;
20
+ const { default: boxen } = await import('boxen');
21
+ console.log(color.banner(figlet.textSync(pkg.name, { font: 'Slant' })));
56
22
  const info = [
57
- `${colors_1.color.gray('Description')}: ${pkg.description}`,
58
- `${colors_1.color.gray('Version')}: ${pkg.version}`,
59
- `${colors_1.color.gray('Author')}: ${pkg.author}`,
60
- `${colors_1.color.gray('Docs')}: ${pkg.docs}`,
23
+ `${color.gray('Description')}: ${pkg.description}`,
24
+ `${color.gray('Version')}: ${pkg.version}`,
25
+ `${color.gray('Author')}: ${pkg.author}`,
26
+ `${color.gray('Docs')}: ${pkg.docs}`,
61
27
  ].join('\n');
62
28
  console.log(boxen(info, {
63
29
  padding: 1,
@@ -67,7 +33,7 @@ async function printBanner() {
67
33
  console.log('Usage:');
68
34
  console.log(' ESC - Cancel AI request');
69
35
  console.log(' exit - Exit the chat');
70
- for (const [name, cmd] of commands_1.commands) {
36
+ for (const [name, cmd] of commands) {
71
37
  console.log(` /${name.padEnd(8)} - ${cmd.description}`);
72
38
  }
73
39
  console.log();
@@ -83,12 +49,12 @@ function prompt(question) {
83
49
  }
84
50
  async function chat(userInput) {
85
51
  const rl = createInterface();
86
- process.stdout.write('\n' + colors_1.color.aiPrefix());
52
+ process.stdout.write('\n' + color.aiPrefix());
87
53
  const controller = new AbortController();
88
54
  // 监听 ESC 键,中断 AI 请求
89
55
  const escListener = (_str, key) => {
90
56
  if (key.name === 'escape' || key.name === 'esc') {
91
- process.stdout.write('\n\n' + colors_1.color.cancelled('[Cancelled]') + '\n');
57
+ process.stdout.write('\n\n' + color.cancelled('[Cancelled]') + '\n');
92
58
  controller.abort();
93
59
  rl.close();
94
60
  }
@@ -97,18 +63,18 @@ async function chat(userInput) {
97
63
  process.stdin.on('keypress', escListener);
98
64
  let usageMetadata;
99
65
  try {
100
- const result = await (0, agent_1.runAgentStream)(userInput, (token) => {
66
+ const result = await runAgentStream(userInput, (token) => {
101
67
  process.stdout.write(token);
102
68
  }, async (toolCalls) => {
103
69
  for (const call of toolCalls) {
104
- console.log((0, colors_1.formatToolLog)(call.name, JSON.stringify(call.args)));
70
+ console.log(formatToolLog(call.name, JSON.stringify(call.args)));
105
71
  }
106
72
  const answer = await new Promise((resolve) => {
107
73
  rl.question('确认执行以上工具? (y/n): ', resolve);
108
74
  });
109
75
  return (answer.trim().toLowerCase() === 'y' ||
110
76
  answer.trim().toLowerCase() === 'yes');
111
- }, commands_1.threadId, controller.signal);
77
+ }, threadId, controller.signal);
112
78
  usageMetadata = result.usageMetadata;
113
79
  }
114
80
  catch (err) {
@@ -121,23 +87,23 @@ async function chat(userInput) {
121
87
  rl.close();
122
88
  }
123
89
  if (usageMetadata) {
124
- const limit = (0, context_1.getModelContextLimit)();
90
+ const limit = getModelContextLimit();
125
91
  const percentage = (usageMetadata.total_tokens / limit) * 100;
126
92
  const percentageStr = percentage.toFixed(1);
127
93
  const tokenText = `Tokens: ${usageMetadata.total_tokens.toLocaleString()} / ${limit.toLocaleString()} (${percentageStr}%)`;
128
94
  if (percentage >= 80) {
129
95
  process.stdout.write('\n' +
130
- colors_1.color.error(tokenText) +
96
+ color.error(tokenText) +
131
97
  '\n' +
132
- colors_1.color.error('警告:Context window 接近大模型接口上限,即将压缩 Context,可能会丢失信息') +
98
+ color.error('警告:Context window 接近大模型接口上限,即将压缩 Context,可能会丢失信息') +
133
99
  '\n' +
134
- colors_1.color.error('建议输入 /new 命令开启新会话'));
100
+ color.error('建议输入 /new 命令开启新会话'));
135
101
  try {
136
- const result = await (0, agent_1.compressContext)(commands_1.threadId);
102
+ const result = await compressContext(threadId);
137
103
  if (result.didCompress) {
138
- process.stdout.write('\n' + colors_1.color.error(`Context 已压缩(第 ${result.count} 次),已保留最近 6 条消息`) + '\n');
104
+ process.stdout.write('\n' + color.error(`Context 已压缩(第 ${result.count} 次),已保留最近 6 条消息`) + '\n');
139
105
  if (result.count >= 3) {
140
- process.stdout.write(colors_1.color.error('强烈建议输入 /new 命令开启新会话,以避免信息丢失') + '\n');
106
+ process.stdout.write(color.error('强烈建议输入 /new 命令开启新会话,以避免信息丢失') + '\n');
141
107
  }
142
108
  }
143
109
  }
@@ -146,32 +112,32 @@ async function chat(userInput) {
146
112
  }
147
113
  }
148
114
  else {
149
- process.stdout.write('\n' + colors_1.color.tokenInfo(tokenText));
115
+ process.stdout.write('\n' + color.tokenInfo(tokenText));
150
116
  }
151
117
  }
152
118
  process.stdout.write('\n\n');
153
119
  }
154
- async function interactiveChat() {
120
+ export async function interactiveChat() {
155
121
  await printBanner();
156
- await (0, hooks_1.runSessionStartHooks)(commands_1.threadId);
122
+ await runSessionStartHooks(threadId);
157
123
  while (true) {
158
- const userInput = await prompt(colors_1.color.userPrefix());
124
+ const userInput = await prompt(color.userPrefix());
159
125
  if (!userInput.trim())
160
126
  continue;
161
127
  if (userInput.toLowerCase() === 'exit') {
162
- console.log(colors_1.color.goodbye('再见!'));
128
+ console.log(color.goodbye('再见!'));
163
129
  break;
164
130
  }
165
131
  if (userInput.startsWith('/')) {
166
132
  const parts = userInput.trim().split(/\s+/);
167
133
  const cmdName = parts[0].slice(1);
168
134
  const args = parts.slice(1);
169
- const cmd = commands_1.commands.get(cmdName);
135
+ const cmd = commands.get(cmdName);
170
136
  if (cmd) {
171
137
  await cmd.execute(args);
172
138
  }
173
139
  else {
174
- console.log(colors_1.color.error(`Unknown command: ${cmdName}`));
140
+ console.log(color.error(`Unknown command: ${cmdName}`));
175
141
  }
176
142
  continue;
177
143
  }
@@ -179,7 +145,7 @@ async function interactiveChat() {
179
145
  await chat(userInput);
180
146
  }
181
147
  catch (err) {
182
- console.error(colors_1.color.error(`请求出错: ${err.message}`));
148
+ console.error(color.error(`请求出错: ${err.message}`));
183
149
  }
184
150
  }
185
151
  }
@@ -1,44 +1,6 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.color = void 0;
37
- exports.initColors = initColors;
38
- exports.formatToolLog = formatToolLog;
39
1
  let _chalk = null;
40
- async function initColors() {
41
- const mod = (await Promise.resolve().then(() => __importStar(require('chalk'))));
2
+ export async function initColors() {
3
+ const mod = (await import('chalk'));
42
4
  _chalk = mod.default;
43
5
  }
44
6
  function createPlainFallback() {
@@ -55,7 +17,7 @@ function ck() {
55
17
  }
56
18
  return _chalk;
57
19
  }
58
- exports.color = {
20
+ export const color = {
59
21
  banner: (text) => ck().cyanBright.bold(text),
60
22
  userPrefix: () => ck().greenBright.bold('You: '),
61
23
  aiPrefix: () => ck().cyanBright.bold('AI: '),
@@ -72,10 +34,10 @@ exports.color = {
72
34
  info: (text) => ck().blueBright(text),
73
35
  good: (text) => ck().greenBright(text),
74
36
  };
75
- function formatToolLog(name, detail) {
76
- const parts = [exports.color.toolTag(), exports.color.toolName(name), exports.color.toolAction()];
37
+ export function formatToolLog(name, detail) {
38
+ const parts = [color.toolTag(), color.toolName(name), color.toolAction()];
77
39
  if (detail) {
78
- parts.push(exports.color.toolArg(detail));
40
+ parts.push(color.toolArg(detail));
79
41
  }
80
42
  return '\n' + parts.join(' ');
81
43
  }