zhitalk 0.0.0 → 0.0.3

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 (83) hide show
  1. package/CLAUDE.md +98 -0
  2. package/README.md +36 -1
  3. package/dist/agent/agent.d.ts +24 -0
  4. package/dist/agent/agent.js +345 -0
  5. package/dist/agent/cli.d.ts +1 -0
  6. package/dist/agent/cli.js +185 -0
  7. package/dist/agent/colors.d.ts +19 -0
  8. package/dist/agent/colors.js +81 -0
  9. package/dist/agent/commands.d.ts +7 -0
  10. package/dist/agent/commands.js +69 -0
  11. package/dist/agent/config.d.ts +38 -0
  12. package/dist/agent/config.js +116 -0
  13. package/dist/agent/context.d.ts +3 -0
  14. package/dist/agent/context.js +107 -0
  15. package/dist/agent/db.d.ts +21 -0
  16. package/dist/agent/db.js +159 -0
  17. package/dist/agent/hooks.d.ts +27 -0
  18. package/dist/agent/hooks.js +115 -0
  19. package/dist/agent/mcp/client.d.ts +25 -0
  20. package/dist/agent/mcp/client.js +113 -0
  21. package/dist/agent/mcp/index.d.ts +4 -0
  22. package/dist/agent/mcp/index.js +27 -0
  23. package/dist/agent/mcp/wrapper.d.ts +7 -0
  24. package/dist/agent/mcp/wrapper.js +25 -0
  25. package/dist/agent/model.d.ts +5 -0
  26. package/dist/agent/model.js +31 -0
  27. package/dist/agent/permission/dangerous-path.json +115 -0
  28. package/dist/agent/permission/exec.d.ts +11 -0
  29. package/dist/agent/permission/exec.js +34 -0
  30. package/dist/agent/permission/is-dangerous-path.d.ts +1 -0
  31. package/dist/agent/permission/is-dangerous-path.js +53 -0
  32. package/dist/agent/permission/is-safe-domains.d.ts +1 -0
  33. package/dist/agent/permission/is-safe-domains.js +142 -0
  34. package/dist/agent/permission/network.d.ts +8 -0
  35. package/dist/agent/permission/network.js +14 -0
  36. package/dist/agent/permission/read.d.ts +9 -0
  37. package/dist/agent/permission/read.js +17 -0
  38. package/dist/agent/permission/util.d.ts +11 -0
  39. package/dist/agent/permission/util.js +160 -0
  40. package/dist/agent/permission/write.d.ts +11 -0
  41. package/dist/agent/permission/write.js +21 -0
  42. package/dist/agent/prompt.d.ts +1 -0
  43. package/dist/agent/prompt.js +50 -0
  44. package/dist/agent/skills.d.ts +8 -0
  45. package/dist/agent/skills.js +91 -0
  46. package/dist/agent/tools/agent_tool.d.ts +3 -0
  47. package/dist/agent/tools/agent_tool.js +44 -0
  48. package/dist/agent/tools/exec_tool.d.ts +3 -0
  49. package/dist/agent/tools/exec_tool.js +28 -0
  50. package/dist/agent/tools/load_skill_tool.d.ts +3 -0
  51. package/dist/agent/tools/load_skill_tool.js +15 -0
  52. package/dist/agent/tools/memory_create_tool.d.ts +6 -0
  53. package/dist/agent/tools/memory_create_tool.js +37 -0
  54. package/dist/agent/tools/memory_delete_tool.d.ts +3 -0
  55. package/dist/agent/tools/memory_delete_tool.js +28 -0
  56. package/dist/agent/tools/memory_retrieve_tool.d.ts +4 -0
  57. package/dist/agent/tools/memory_retrieve_tool.js +24 -0
  58. package/dist/agent/tools/profile_update_tool.d.ts +3 -0
  59. package/dist/agent/tools/profile_update_tool.js +50 -0
  60. package/dist/agent/tools/read_file_tool.d.ts +3 -0
  61. package/dist/agent/tools/read_file_tool.js +16 -0
  62. package/dist/agent/tools/run_js_tool.d.ts +3 -0
  63. package/dist/agent/tools/run_js_tool.js +36 -0
  64. package/dist/agent/tools/run_py_tool.d.ts +3 -0
  65. package/dist/agent/tools/run_py_tool.js +27 -0
  66. package/dist/agent/tools/search.d.ts +3 -0
  67. package/dist/agent/tools/search.js +10 -0
  68. package/dist/agent/tools/web_fetch_tool.d.ts +3 -0
  69. package/dist/agent/tools/web_fetch_tool.js +33 -0
  70. package/dist/agent/tools/web_search_tool.d.ts +3 -0
  71. package/dist/agent/tools/web_search_tool.js +38 -0
  72. package/dist/agent/tools/write_file_tool.d.ts +4 -0
  73. package/dist/agent/tools/write_file_tool.js +15 -0
  74. package/dist/agent/tools.d.ts +8 -0
  75. package/dist/agent/tools.js +193 -0
  76. package/dist/agent/utils.d.ts +2 -0
  77. package/dist/agent/utils.js +30 -0
  78. package/dist/index.d.ts +2 -0
  79. package/dist/index.js +72 -0
  80. package/dist/install.d.ts +1 -0
  81. package/dist/install.js +108 -0
  82. package/package.json +43 -6
  83. package/index.js +0 -1
