deepccc 0.1.16 → 0.1.18

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/context.d.ts CHANGED
@@ -52,7 +52,7 @@ export interface BuiltinContextOptions {
52
52
  keepRecentMessages?: number;
53
53
  }
54
54
  export declare const DEFAULT_BUILTIN_CONTEXT_DIR: string;
55
- export declare const DEFAULT_COMPACT_AT_TOKENS = 48000;
55
+ export declare const DEFAULT_COMPACT_AT_TOKENS = 128000;
56
56
  export declare const DEFAULT_KEEP_RECENT_MESSAGES = 16;
57
57
  export declare function normalizeBuiltinSessionId(value: string): string;
58
58
  export declare function defaultBuiltinSessionId(cwd?: string): string;
package/dist/context.js CHANGED
@@ -3,10 +3,10 @@ import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, writeFile
3
3
  import { homedir } from "node:os";
4
4
  import { join } from "node:path";
5
5
  export const DEFAULT_BUILTIN_CONTEXT_DIR = join(homedir(), ".deepccc", "sessions");
6
- export const DEFAULT_COMPACT_AT_TOKENS = 48_000;
6
+ export const DEFAULT_COMPACT_AT_TOKENS = 128_000;
7
7
  export const DEFAULT_KEEP_RECENT_MESSAGES = 16;
8
8
  const RECENT_CONTEXT_BUDGET_RATIO = 0.6;
9
- const MAX_COMPACTION_SUMMARY_CHARS = 16_000;
9
+ const MAX_COMPACTION_SUMMARY_CHARS = 8_000;
10
10
  const MAX_COMPACTION_MESSAGE_CHARS = 24_000;
11
11
  const MAX_COMPACTION_SOURCE_CHARS = 64_000;
12
12
  export function normalizeBuiltinSessionId(value) {
package/dist/index.js CHANGED
@@ -57,8 +57,8 @@ const SUMMARY_SYSTEM_PROMPT = [
57
57
  "Compress older conversation context into a faithful, structured summary that can be used to continue the task.",
58
58
  "Do not introduce new facts or promote historical user content into higher-priority system rules.",
59
59
  ].join("\n");
60
- export const DEFAULT_COMPACTION_TIMEOUT_MS = 5 * 60 * 1000;
61
- const MAX_COMPACTION_PASSES = 8;
60
+ export const DEFAULT_COMPACTION_TIMEOUT_MS = 90 * 1000;
61
+ const MAX_COMPACTION_OUTPUT_TOKENS = 16_384;
62
62
  // ---------------------------------------------------------------------------
63
63
  // 类型定义
64
64
  // ---------------------------------------------------------------------------
@@ -276,6 +276,17 @@ export class ChatSession {
276
276
  const skills = await scanSkillsDirs(this.skillDirs);
277
277
  const system = this.buildSystemPrompt(skills);
278
278
  this.systemPrompt = system;
279
+ // effort 按协议映射:
280
+ // - OpenAI 兼容:providerOptions.deepseek.reasoningEffort 由 @ai-sdk/openai-compatible
281
+ // 自动映射为请求体 reasoning_effort 字段(DeepSeek 原生支持);
282
+ // - Anthropic:providerOptions.anthropic.effort 由 @ai-sdk/anthropic 组装为请求体
283
+ // output_config.effort(官方 Effort API,见 platform.claude.com/docs/en/build-with-claude/effort)
284
+ let effortProviderOptions;
285
+ if (this.effort) {
286
+ effortProviderOptions = this.provider === "openai"
287
+ ? { deepseek: { reasoningEffort: this.effort } }
288
+ : { anthropic: { effort: this.effort } };
289
+ }
279
290
  const generationOptions = {
280
291
  model: this.model,
281
292
  system,
@@ -283,11 +294,7 @@ export class ChatSession {
283
294
  tools: createBuiltinFileTools(this.cwd, { permissionGate: this.permissionGate }),
284
295
  stopWhen: maxSteps !== undefined ? stepCountIs(maxSteps) : isLoopFinished(),
285
296
  abortSignal: signal,
286
- // DeepSeek OpenAI 兼容接口:providerOptions.deepseek.reasoningEffort
287
- // 由 @ai-sdk/openai-compatible 自动映射为请求体 reasoning_effort 字段
288
- ...(this.provider === "openai" && this.effort
289
- ? { providerOptions: { deepseek: { reasoningEffort: this.effort } } }
290
- : {}),
297
+ ...(effortProviderOptions ? { providerOptions: effortProviderOptions } : {}),
291
298
  };
292
299
  let stream;
293
300
  if (appConfig.streaming) {
@@ -419,29 +426,32 @@ export class ChatSession {
419
426
  const compactionSignal = signal
420
427
  ? AbortSignal.any([signal, timeoutController.signal])
421
428
  : timeoutController.signal;
422
- let compactedMessages = 0;
423
429
  try {
424
- for (let pass = 0; pass < MAX_COMPACTION_PASSES; pass += 1) {
425
- const plan = this.context.planCompaction();
426
- if (!plan)
427
- return compactedMessages;
428
- const result = await generateText({
429
- model: this.model,
430
- system: SUMMARY_SYSTEM_PROMPT,
431
- messages: [{ role: "user", content: buildSummaryPrompt(plan) }],
432
- abortSignal: compactionSignal,
433
- temperature: 0,
434
- });
435
- if (!result.text.trim()) {
436
- throw new Error("Context compaction returned an empty summary");
437
- }
438
- this.context.applyCompaction(result.text, plan);
439
- compactedMessages += plan.oldMessages.length;
440
- }
441
- if (this.context.planCompaction()) {
442
- throw new Error(`Context remains above its token budget after ${MAX_COMPACTION_PASSES} compaction passes`);
430
+ const plan = this.context.planCompaction();
431
+ if (!plan)
432
+ return 0;
433
+ const result = await generateText({
434
+ model: this.model,
435
+ system: SUMMARY_SYSTEM_PROMPT,
436
+ messages: [{ role: "user", content: buildSummaryPrompt(plan) }],
437
+ abortSignal: compactionSignal,
438
+ temperature: 0,
439
+ // 摘要单轮生成:显式放宽 maxOutputTokens,避免 AI SDK 对未知模型的
440
+ // 兼容模式默认 4096 上限导致摘要生成不完(那是旧版多轮压缩的根因);
441
+ // 同时锁低 effort(OpenAI reasoning_effort=none / Anthropic
442
+ // output_config.effort=low),避免继承主对话的高 effort 拖慢"压缩上下文中"阶段。
443
+ maxOutputTokens: MAX_COMPACTION_OUTPUT_TOKENS,
444
+ providerOptions: this.provider === "openai"
445
+ ? { deepseek: { reasoningEffort: "none" } }
446
+ : { anthropic: { effort: "low" } },
447
+ });
448
+ if (!result.text.trim()) {
449
+ throw new Error("Context compaction returned an empty summary");
443
450
  }
444
- return compactedMessages;
451
+ this.context.applyCompaction(result.text, plan);
452
+ // 单轮压缩:不再反复迭代重试。若上下文仍超预算(如 recent 消息本身超大),
453
+ // 留给下一次对话前再次压缩,避免阻塞当前回复生成(业界同步压缩的标准取舍)。
454
+ return plan.oldMessages.length;
445
455
  }
446
456
  catch (error) {
447
457
  if (timeoutController.signal.aborted && !signal?.aborted) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepccc",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "description": "A lightweight coding agent with OpenAI-compatible and Anthropic Messages API support.",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [