mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
fix(compact): make config knobs explicit and flag two review smells
Address @tianyicui's minor-revision review on PR #110: - Make every BasicCompactConfig knob required except `auto` (defaults true): there is no data yet to justify default thresholds/budgets, so a consumer states each value explicitly. Drop the DEFAULTS export and the constructor's `= {}` default; example cordis.yml, the compaction e2e, the README, and every test construction site now pass a complete config (tests route through a `cfg()` helper). - Add a TODO on estimateContentTokens: char/4 is coarse; replace with a real tokenizer or post-response usage feedback in a follow-up. - Add a TODO on the agent/pre-step `fullSystemPrompt` param flagging it as a smell on a generic per-step seam (compaction is its sole consumer); a `//` line comment so it stays out of the generated catalog.
This commit is contained in:
@@ -39,7 +39,7 @@ import type { BasicCompactConfig, ResolvedConfig } from './types.ts'
|
||||
import { resolveConfig } from './types.ts'
|
||||
|
||||
export type { BasicCompactConfig, ResolvedConfig } from './types.ts'
|
||||
export { DEFAULTS, resolveConfig } from './types.ts'
|
||||
export { resolveConfig } from './types.ts'
|
||||
|
||||
/** Per-block structural overhead for JSON framing / type tag. */
|
||||
const BLOCK_OVERHEAD = 4
|
||||
@@ -155,10 +155,10 @@ function finishError(finish: FinishReason): Error | undefined {
|
||||
export class BasicCompactService extends CompactService {
|
||||
static inject = ['llm']
|
||||
|
||||
/** Resolved configuration (defaults applied). */
|
||||
/** Resolved configuration (`auto` defaulted). */
|
||||
readonly config: ResolvedConfig
|
||||
|
||||
constructor(ctx: Context, config: BasicCompactConfig = {}) {
|
||||
constructor(ctx: Context, config: BasicCompactConfig) {
|
||||
super(ctx)
|
||||
this.config = resolveConfig(config)
|
||||
|
||||
@@ -207,6 +207,9 @@ export class BasicCompactService extends CompactService {
|
||||
|
||||
// ---- Token estimation (overridable hooks) ----
|
||||
|
||||
// TODO: char/4 is a coarse heuristic. Replace with an exact count — a real
|
||||
// tokenizer, or the provider's post-response `usage` (input tokens) fed back
|
||||
// as a correction — so threshold decisions match the model's actual budget.
|
||||
/**
|
||||
* Estimate the token count of content blocks — char/4 with per-block
|
||||
* overhead. Override in a subclass to plug in a real tokenizer.
|
||||
|
||||
@@ -9,40 +9,34 @@
|
||||
* @module @deepseek-ai/dsh-compact-basic/types
|
||||
*/
|
||||
|
||||
/** Backend configuration — all optional with sensible defaults. */
|
||||
/**
|
||||
* Backend configuration. Every knob is REQUIRED except `auto`: there is no
|
||||
* concrete data yet to justify default thresholds/budgets, so a consumer must
|
||||
* state each value explicitly rather than inherit a guessed default. `auto`
|
||||
* alone defaults to `true` (auto-compaction is the intended posture).
|
||||
*/
|
||||
export interface BasicCompactConfig {
|
||||
/** Context window size in tokens (default 128000). */
|
||||
contextWindow?: number
|
||||
/** Compact when estimated token usage exceeds this fraction of context window (default 0.8). */
|
||||
thresholdRatio?: number
|
||||
/** Number of tokens of recent context to retain during compaction (default 20480). */
|
||||
retainTokens?: number
|
||||
/** Model to use for summarization (default '' — uses the agent's model). */
|
||||
summarizationModel?: string
|
||||
/** Provider generation cap for the summarization call (default 8192). */
|
||||
maxTokens?: number
|
||||
/** Extra compaction attempts when the first compacted surface is still over threshold (default 1). */
|
||||
compactionRetries?: number
|
||||
/** Context window size in tokens. */
|
||||
contextWindow: number
|
||||
/** Compact when estimated token usage exceeds this fraction of context window. */
|
||||
thresholdRatio: number
|
||||
/** Number of tokens of recent context to retain during compaction. */
|
||||
retainTokens: number
|
||||
/** Model to use for summarization (`''` — uses the agent's model). */
|
||||
summarizationModel: string
|
||||
/** Provider generation cap for the summarization call. */
|
||||
maxTokens: number
|
||||
/** Extra compaction attempts when the first compacted surface is still over threshold. */
|
||||
compactionRetries: number
|
||||
/** Enable automatic compaction on the `agent/pre-step` seam (default true). */
|
||||
auto?: boolean
|
||||
}
|
||||
|
||||
/** Resolved config with all defaults applied. */
|
||||
/** Resolved config with `auto` defaulted. */
|
||||
export type ResolvedConfig = Required<BasicCompactConfig>
|
||||
|
||||
/** Default configuration values. */
|
||||
export const DEFAULTS: ResolvedConfig = {
|
||||
contextWindow: 128000,
|
||||
thresholdRatio: 0.8,
|
||||
retainTokens: 20480,
|
||||
summarizationModel: '',
|
||||
maxTokens: 8192,
|
||||
compactionRetries: 1,
|
||||
auto: true,
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply defaults to a partial config and reject nonsensical numeric knobs.
|
||||
* Default `auto` when unset and reject nonsensical numeric knobs.
|
||||
*
|
||||
* Convergence is not a static config invariant: provider generation caps can be
|
||||
* spent on hidden or surfaced reasoning tokens, and the model may emit a summary
|
||||
@@ -52,7 +46,7 @@ export const DEFAULTS: ResolvedConfig = {
|
||||
* throwing if the surface still exceeds the threshold.
|
||||
*/
|
||||
export function resolveConfig(config: BasicCompactConfig): ResolvedConfig {
|
||||
const resolved = { ...DEFAULTS, ...config }
|
||||
const resolved: ResolvedConfig = { auto: true, ...config }
|
||||
|
||||
assertPositiveInteger('contextWindow', resolved.contextWindow)
|
||||
assertRatio('thresholdRatio', resolved.thresholdRatio)
|
||||
|
||||
Reference in New Issue
Block a user