@@ -0,0 +1,185 @@
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'));
46
+ function createInterface() {
47
+ return readline.createInterface({
48
+ input: process.stdin,
49
+ output: process.stdout,
50
+ });
51
+ }
52
+ 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' })));
56
+ 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}`,
61
+ ].join('\n');
62
+ console.log(boxen(info, {
63
+ padding: 1,
64
+ borderStyle: 'round',
65
+ borderColor: 'gray',
66
+ }));
67
+ console.log('Usage:');
68
+ console.log(' ESC - Cancel AI request');
69
+ console.log(' exit - Exit the chat');
70
+ for (const [name, cmd] of commands_1.commands) {
71
+ console.log(` /${name.padEnd(8)} - ${cmd.description}`);
72
+ }
73
+ console.log();
74
+ }
75
+ function prompt(question) {
76
+ return new Promise((resolve) => {
77
+ const rl = createInterface();
78
+ rl.question(question, (answer) => {
79
+ rl.close();
80
+ resolve(answer);
81
+ });
82
+ });
83
+ }
84
+ async function chat(userInput) {
85
+ const rl = createInterface();
86
+ process.stdout.write('\n' + colors_1.color.aiPrefix());
87
+ const controller = new AbortController();
88
+ // 监听 ESC 键,中断 AI 请求
89
+ const escListener = (_str, key) => {
90
+ if (key.name === 'escape' || key.name === 'esc') {
91
+ process.stdout.write('\n\n' + colors_1.color.cancelled('[Cancelled]') + '\n');
92
+ controller.abort();
93
+ rl.close();
94
+ }
95
+ };
96
+ readline.emitKeypressEvents(process.stdin);
97
+ process.stdin.on('keypress', escListener);
98
+ let usageMetadata;
99
+ try {
100
+ const result = await (0, agent_1.runAgentStream)(userInput, (token) => {
101
+ process.stdout.write(token);
102
+ }, async (toolCalls) => {
103
+ for (const call of toolCalls) {
104
+ console.log((0, colors_1.formatToolLog)(call.name, JSON.stringify(call.args)));
105
+ }
106
+ const answer = await new Promise((resolve) => {
107
+ rl.question('确认执行以上工具? (y/n): ', resolve);
108
+ });
109
+ return (answer.trim().toLowerCase() === 'y' ||
110
+ answer.trim().toLowerCase() === 'yes');
111
+ }, commands_1.threadId, controller.signal);
112
+ usageMetadata = result.usageMetadata;
113
+ }
114
+ catch (err) {
115
+ if (err.message !== 'abort') {
116
+ throw err;
117
+ }
118
+ }
119
+ finally {
120
+ process.stdin.removeListener('keypress', escListener);
121
+ rl.close();
122
+ }
123
+ if (usageMetadata) {
124
+ const limit = (0, context_1.getModelContextLimit)();
125
+ const percentage = (usageMetadata.total_tokens / limit) * 100;
126
+ const percentageStr = percentage.toFixed(1);
127
+ const tokenText = `Tokens: ${usageMetadata.total_tokens.toLocaleString()} / ${limit.toLocaleString()} (${percentageStr}%)`;
128
+ if (percentage >= 80) {
129
+ process.stdout.write('\n' +
130
+ colors_1.color.error(tokenText) +
131
+ '\n' +
132
+ colors_1.color.error('警告:Context window 接近大模型接口上限,即将压缩 Context,可能会丢失信息') +
133
+ '\n' +
134
+ colors_1.color.error('建议输入 /new 命令开启新会话'));
135
+ try {
136
+ const result = await (0, agent_1.compressContext)(commands_1.threadId);
137
+ if (result.didCompress) {
138
+ process.stdout.write('\n' + colors_1.color.error(`Context 已压缩(第 ${result.count} 次),已保留最近 6 条消息`) + '\n');
139
+ if (result.count >= 3) {
140
+ process.stdout.write(colors_1.color.error('强烈建议输入 /new 命令开启新会话,以避免信息丢失') + '\n');
141
+ }
142
+ }
143
+ }
144
+ catch {
145
+ // 压缩失败不影响主流程
146
+ }
147
+ }
148
+ else {
149
+ process.stdout.write('\n' + colors_1.color.tokenInfo(tokenText));
150
+ }
151
+ }
152
+ process.stdout.write('\n\n');
153
+ }
154
+ async function interactiveChat() {
155
+ await printBanner();
156
+ await (0, hooks_1.runSessionStartHooks)(commands_1.threadId);
157
+ while (true) {
158
+ const userInput = await prompt(colors_1.color.userPrefix());
159
+ if (!userInput.trim())
160
+ continue;
161
+ if (userInput.toLowerCase() === 'exit') {
162
+ console.log(colors_1.color.goodbye('再见!'));
163
+ break;
164
+ }
165
+ if (userInput.startsWith('/')) {
166
+ const parts = userInput.trim().split(/\s+/);
167
+ const cmdName = parts[0].slice(1);
168
+ const args = parts.slice(1);
169
+ const cmd = commands_1.commands.get(cmdName);
170
+ if (cmd) {
171
+ await cmd.execute(args);
172
+ }
173
+ else {
174
+ console.log(colors_1.color.error(`Unknown command: ${cmdName}`));
175
+ }
176
+ continue;
177
+ }
178
+ try {
179
+ await chat(userInput);
180
+ }
181
+ catch (err) {
182
+ console.error(colors_1.color.error(`请求出错: ${err.message}`));
183
+ }
184
+ }
185
+ }
@@ -0,0 +1,19 @@
1
+ export declare function initColors(): Promise<void>;
2
+ export declare const color: {
3
+ banner: (text: string) => string;
4
+ userPrefix: () => string;
5
+ aiPrefix: () => string;
6
+ goodbye: (text: string) => string;
7
+ cancelled: (text: string) => string;
8
+ error: (text: string) => string;
9
+ toolTag: () => string;
10
+ toolName: (name: string) => string;
11
+ toolAction: () => string;
12
+ toolArg: (arg: string) => string;
13
+ gray: (text: string) => string;
14
+ tokenInfo: (text: string) => string;
15
+ warn: (text: string) => string;
16
+ info: (text: string) => string;
17
+ good: (text: string) => string;
18
+ };
19
+ export declare function formatToolLog(name: string, detail?: string): string;
@@ -0,0 +1,81 @@
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
+ let _chalk = null;
40
+ async function initColors() {
41
+ const mod = (await Promise.resolve().then(() => __importStar(require('chalk'))));
42
+ _chalk = mod.default;
43
+ }
44
+ function createPlainFallback() {
45
+ const handler = {
46
+ get: () => createPlainFallback(),
47
+ apply: (_target, _thisArg, args) => args[0] ?? '',
48
+ };
49
+ const fn = (...args) => args[0] ?? '';
50
+ return new Proxy(fn, handler);
51
+ }
52
+ function ck() {
53
+ if (!_chalk) {
54
+ return createPlainFallback();
55
+ }
56
+ return _chalk;
57
+ }
58
+ exports.color = {
59
+ banner: (text) => ck().cyanBright.bold(text),
60
+ userPrefix: () => ck().greenBright.bold('You: '),
61
+ aiPrefix: () => ck().cyanBright.bold('AI: '),
62
+ goodbye: (text) => ck().yellowBright(text),
63
+ cancelled: (text) => ck().yellowBright.bold(text),
64
+ error: (text) => ck().redBright.bold(text),
65
+ toolTag: () => ck().magentaBright('[Tool]'),
66
+ toolName: (name) => ck().yellowBright(name),
67
+ toolAction: () => ck().gray('called:'),
68
+ toolArg: (arg) => ck().cyan(arg),
69
+ gray: (text) => ck().gray(text),
70
+ tokenInfo: (text) => ck().gray(text),
71
+ warn: (text) => ck().yellow(text),
72
+ info: (text) => ck().blueBright(text),
73
+ good: (text) => ck().greenBright(text),
74
+ };
75
+ function formatToolLog(name, detail) {
76
+ const parts = [exports.color.toolTag(), exports.color.toolName(name), exports.color.toolAction()];
77
+ if (detail) {
78
+ parts.push(exports.color.toolArg(detail));
79
+ }
80
+ return '\n' + parts.join(' ');
81
+ }
@@ -0,0 +1,7 @@
1
+ export declare let threadId: string;
2
+ export interface ChatCommand {
3
+ name: string;
4
+ description: string;
5
+ execute(args: string[]): void | Promise<void>;
6
+ }
7
+ export declare const commands: Map<string, ChatCommand>;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.commands = exports.threadId = void 0;
7
+ const crypto_1 = require("crypto");
8
+ const cli_table3_1 = __importDefault(require("cli-table3"));
9
+ const colors_1 = require("./colors");
10
+ const db_1 = require("./db");
11
+ const agent_1 = require("./agent");
12
+ exports.threadId = (0, crypto_1.randomUUID)();
13
+ exports.commands = new Map();
14
+ exports.commands.set('new', {
15
+ name: 'new',
16
+ description: 'Start a new chat session',
17
+ execute() {
18
+ exports.threadId = (0, crypto_1.randomUUID)();
19
+ console.log(colors_1.color.goodbye(`\nNew session started ${exports.threadId}.\n`));
20
+ },
21
+ });
22
+ exports.commands.set('rewind', {
23
+ name: 'rewind',
24
+ description: 'Restore a chat session by thread_id',
25
+ execute(args) {
26
+ const id = args[0];
27
+ if (!id) {
28
+ console.log(colors_1.color.error('\nError: please provide a thread_id. Usage: /rewind <thread_id>\n'));
29
+ return;
30
+ }
31
+ if (!(0, db_1.threadIdExists)(id)) {
32
+ console.log(colors_1.color.error(`\nError: thread_id "${id}" not found.\n`));
33
+ return;
34
+ }
35
+ exports.threadId = id;
36
+ console.log(colors_1.color.goodbye(`\nRestored session ${exports.threadId}.\n`));
37
+ },
38
+ });
39
+ exports.commands.set('sessions', {
40
+ name: 'sessions',
41
+ description: 'List recent chat sessions',
42
+ execute() {
43
+ const sessions = (0, db_1.listRecentSessions)();
44
+ if (sessions.length === 0) {
45
+ console.log('\n暂无聊天记录\n');
46
+ return;
47
+ }
48
+ const table = new cli_table3_1.default({
49
+ head: ['thread_id', '最后用户输入的问题', '时间'],
50
+ });
51
+ for (const s of sessions) {
52
+ table.push([s.thread_id, s.last_question, s.last_ts]);
53
+ }
54
+ console.log('\n' + table.toString() + '\n');
55
+ },
56
+ });
57
+ exports.commands.set('compact', {
58
+ name: 'compact',
59
+ description: 'Compress context for the current session',
60
+ async execute() {
61
+ const result = await (0, agent_1.compressContext)(exports.threadId);
62
+ if (result.didCompress) {
63
+ console.log(colors_1.color.goodbye(`\nContext compressed (count: ${result.count}).\n`));
64
+ }
65
+ else {
66
+ console.log('\nNo context to compress.\n');
67
+ }
68
+ },
69
+ });
@@ -0,0 +1,38 @@
1
+ export declare const WORKSPACE_DIR: string;
2
+ export declare const CONFIG_PATH: string;
3
+ interface ModelConfig {
4
+ model: string;
5
+ apiKey: string;
6
+ baseURL: string;
7
+ }
8
+ export interface HookConfig {
9
+ matcher: string;
10
+ command: string;
11
+ }
12
+ export interface HooksConfig {
13
+ hooks: {
14
+ PreToolUse?: HookConfig[];
15
+ PostToolUse?: HookConfig[];
16
+ SessionStart?: HookConfig[];
17
+ };
18
+ }
19
+ export interface McpServerConfig {
20
+ command?: string;
21
+ args?: string[];
22
+ env?: Record<string, string>;
23
+ url?: string;
24
+ headers?: Record<string, string>;
25
+ }
26
+ interface ZhitalkConfig {
27
+ model?: ModelConfig;
28
+ env?: Record<string, string>;
29
+ hooks?: HooksConfig['hooks'];
30
+ mcpServers?: Record<string, McpServerConfig>;
31
+ }
32
+ export declare function loadConfig(): ZhitalkConfig;
33
+ export declare function getModelConfig(): ModelConfig;
34
+ export declare function getEnv(key: string): string | undefined;
35
+ export declare function getHooksConfig(): HooksConfig;
36
+ export declare function getMCPServerConfig(): Record<string, McpServerConfig>;
37
+ export declare function clearConfigCache(): void;
38
+ export {};
@@ -0,0 +1,116 @@
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.CONFIG_PATH = exports.WORKSPACE_DIR = void 0;
37
+ exports.loadConfig = loadConfig;
38
+ exports.getModelConfig = getModelConfig;
39
+ exports.getEnv = getEnv;
40
+ exports.getHooksConfig = getHooksConfig;
41
+ exports.getMCPServerConfig = getMCPServerConfig;
42
+ exports.clearConfigCache = clearConfigCache;
43
+ const fs = __importStar(require("fs"));
44
+ const path = __importStar(require("path"));
45
+ const os = __importStar(require("os"));
46
+ exports.WORKSPACE_DIR = path.join(os.homedir(), '.zhitalk');
47
+ exports.CONFIG_PATH = path.join(exports.WORKSPACE_DIR, 'zhitalk.json');
48
+ let cachedConfig = null;
49
+ function loadConfig() {
50
+ if (cachedConfig) {
51
+ return cachedConfig;
52
+ }
53
+ if (!fs.existsSync(exports.CONFIG_PATH)) {
54
+ throw new Error(`找不到配置文件 ${exports.CONFIG_PATH}\n\n请创建该文件并配置相关信息,例如:\n{\n "model": {\n "model": "kimi-k2.6",\n "apiKey": "your-api-key",\n "baseURL": "https://api.moonshot.cn/v1"\n },\n "env": {\n "TAVILY_API_KEY": "your-tavily-api-key"\n }\n}`);
55
+ }
56
+ let config;
57
+ try {
58
+ const content = fs.readFileSync(exports.CONFIG_PATH, 'utf-8');
59
+ config = JSON.parse(content);
60
+ }
61
+ catch (e) {
62
+ throw new Error(`配置文件 ${exports.CONFIG_PATH} 解析失败:${e instanceof Error ? e.message : String(e)}`);
63
+ }
64
+ cachedConfig = config;
65
+ return config;
66
+ }
67
+ function getModelConfig() {
68
+ const config = loadConfig();
69
+ if (!config.model || typeof config.model !== 'object') {
70
+ throw new Error(`配置文件 ${exports.CONFIG_PATH} 中缺少 model 对象,请参考 https://zhitalk.chat/#config 修改配置`);
71
+ }
72
+ if (!config.model.model) {
73
+ throw new Error(`配置文件 ${exports.CONFIG_PATH} 中缺少 model.model 字段,请参考 https://zhitalk.chat/#config 修改配置`);
74
+ }
75
+ if (!config.model.apiKey) {
76
+ throw new Error(`配置文件 ${exports.CONFIG_PATH} 中缺少 model.apiKey 字段,请参考 https://zhitalk.chat/#config 修改配置`);
77
+ }
78
+ if (!config.model.baseURL) {
79
+ throw new Error(`配置文件 ${exports.CONFIG_PATH} 中缺少 model.baseURL 字段,请参考 https://zhitalk.chat/#config 修改配置`);
80
+ }
81
+ return config.model;
82
+ }
83
+ function getEnv(key) {
84
+ const config = loadConfig();
85
+ return config.env?.[key];
86
+ }
87
+ function getHooksConfig() {
88
+ try {
89
+ const config = loadConfig();
90
+ return { hooks: config.hooks || {} };
91
+ }
92
+ catch {
93
+ return { hooks: {} };
94
+ }
95
+ }
96
+ function getMCPServerConfig() {
97
+ try {
98
+ const content = fs.readFileSync(exports.CONFIG_PATH, 'utf-8');
99
+ const parsed = JSON.parse(content);
100
+ if (!parsed.mcpServers || typeof parsed.mcpServers !== 'object') {
101
+ // console.warn('[MCP] zhitalk.json missing "mcpServers" field, skipping')
102
+ return {};
103
+ }
104
+ return parsed.mcpServers;
105
+ }
106
+ catch (err) {
107
+ if (err.code === 'ENOENT') {
108
+ return {};
109
+ }
110
+ console.warn(`[MCP] Failed to load zhitalk.json: ${err.message}, skipping`);
111
+ return {};
112
+ }
113
+ }
114
+ function clearConfigCache() {
115
+ cachedConfig = null;
116
+ }
@@ -0,0 +1,3 @@
1
+ import { BaseMessage } from '@langchain/core/messages';
2
+ export declare function getModelContextLimit(): number;
3
+ export declare function compressMessages(messages: BaseMessage[], existingSummary: string | null): Promise<string>;
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getModelContextLimit = getModelContextLimit;
4
+ exports.compressMessages = compressMessages;
5
+ const messages_1 = require("@langchain/core/messages");
6
+ const model_1 = require("./model");
7
+ const config_1 = require("./config");
8
+ const MODEL_CONTEXT_LIMITS = {
9
+ // Moonshot / Kimi
10
+ 'moonshot-v1-8k': 8192,
11
+ 'moonshot-v1-32k': 32768,
12
+ 'moonshot-v1-128k': 131072,
13
+ 'kimi-k2.6': 256000,
14
+ // DeepSeek
15
+ 'deepseek-chat': 1048576,
16
+ 'deepseek-reasoner': 1048576,
17
+ 'deepseek-v3': 65536,
18
+ 'deepseek-v3.1': 131072,
19
+ 'deepseek-v4': 1048576,
20
+ 'deepseek-r1': 65536,
21
+ // MiniMax
22
+ 'minimax-text-01': 1048576,
23
+ 'minimax-m1': 1048576,
24
+ 'minimax-m3': 1048576,
25
+ // GLM (Zhipu)
26
+ 'glm-4': 131072,
27
+ 'glm-4-plus': 131072,
28
+ 'glm-4-air': 131072,
29
+ 'glm-4-flash': 131072,
30
+ 'glm-4v': 131072,
31
+ // Qwen (Alibaba)
32
+ 'qwen-max': 32768,
33
+ 'qwen-plus': 131072,
34
+ 'qwen-plus-2025-07-28': 1048576,
35
+ 'qwen-turbo': 1048576,
36
+ 'qwen-long': 10485760,
37
+ // Xiaomi MiMo
38
+ 'mimo-7b': 32768,
39
+ 'mimo-v2.5': 1048576,
40
+ };
41
+ function getModelContextLimit() {
42
+ const modelName = (0, config_1.getModelConfig)().model || '';
43
+ return MODEL_CONTEXT_LIMITS[modelName.toLowerCase()] || 128000;
44
+ }
45
+ function formatMessagesForCompression(messages) {
46
+ return messages
47
+ .map((msg) => {
48
+ const role = msg.type;
49
+ let content = typeof msg.content === 'string'
50
+ ? msg.content
51
+ : JSON.stringify(msg.content);
52
+ if (role === 'ai' && msg.tool_calls?.length) {
53
+ content += `\n[Tool Calls: ${JSON.stringify(msg.tool_calls)}]`;
54
+ }
55
+ return `[${role}] ${content}`;
56
+ })
57
+ .join('\n\n');
58
+ }
59
+ async function compressMessages(messages, existingSummary) {
60
+ if (messages.length === 0) {
61
+ return existingSummary || '';
62
+ }
63
+ const text = formatMessagesForCompression(messages);
64
+ const prompt = `请对以下对话内容进行结构化压缩摘要,要求如下:
65
+
66
+ 1. 压缩比例至少 50%,去除重复、冗余、语气词和过渡性内容,但保留所有关键决策、结论、数据和待办事项。
67
+ 2. 若对话包含多轮主题,请按主题分段压缩。
68
+ 3. 无内容的项目可写“无”。
69
+
70
+ 输出格式(Markdown):
71
+
72
+ ## 时间
73
+ 对话发生的时间范围或关键时间点。
74
+
75
+ ## 摘要
76
+ 概括本轮对话的核心内容。
77
+
78
+ ## 决策
79
+ 列出对话中做出的所有明确决策(如技术选型、方案确定、优先级调整等)。
80
+
81
+ ## 结论
82
+ 列出对话中达成的所有结论或共识。
83
+
84
+ ## 待办
85
+ 列出所有明确的待办事项(TODO),包括负责人(如有)。
86
+
87
+ ## 遗留问题
88
+ 列出尚未解决、需要后续跟进的问题。
89
+
90
+ ## 原话摘要
91
+ 摘录最具代表性的原话或关键信息,用引号标注。
92
+
93
+ ---
94
+
95
+ 对话内容如下:
96
+
97
+ ${text}`;
98
+ const model = (0, model_1.createModel)({ streaming: false });
99
+ const response = await model.invoke([new messages_1.HumanMessage(prompt)]);
100
+ const newSummary = typeof response.content === 'string'
101
+ ? response.content
102
+ : JSON.stringify(response.content);
103
+ if (existingSummary) {
104
+ return `${existingSummary}\n\n[后续对话摘要]\n${newSummary}`;
105
+ }
106
+ return newSummary;
107
+ }
@@ -0,0 +1,21 @@
1
+ export declare const DB_PATH: string;
2
+ export interface SessionRow {
3
+ thread_id: string;
4
+ last_question: string;
5
+ last_ts: string;
6
+ }
7
+ export interface MemorySearchResult {
8
+ id: number;
9
+ type: string;
10
+ content: string;
11
+ keywords: string | null;
12
+ importance: number;
13
+ session_id: string | null;
14
+ created_at: string;
15
+ updated_at: string;
16
+ final_score: number;
17
+ }
18
+ export declare function searchMemories(query: string[], limit?: number): MemorySearchResult[];
19
+ export declare function threadIdExists(threadId: string): boolean;
20
+ export declare function initDb(): void;
21
+ export declare function listRecentSessions(): SessionRow[];