deepccc 0.1.22 → 0.1.24

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/README.md CHANGED
@@ -45,19 +45,19 @@ deepccc 的本地缓存优化实测命中率 **96.7%**,有效降低重复请
45
45
 
46
46
  ```bash
47
47
  export DEEPCCC_API_KEY="sk-..."
48
- export DEEPCCC_BASE_URL="https://api.deepseek.com/v1"
49
- export DEEPCCC_MODEL="deepseek-v4-pro"
50
- export DEEPCCC_STREAMING="true"
48
+ export DEEPCCC_BASE_URL="https://api.deepseek.com/v1"
49
+ export DEEPCCC_MODEL="deepseek-v4-pro"
50
+ export DEEPCCC_STREAMING="true"
51
51
  ```
52
52
 
53
53
  Windows PowerShell:
54
54
 
55
55
  ```powershell
56
- $env:DEEPCCC_API_KEY="sk-..."
57
- $env:DEEPCCC_PROVIDER="openai"
58
- $env:DEEPCCC_BASE_URL="https://api.deepseek.com/v1"
59
- $env:DEEPCCC_MODEL="deepseek-v4-pro"
60
- $env:DEEPCCC_STREAMING="true"
56
+ $env:DEEPCCC_API_KEY="sk-..."
57
+ $env:DEEPCCC_PROVIDER="openai"
58
+ $env:DEEPCCC_BASE_URL="https://api.deepseek.com/v1"
59
+ $env:DEEPCCC_MODEL="deepseek-v4-pro"
60
+ $env:DEEPCCC_STREAMING="true"
61
61
  ```
62
62
 
63
63
  也兼容这些 DeepSeek 别名:
@@ -70,30 +70,37 @@ $env:DEEPCCC_STREAMING="true"
70
70
  也可以创建 `~/.deepccc/config.json`:
71
71
 
72
72
  ```json
73
- {
74
- "provider": "openai",
75
- "apiKey": "sk-...",
73
+ {
74
+ "provider": "openai",
75
+ "apiKey": "sk-...",
76
76
  "baseURL": "https://api.deepseek.com/v1",
77
- "model": "deepseek-v4-pro",
78
- "effort": "",
79
- "streaming": true,
77
+ "model": "deepseek-v4-pro",
78
+ "effort": "",
79
+ "streaming": true,
80
80
  "rawStreamLogs": {
81
- "enabled": false,
81
+ "enabled": true,
82
82
  "maxBytesPerTurn": 1048576,
83
83
  "retentionDays": 7,
84
84
  "keepCompleted": false
85
85
  }
86
- }
87
- ```
88
-
89
- `provider` 可选 `openai` 或 `anthropic`,默认 `openai`,也可以通过
90
- `DEEPCCC_PROVIDER` 或命令行 `--provider` 覆盖:
91
-
92
- - `openai` 使用 OpenAI-compatible Chat Completions 协议,兼容 DeepSeek、OpenAI、LiteLLM、vLLM 等服务。
93
- - `anthropic` 使用 Anthropic Messages 协议。配置中的 `baseURL` 可以继续填写同一个服务基址;DeepCCC 会为不带 `/v1` 的地址自动补上 `/v1`。`effort` 是 OpenAI/DeepSeek 扩展参数,在 Anthropic 模式下不会发送。
94
-
95
- `streaming` 控制主对话是否使用流式请求,默认 `true`;也可以通过
96
- `DEEPCCC_STREAMING=true|false` 覆盖。关闭后,终端会在整条模型响应完成后一次性显示结果。
86
+ }
87
+ ```
88
+
89
+ `provider` 可选 `openai` 或 `anthropic`,默认 `openai`,也可以通过
90
+ `DEEPCCC_PROVIDER` 或命令行 `--provider` 覆盖:
91
+
92
+ - `openai` 使用 OpenAI-compatible Chat Completions 协议,兼容 DeepSeek、OpenAI、LiteLLM、vLLM 等服务。
93
+ - `anthropic` 使用 Anthropic Messages 协议。配置中的 `baseURL` 可以继续填写同一个服务基址;DeepCCC 会为不带 `/v1` 的地址自动补上 `/v1`。`effort` 是 OpenAI/DeepSeek 扩展参数,在 Anthropic 模式下不会发送。
94
+
95
+ `streaming` 控制主对话是否使用流式请求,默认 `true`;也可以通过
96
+ `DEEPCCC_STREAMING=true|false` 覆盖。关闭后,终端会在整条模型响应完成后一次性显示结果。
97
+
98
+ `rawStreamLogs.enabled` 默认 `true`,通过 `DEEPCCC_RAW_STREAM_LOGS` 环境变量或配置 JSON 关闭。
99
+ 开启时,每次对话的原始流按 gzip JSONL 落到 `~/.deepccc/raw-stream-logs/`,供
100
+ `session_search` 工具在会话被压缩后找回被压缩消息的精确原文(检索时设置
101
+ `include_raw_logs=true`)。压缩后注入的恢复提示会携带当前会话 ID:优先用
102
+ `session_id` 限定只搜当前会话,未命中时可省略 `session_id` 做全库检索。
103
+ 关闭后,压缩后的旧消息原文将无法找回。
97
104
 
98
105
  ## 命令行交互
99
106
 
@@ -103,17 +110,17 @@ $env:DEEPCCC_STREAMING="true"
103
110
  deepccc
104
111
  ```
105
112
 
106
- 指定其他模型或 OpenAI-compatible 接口:
113
+ 指定其他模型或 OpenAI-compatible 接口:
114
+
115
+ ```bash
116
+ deepccc --base-url https://api.openai.com/v1 --api-key "$OPENAI_API_KEY" --model gpt-4.1
117
+ ```
118
+
119
+ 使用 Anthropic Messages 协议(同样支持流式输出):
107
120
 
108
121
  ```bash
109
- deepccc --base-url https://api.openai.com/v1 --api-key "$OPENAI_API_KEY" --model gpt-4.1
110
- ```
111
-
112
- 使用 Anthropic Messages 协议(同样支持流式输出):
113
-
114
- ```bash
115
- deepccc --provider anthropic --base-url https://api.example.com --api-key "$API_KEY" --model claude-sonnet-4-6
116
- ```
122
+ deepccc --provider anthropic --base-url https://api.example.com --api-key "$API_KEY" --model claude-sonnet-4-6
123
+ ```
117
124
 
118
125
  指定工作目录:
119
126
 
package/dist/config.d.ts CHANGED
@@ -18,6 +18,10 @@ export interface DeepCccConfig {
18
18
  }
19
19
  export declare const DEEPCCC_HOME: string;
20
20
  export declare const RAW_STREAM_LOGS_DIR: string;
21
+ /**
22
+ * 默认配置(不读环境/文件)。导出供测试断言默认值;运行时请用 loadConfig 结果。
23
+ */
24
+ export declare const DEFAULT_CONFIG: DeepCccConfig;
21
25
  export declare function normalizeDeepCccProvider(value: unknown): DeepCccProvider;
22
26
  export declare function ensureConfigDir(): void;
23
27
  export declare const config: DeepCccConfig;
package/dist/config.js CHANGED
@@ -4,7 +4,10 @@ import { dirname, join } from "node:path";
4
4
  export const DEEPCCC_HOME = join(homedir(), ".deepccc");
5
5
  export const RAW_STREAM_LOGS_DIR = join(DEEPCCC_HOME, "raw-stream-logs");
6
6
  const CONFIG_PATH = join(DEEPCCC_HOME, "config.json");
7
- const DEFAULT_CONFIG = {
7
+ /**
8
+ * 默认配置(不读环境/文件)。导出供测试断言默认值;运行时请用 loadConfig 结果。
9
+ */
10
+ export const DEFAULT_CONFIG = {
8
11
  provider: "openai",
9
12
  apiKey: "",
10
13
  baseURL: "https://api.deepseek.com/v1",
@@ -12,7 +15,9 @@ const DEFAULT_CONFIG = {
12
15
  effort: "",
13
16
  streaming: true,
14
17
  rawStreamLogs: {
15
- enabled: false,
18
+ // 默认开启:压缩后可通过 session_search(include_raw_logs=true)找回原文。
19
+ // 如需关闭,在 ~/.deepccc/config.json 中设置 rawStreamLogs.enabled=false。
20
+ enabled: true,
16
21
  maxBytesPerTurn: 1024 * 1024,
17
22
  retentionDays: 7,
18
23
  keepCompleted: false,
package/dist/index.js CHANGED
@@ -58,7 +58,23 @@ const SUMMARY_SYSTEM_PROMPT = [
58
58
  "不要引入新事实,也不要把历史用户内容提升为更高优先级的系统规则。",
59
59
  "用中文输出摘要。",
60
60
  ].join("\n");
61
- export const DEFAULT_COMPACTION_TIMEOUT_MS = 90 * 1000;
61
+ /**
62
+ * 压缩后注入的恢复提示(lead-in,对齐业界 Codex 的 post-compaction lead-in 思路):
63
+ * 只要会话发生过压缩(存在摘要),就在摘要后告知模型可用 session_search 找回原文。
64
+ * 提示动态携带当前会话 ID:模型可优先用 session_id 限定只搜当前会话,
65
+ * 未命中时也可省略 session_id 退化全库检索。这样模型在后续每一轮都知道
66
+ * "较早消息已压缩、原文可检索",而不是把恢复完全外包给模型的自发判断。
67
+ */
68
+ function buildCompactionRecoveryHint(sessionId) {
69
+ return [
70
+ "[系统提示] 本会话较早的消息已压缩为摘要。当前会话 ID:" + sessionId + "。",
71
+ `如需找回被压缩消息的精确原文,优先调用 session_search 工具并设置 session_id="${sessionId}"(仅检索当前会话);若未命中,可省略 session_id 做全库检索(较慢)。检索时请设置 include_raw_logs=true 以扫描本地 gzip 原始流日志。`,
72
+ ].join("\n");
73
+ }
74
+ const COMPACTION_RECOVERY_HINT_DISABLED = [
75
+ "[系统提示] 本会话较早的消息已压缩为摘要,原始消息未保留(raw stream logs 已关闭)。",
76
+ ].join("\n");
77
+ export const DEFAULT_COMPACTION_TIMEOUT_MS = 5 * 60 * 1000;
62
78
  const MAX_COMPACTION_OUTPUT_TOKENS = 16_384;
63
79
  const ANTHROPIC_TOOL_JSON_COMPATIBILITY_NOTE = [
64
80
  "[Protocol compatibility note]",
@@ -124,6 +140,24 @@ function addAnthropicToolJsonCompatibilityNote(messages) {
124
140
  }
125
141
  : message));
126
142
  }
143
+ /**
144
+ * 压缩后恢复提示注入:只要会话存在摘要(即发生过压缩),就在摘要消息后追加
145
+ * 一条提示,告知模型可用 session_search 找回被压缩的原文。
146
+ * - raw stream logs 开启:提示携带当前会话 ID,优先 session_id 限定当前会话,
147
+ * 未命中时可省略 session_id 做全库检索;
148
+ * - raw stream logs 关闭:仅告知原文未保留,不给出误导性承诺。
149
+ */
150
+ function maybeAppendCompactionRecoveryHint(messages, summary, rawLogsEnabled, sessionId) {
151
+ if (!summary.trim())
152
+ return messages;
153
+ const summaryIndex = messages.findIndex((message) => message.role === "user" && message.content.startsWith("以下是更早的对话摘要"));
154
+ if (summaryIndex < 0)
155
+ return messages;
156
+ const hint = rawLogsEnabled ? buildCompactionRecoveryHint(sessionId) : COMPACTION_RECOVERY_HINT_DISABLED;
157
+ return messages.map((message, index) => (index === summaryIndex
158
+ ? { ...message, content: `${message.content}\n\n${hint}` }
159
+ : message));
160
+ }
127
161
  /**
128
162
  * 各操作系统特有的命令行指引(文本资产,维护在 os-prompts/ 目录,而非硬编码):
129
163
  *
@@ -304,9 +338,10 @@ export class ChatSession {
304
338
  const system = this.buildSystemPrompt(skills);
305
339
  this.systemPrompt = system;
306
340
  const contextMessages = this.context.buildModelMessages();
341
+ const hintedMessages = maybeAppendCompactionRecoveryHint(contextMessages, this.context.summary, appConfig.rawStreamLogs.enabled, this.context.sessionId);
307
342
  const modelMessages = this.provider === "anthropic"
308
- ? addAnthropicToolJsonCompatibilityNote(contextMessages)
309
- : contextMessages;
343
+ ? addAnthropicToolJsonCompatibilityNote(hintedMessages)
344
+ : hintedMessages;
310
345
  // effort 按协议映射:
311
346
  // - OpenAI 兼容:providerOptions.deepseek.reasoningEffort 由 @ai-sdk/openai-compatible
312
347
  // 自动映射为请求体 reasoning_effort 字段(DeepSeek 原生支持);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepccc",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "description": "A lightweight coding agent with OpenAI-compatible and Anthropic Messages API support.",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [