deepccc 0.1.27 → 0.1.28

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
@@ -46,8 +46,10 @@ deepccc 的本地缓存优化实测命中率 **96.7%**,有效降低重复请
46
46
  ```bash
47
47
  export DEEPCCC_API_KEY="sk-..."
48
48
  export DEEPCCC_BASE_URL="https://api.deepseek.com/v1"
49
- export DEEPCCC_MODEL="deepseek-v4-pro"
50
- export DEEPCCC_STREAMING="true"
49
+ export DEEPCCC_MODEL="deepseek-v4-pro"
50
+ export DEEPCCC_EFFORT="high"
51
+ export DEEPCCC_MAX_OUTPUT_TOKENS="32768"
52
+ export DEEPCCC_STREAMING="true"
51
53
  ```
52
54
 
53
55
  Windows PowerShell:
@@ -56,8 +58,10 @@ Windows PowerShell:
56
58
  $env:DEEPCCC_API_KEY="sk-..."
57
59
  $env:DEEPCCC_PROVIDER="openai"
58
60
  $env:DEEPCCC_BASE_URL="https://api.deepseek.com/v1"
59
- $env:DEEPCCC_MODEL="deepseek-v4-pro"
60
- $env:DEEPCCC_STREAMING="true"
61
+ $env:DEEPCCC_MODEL="deepseek-v4-pro"
62
+ $env:DEEPCCC_EFFORT="high"
63
+ $env:DEEPCCC_MAX_OUTPUT_TOKENS="32768"
64
+ $env:DEEPCCC_STREAMING="true"
61
65
  ```
62
66
 
63
67
  也兼容这些 DeepSeek 别名:
@@ -75,10 +79,18 @@ $env:DEEPCCC_STREAMING="true"
75
79
  "apiKey": "sk-...",
76
80
  "baseURL": "https://api.deepseek.com/v1",
77
81
  "model": "deepseek-v4-pro",
78
- "subModel": "",
79
- "effort": "",
80
- "streaming": true,
82
+ "subModel": "",
83
+ "effort": "",
84
+ "maxOutputTokens": null,
85
+ "streaming": true,
81
86
  "contextWindow": 1048576,
87
+ "git": {
88
+ "coAuthor": {
89
+ "enabled": true,
90
+ "name": "DeepCCC",
91
+ "email": "20184052+wzj998@users.noreply.github.com"
92
+ }
93
+ },
82
94
  "rawStreamLogs": {
83
95
  "enabled": true,
84
96
  "maxBytesPerTurn": 1048576,
@@ -88,14 +100,24 @@ $env:DEEPCCC_STREAMING="true"
88
100
  }
89
101
  ```
90
102
 
103
+ `git.coAuthor.enabled` 默认开启。DeepCCC 通过 `run_command` 创建 Git 提交时会保留用户为
104
+ 主 Author,并追加 `Co-authored-by: DeepCCC <20184052+wzj998@users.noreply.github.com>`。
105
+ 可设为 `false` 或用 `DEEPCCC_GIT_COAUTHOR=false` 全局关闭。ChatCCC 的
106
+ `ccc.gitCoAuthor` 是三态 override:`null`/缺失跟随这里,`true` 强制开启,`false` 强制关闭。
107
+
91
108
  `provider` 可选 `openai` 或 `anthropic`,默认 `openai`,也可以通过
92
109
  `DEEPCCC_PROVIDER` 或命令行 `--provider` 覆盖:
93
110
 
94
111
  - `openai` 使用 OpenAI-compatible Chat Completions 协议,兼容 DeepSeek、OpenAI、LiteLLM、vLLM 等服务。
95
- - `anthropic` 使用 Anthropic Messages 协议。配置中的 `baseURL` **完全按填写值使用,不自动补 `/v1`**,请填写到完整版本化地址,例如 DeepSeek 官方 Anthropic 端点为 `https://api.deepseek.com/anthropic/v1`(官方 Anthropic SDK 使用的 `https://api.deepseek.com/anthropic` 基址会拼接为 `.../anthropic/v1/messages`)。`effort` 是 OpenAI/DeepSeek 扩展参数,在 Anthropic 模式下不会发送。
112
+ - `anthropic` 使用 Anthropic Messages 协议。配置中的 `baseURL` **完全按填写值使用,不自动补 `/v1`**,请填写到完整版本化地址,例如 DeepSeek 官方 Anthropic 端点为 `https://api.deepseek.com/anthropic/v1`(官方 Anthropic SDK 使用的 `https://api.deepseek.com/anthropic` 基址会拼接为 `.../anthropic/v1/messages`)。`effort` 在 OpenAI-compatible 模式映射为 `reasoning_effort`,在 Anthropic 模式映射为 `output_config.effort`;目标服务不支持时应留空。
96
113
 
97
- `streaming` 控制主对话是否使用流式请求,默认 `true`;也可以通过
98
- `DEEPCCC_STREAMING=true|false` 覆盖。关闭后,终端会在整条模型响应完成后一次性显示结果。
114
+ `streaming` 控制主对话是否使用流式请求,默认 `true`;也可以通过
115
+ `DEEPCCC_STREAMING=true|false` 覆盖。关闭后,终端会在整条模型响应完成后一次性显示结果。
116
+
117
+ `maxOutputTokens` 限制主对话单次最大输出 token,默认不配置(`null`/缺失),此时不向
118
+ Provider 发送 `max_tokens`,使用模型服务端默认值。可通过 `DEEPCCC_MAX_OUTPUT_TOKENS`
119
+ 或命令行 `--max-output-tokens` 覆盖;只接受正整数。该限制会同时覆盖模型思考内容、
120
+ 工具参数和最终回答,设置过小可能导致工具调用或长回复被截断。
99
121
 
100
122
  `contextWindow` 是模型上下文窗口(token),默认 `1048576`(1M,DeepSeek V4 Pro/Flash
101
123
  原生规格);上下文压缩阈值自动 = `contextWindow × 0.8`(超出即把较早消息压缩为摘要)。
@@ -166,7 +188,15 @@ deepccc --max-steps 20
166
188
  deepccc --effort high
167
189
  ```
168
190
 
169
- 可选值:`none` / `minimal` / `low` / `medium` / `high` / `xhigh` / `max`(留空则不传 `reasoning_effort` 请求字段)。
191
+ 可选值:`none` / `minimal` / `low` / `medium` / `high` / `xhigh` / `max`(留空则不传 `reasoning_effort` 请求字段)。
192
+
193
+ 限制主对话最大输出 token:
194
+
195
+ ```bash
196
+ deepccc --max-output-tokens 8192
197
+ ```
198
+
199
+ 不设置时使用 Provider 默认值。
170
200
 
171
201
  ## 权限机制
172
202
 
package/dist/cli.js CHANGED
@@ -65,6 +65,10 @@ function parseArgs(argv = process.argv.slice(2)) {
65
65
  config.effort = next;
66
66
  i++;
67
67
  }
68
+ else if (arg === "--max-output-tokens" && next !== undefined) {
69
+ config.maxOutputTokens = parsePositiveIntegerOption("--max-output-tokens", next);
70
+ i++;
71
+ }
68
72
  else if (arg === "--base-url" && next !== undefined) {
69
73
  config.baseURL = next;
70
74
  i++;
@@ -131,6 +135,7 @@ function printHelp(appConfig) {
131
135
  ` --model <name> Model name (current default ${appConfig.model})`,
132
136
  ` --sub-model <name> Sub-model for lightweight steps (compaction/task; empty = follow main model)`,
133
137
  ` --effort <level> Reasoning effort: none/minimal/low/medium/high/xhigh/max (overrides config.effort)`,
138
+ ` --max-output-tokens <n> Maximum output tokens (unset = Provider default)`,
134
139
  ` --base-url <url> Provider API base URL (current default ${appConfig.baseURL})`,
135
140
  " --api-key <key> API key",
136
141
  " --cwd <path> Working directory",
package/dist/config.d.ts CHANGED
@@ -12,6 +12,8 @@ export interface DeepCccConfig {
12
12
  subModel: string;
13
13
  /** Reasoning effort(none/minimal/low/medium/high/xhigh/max),留空不传 reasoning_effort */
14
14
  effort: string;
15
+ /** 主对话最大输出 token;未配置时不传,使用 Provider 默认值。 */
16
+ maxOutputTokens?: number;
15
17
  /** 主对话是否使用流式请求;默认开启 */
16
18
  streaming: boolean;
17
19
  /**
@@ -19,6 +21,13 @@ export interface DeepCccConfig {
19
21
  * 上下文压缩阈值自动 = contextWindow × 0.8;超过模型/服务端实际上限会被 API 拒绝。
20
22
  */
21
23
  contextWindow: number;
24
+ git: {
25
+ coAuthor: {
26
+ enabled: boolean;
27
+ name: string;
28
+ email: string;
29
+ };
30
+ };
22
31
  rawStreamLogs: {
23
32
  enabled: boolean;
24
33
  maxBytesPerTurn: number;
package/dist/config.js CHANGED
@@ -16,6 +16,13 @@ export const DEFAULT_CONFIG = {
16
16
  effort: "",
17
17
  streaming: true,
18
18
  contextWindow: 1_048_576,
19
+ git: {
20
+ coAuthor: {
21
+ enabled: true,
22
+ name: "DeepCCC",
23
+ email: "20184052+wzj998@users.noreply.github.com",
24
+ },
25
+ },
19
26
  rawStreamLogs: {
20
27
  // 默认开启:压缩后可通过 session_search(include_raw_logs=true)找回原文。
21
28
  // 如需关闭,在 ~/.deepccc/config.json 中设置 rawStreamLogs.enabled=false。
@@ -49,6 +56,12 @@ function numberEnv(name) {
49
56
  const value = Number(env(name));
50
57
  return Number.isFinite(value) && value >= 0 ? value : undefined;
51
58
  }
59
+ function optionalPositiveInteger(value) {
60
+ if (value === undefined || value === null || value === "")
61
+ return undefined;
62
+ const parsed = Number(value);
63
+ return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;
64
+ }
52
65
  export function normalizeDeepCccProvider(value) {
53
66
  if (value === undefined || value === null || String(value).trim() === "")
54
67
  return "openai";
@@ -62,6 +75,8 @@ function loadConfig() {
62
75
  const rawLogs = file.rawStreamLogs && typeof file.rawStreamLogs === "object"
63
76
  ? file.rawStreamLogs
64
77
  : {};
78
+ const git = file.git && typeof file.git === "object" ? file.git : {};
79
+ const coAuthor = git.coAuthor && typeof git.coAuthor === "object" ? git.coAuthor : {};
65
80
  return {
66
81
  provider: normalizeDeepCccProvider(env("DEEPCCC_PROVIDER") ?? file.provider ?? DEFAULT_CONFIG.provider),
67
82
  apiKey: env("DEEPCCC_API_KEY") ?? env("DEEPSEEK_API_KEY") ?? file.apiKey ?? DEFAULT_CONFIG.apiKey,
@@ -69,8 +84,17 @@ function loadConfig() {
69
84
  model: env("DEEPCCC_MODEL") ?? env("DEEPSEEK_MODEL") ?? file.model ?? DEFAULT_CONFIG.model,
70
85
  subModel: env("DEEPCCC_SUB_MODEL") ?? file.subModel ?? DEFAULT_CONFIG.subModel,
71
86
  effort: env("DEEPCCC_EFFORT") ?? env("DEEPSEEK_EFFORT") ?? file.effort ?? DEFAULT_CONFIG.effort,
87
+ maxOutputTokens: optionalPositiveInteger(env("DEEPCCC_MAX_OUTPUT_TOKENS"))
88
+ ?? optionalPositiveInteger(file.maxOutputTokens),
72
89
  streaming: boolEnv("DEEPCCC_STREAMING") ?? file.streaming ?? DEFAULT_CONFIG.streaming,
73
90
  contextWindow: numberEnv("DEEPCCC_CONTEXT_WINDOW") ?? file.contextWindow ?? DEFAULT_CONFIG.contextWindow,
91
+ git: {
92
+ coAuthor: {
93
+ enabled: boolEnv("DEEPCCC_GIT_COAUTHOR") ?? coAuthor.enabled ?? DEFAULT_CONFIG.git.coAuthor.enabled,
94
+ name: coAuthor.name?.trim() || DEFAULT_CONFIG.git.coAuthor.name,
95
+ email: coAuthor.email?.trim() || DEFAULT_CONFIG.git.coAuthor.email,
96
+ },
97
+ },
74
98
  rawStreamLogs: {
75
99
  enabled: boolEnv("DEEPCCC_RAW_STREAM_LOGS") ?? rawLogs.enabled ?? DEFAULT_CONFIG.rawStreamLogs.enabled,
76
100
  maxBytesPerTurn: numberEnv("DEEPCCC_RAW_STREAM_MAX_BYTES") ?? rawLogs.maxBytesPerTurn ?? DEFAULT_CONFIG.rawStreamLogs.maxBytesPerTurn,
@@ -71,6 +71,13 @@ export interface RunCommandOutput {
71
71
  truncated: boolean;
72
72
  durationMs: number;
73
73
  }
74
+ export interface GitCoAuthorOptions {
75
+ enabled: boolean;
76
+ name: string;
77
+ email: string;
78
+ }
79
+ /** Adds DeepCCC attribution to git commit commands without replacing the user's author. */
80
+ export declare function withGitCoAuthor(command: string, coAuthor?: GitCoAuthorOptions): string;
74
81
  export interface FileEdit {
75
82
  oldText: string;
76
83
  newText: string;
@@ -143,7 +150,7 @@ export declare function expandHomePath(value: string): string;
143
150
  export declare function readFileForTool(cwd: string, input: ReadFileInput): Promise<ReadFileOutput>;
144
151
  export declare function listDirForTool(cwd: string, input?: ListDirInput): Promise<ListDirOutput>;
145
152
  export declare function searchCodeForTool(cwd: string, input: SearchCodeInput, signal?: AbortSignal, runtimeOptions?: SearchCodeRuntimeOptions): Promise<SearchCodeOutput>;
146
- export declare function runCommandForTool(cwd: string, input: RunCommandInput, abortSignal?: AbortSignal): Promise<RunCommandOutput>;
153
+ export declare function runCommandForTool(cwd: string, input: RunCommandInput, abortSignal?: AbortSignal, coAuthor?: GitCoAuthorOptions): Promise<RunCommandOutput>;
147
154
  export declare function editFileForTool(cwd: string, input: EditFileInput): Promise<EditFileOutput>;
148
155
  export declare function createFileForTool(cwd: string, input: CreateFileInput): Promise<FileWriteOutput>;
149
156
  export declare function deleteFileForTool(cwd: string, input: DeleteFileInput): Promise<DeleteFileOutput>;
@@ -152,6 +159,8 @@ export declare function applyPatchForTool(cwd: string, input: ApplyPatchInput):
152
159
  export interface BuiltinFileToolsOptions {
153
160
  /** 权限门控:副作用工具(run_command/文件写操作)执行前会先经过 gate.check */
154
161
  permissionGate?: PermissionGate;
162
+ /** Git commits created by DeepCCC receive this Co-authored-by trailer when enabled. */
163
+ gitCoAuthor?: GitCoAuthorOptions;
155
164
  /** session_search 工具的会话/原始日志目录(默认 ~/.deepccc/sessions 与 raw-stream-logs;测试可注入) */
156
165
  sessionSearch?: {
157
166
  contextDir?: string;
@@ -26,6 +26,13 @@ const MAX_COMMAND_TIMEOUT_MS = 900_000;
26
26
  export const MAX_TASK_OUTPUT_CHARS = 32_000;
27
27
  const requireFromHere = createRequire(import.meta.url);
28
28
  const FALLBACK_SKIPPED_DIRECTORIES = new Set([".git", "node_modules"]);
29
+ /** Adds DeepCCC attribution to git commit commands without replacing the user's author. */
30
+ export function withGitCoAuthor(command, coAuthor) {
31
+ if (!coAuthor?.enabled || command.includes(coAuthor.email))
32
+ return command;
33
+ const trailer = ` --trailer "Co-authored-by: ${coAuthor.name} <${coAuthor.email}>"`;
34
+ return command.replace(/(^|(?:&&|\|\||;|\|)\s*)(git\s+commit)\b/g, (_match, prefix, gitCommit) => `${prefix}${gitCommit}${trailer}`);
35
+ }
29
36
  /**
30
37
  * 把 `~` / `~/x`(含反斜杠 `~\\x`)展开为用户主目录绝对路径。
31
38
  * `~user/x` 形式不展开(Node 无内置支持),保持原样交给后续解析。
@@ -676,8 +683,8 @@ export async function searchCodeForTool(cwd, input, signal, runtimeOptions = {})
676
683
  : fallback.truncated,
677
684
  };
678
685
  }
679
- export async function runCommandForTool(cwd, input, abortSignal) {
680
- const command = input.command?.trim();
686
+ export async function runCommandForTool(cwd, input, abortSignal, coAuthor) {
687
+ const command = withGitCoAuthor(input.command?.trim(), coAuthor);
681
688
  if (!command)
682
689
  throw new Error("command is required");
683
690
  const commandCwd = resolveToolPath(cwd, input.cwd);
@@ -1016,14 +1023,14 @@ export function createBuiltinFileTools(cwd, options = {}) {
1016
1023
  },
1017
1024
  required: ["command"],
1018
1025
  }),
1019
- execute: async (input, options) => {
1026
+ execute: async (input, execOptions) => {
1020
1027
  await guard({
1021
1028
  tool: "run_command",
1022
1029
  action: input.command,
1023
1030
  reason: isDangerousCommand(input.command) ? "high-risk" : "rule",
1024
1031
  detail: `运行命令: ${input.command}`,
1025
1032
  });
1026
- return runCommandForTool(cwd, input, options.abortSignal);
1033
+ return runCommandForTool(cwd, input, execOptions.abortSignal, options.gitCoAuthor);
1027
1034
  },
1028
1035
  }),
1029
1036
  task: tool({
package/dist/index.d.ts CHANGED
@@ -37,6 +37,8 @@ export interface ChatSessionConfig {
37
37
  * overrides config.effort; empty omits the reasoning_effort request field.
38
38
  */
39
39
  effort?: string;
40
+ /** Maximum output tokens for the main conversation; unset uses the Provider default. */
41
+ maxOutputTokens?: number;
40
42
  }
41
43
  export interface ChatSessionOptions {
42
44
  /** Session working directory. */
@@ -78,6 +80,8 @@ export interface ChatSessionOptions {
78
80
  * 调用)自动拒绝高危命令,常规文件操作与低危命令不受影响。
79
81
  */
80
82
  permissionResolver?: PermissionResolver;
83
+ /** Overrides ~/.deepccc/config.json git.coAuthor.enabled for this integration. */
84
+ gitCoAuthor?: boolean;
81
85
  }
82
86
  /**
83
87
  * 流式响应事件
@@ -136,9 +140,11 @@ export declare class ChatSession {
136
140
  private compactionTimeoutMs;
137
141
  private maxSteps?;
138
142
  private effort;
143
+ private maxOutputTokens?;
139
144
  private permissionMode;
140
145
  private permissionResolver?;
141
146
  private permissionGate;
147
+ private gitCoAuthorEnabled;
142
148
  private skillDirs;
143
149
  private customSystemPrompt;
144
150
  /** 最近一次 chat() 使用的 system prompt(供 history 等读取) */
package/dist/index.js CHANGED
@@ -77,6 +77,7 @@ const COMPACTION_RECOVERY_HINT_DISABLED = [
77
77
  ].join("\n");
78
78
  export const DEFAULT_COMPACTION_TIMEOUT_MS = 5 * 60 * 1000;
79
79
  const MAX_COMPACTION_OUTPUT_TOKENS = 16_384;
80
+ const OPENAI_COMPATIBLE_PROVIDER_NAME = "deepccc";
80
81
  /** task 子代理工具:子代理单轮对话的最大工具步数(防失控循环,结果收敛后即结束) */
81
82
  const TASK_MAX_STEPS = 20;
82
83
  /** 子代理最终输出截断:保留前 MAX_TASK_OUTPUT_CHARS 字符,尾部注明截断信息 */
@@ -219,6 +220,14 @@ function normalizeMaxSteps(value) {
219
220
  }
220
221
  return value;
221
222
  }
223
+ function normalizeMaxOutputTokens(value) {
224
+ if (value === undefined)
225
+ return undefined;
226
+ if (!Number.isFinite(value) || !Number.isInteger(value) || value <= 0) {
227
+ throw new Error("maxOutputTokens must be a positive integer when provided");
228
+ }
229
+ return value;
230
+ }
222
231
  function normalizeAnthropicBaseURL(baseURL) {
223
232
  // 完全按用户填写的地址使用,不自动补 /v1(AI SDK 仅对官方 api.anthropic.com
224
233
  // 特判补一次 /v1,其他地址原样拼接 /messages)。
@@ -239,9 +248,11 @@ export class ChatSession {
239
248
  compactionTimeoutMs;
240
249
  maxSteps;
241
250
  effort;
251
+ maxOutputTokens;
242
252
  permissionMode;
243
253
  permissionResolver;
244
254
  permissionGate;
255
+ gitCoAuthorEnabled;
245
256
  skillDirs;
246
257
  customSystemPrompt;
247
258
  /** 最近一次 chat() 使用的 system prompt(供 history 等读取) */
@@ -266,6 +277,7 @@ export class ChatSession {
266
277
  baseURL: this.baseURL,
267
278
  model: this.subModelId || this.modelId,
268
279
  effort: this.effort,
280
+ maxOutputTokens: this.maxOutputTokens,
269
281
  }, {
270
282
  cwd: taskCwd,
271
283
  persist: false,
@@ -303,6 +315,7 @@ export class ChatSession {
303
315
  this.subModelId = (overrides.subModel ?? appConfig.subModel ?? "").trim();
304
316
  this.provider = normalizeDeepCccProvider(overrides.provider ?? appConfig.provider);
305
317
  this.effort = (overrides.effort ?? appConfig.effort ?? "").trim();
318
+ this.maxOutputTokens = normalizeMaxOutputTokens(overrides.maxOutputTokens ?? appConfig.maxOutputTokens);
306
319
  this.apiKey = apiKey;
307
320
  this.baseURL = baseURL;
308
321
  const provider = this.provider === "anthropic"
@@ -311,7 +324,7 @@ export class ChatSession {
311
324
  apiKey,
312
325
  })
313
326
  : createOpenAICompatible({
314
- name: "deepccc",
327
+ name: OPENAI_COMPATIBLE_PROVIDER_NAME,
315
328
  baseURL,
316
329
  apiKey,
317
330
  includeUsage: true,
@@ -325,6 +338,7 @@ export class ChatSession {
325
338
  this.customSystemPrompt = options.systemPrompt ?? "";
326
339
  this.permissionMode = options.permissionMode ?? "ask";
327
340
  this.permissionResolver = options.permissionResolver;
341
+ this.gitCoAuthorEnabled = options.gitCoAuthor ?? appConfig.git.coAuthor.enabled;
328
342
  // 技能目录在构造时确定;技能内容在每次 chat() 前重新扫描(mtime 热加载),
329
343
  // 因此创建/修改技能后下一次对话自动生效,无需重启。
330
344
  this.skillDirs =
@@ -413,14 +427,14 @@ export class ChatSession {
413
427
  ? addAnthropicToolJsonCompatibilityNote(hintedMessages)
414
428
  : hintedMessages;
415
429
  // effort 按协议映射:
416
- // - OpenAI 兼容:providerOptions.deepseek.reasoningEffort 由 @ai-sdk/openai-compatible
417
- // 自动映射为请求体 reasoning_effort 字段(DeepSeek 原生支持);
430
+ // - OpenAI 兼容:providerOptions 的 key 必须与 createOpenAICompatible.name 一致;
431
+ // reasoningEffort 由 SDK 映射为请求体 reasoning_effort 字段;
418
432
  // - Anthropic:providerOptions.anthropic.effort 由 @ai-sdk/anthropic 组装为请求体
419
433
  // output_config.effort(官方 Effort API,见 platform.claude.com/docs/en/build-with-claude/effort)
420
434
  let effortProviderOptions;
421
435
  if (this.effort) {
422
436
  effortProviderOptions = this.provider === "openai"
423
- ? { deepseek: { reasoningEffort: this.effort } }
437
+ ? { [OPENAI_COMPATIBLE_PROVIDER_NAME]: { reasoningEffort: this.effort } }
424
438
  : { anthropic: { effort: this.effort } };
425
439
  }
426
440
  const baseGenerationOptions = {
@@ -429,9 +443,16 @@ export class ChatSession {
429
443
  tools: createBuiltinFileTools(this.cwd, {
430
444
  permissionGate: this.permissionGate,
431
445
  runTask: this.runTask,
446
+ gitCoAuthor: {
447
+ ...appConfig.git.coAuthor,
448
+ enabled: this.gitCoAuthorEnabled,
449
+ },
432
450
  }),
433
451
  stopWhen: maxSteps !== undefined ? stepCountIs(maxSteps) : isLoopFinished(),
434
452
  abortSignal: signal,
453
+ ...(this.maxOutputTokens !== undefined
454
+ ? { maxOutputTokens: this.maxOutputTokens }
455
+ : {}),
435
456
  ...(effortProviderOptions ? { providerOptions: effortProviderOptions } : {}),
436
457
  };
437
458
  for (let attempt = 0; attempt < 2; attempt += 1) {
@@ -624,7 +645,7 @@ export class ChatSession {
624
645
  // output_config.effort=low),避免继承主对话的高 effort 拖慢"压缩上下文中"阶段。
625
646
  maxOutputTokens: MAX_COMPACTION_OUTPUT_TOKENS,
626
647
  providerOptions: this.provider === "openai"
627
- ? { deepseek: { reasoningEffort: "none" } }
648
+ ? { [OPENAI_COMPATIBLE_PROVIDER_NAME]: { reasoningEffort: "none" } }
628
649
  : { anthropic: { effort: "low" } },
629
650
  });
630
651
  if (!result.text.trim()) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepccc",
3
- "version": "0.1.27",
3
+ "version": "0.1.28",
4
4
  "description": "A lightweight coding agent with OpenAI-compatible and Anthropic Messages API support.",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [