/** * CompactorRole - Context compaction worker * Summarizes conversation history to free token space. * DD §8.4. * * @module packages/workers/src/roles/CompactorRole */ import { WorkerRuntime } from '../WorkerRuntime.js' export interface CompactorResult { status: 'compacted' | 'skipped' | 'blocked' summary_content: string tokens_freed: number compacted_layers: string[] } export class CompactorRole { private runtime: WorkerRuntime constructor(runtime: WorkerRuntime) { this.runtime = runtime } async run(compact_spec: { task_id: string; current_tokens: number; threshold: number }): Promise { const result: CompactorResult = { status: 'skipped', summary_content: '', tokens_freed: 0, compacted_layers: [] } try { this.runtime.emit('compaction.started', { task_id: compact_spec.task_id }) // Check if compaction is needed if (compact_spec.current_tokens < compact_spec.threshold) { result.status = 'skipped' result.summary_content = `Tokens (${compact_spec.current_tokens}) below threshold (${compact_spec.threshold}) — no compaction needed` return result } // Use LLM to generate summary of the conversation const tokens_to_free = compact_spec.current_tokens - Math.floor(compact_spec.threshold * 0.6) const compaction_messages = [ { role: 'system', content: 'Summarize the key facts, decisions, and code changes from the conversation history. Keep it concise but complete. Include file paths, function names, and architectural decisions.' }, { role: 'user', content: `Compaction requested: ${compact_spec.current_tokens} tokens in context, threshold is ${compact_spec.threshold}. Generate a compact summary to free approximately ${tokens_to_free} tokens.` } ] try { const summary = await this.runtime.call_llm({ messages: compaction_messages, max_tokens: 2048, temperature: 0.2 }) result.summary_content = summary.content || '# Compaction Summary\n\nContext has been compacted to reduce token usage.' result.tokens_freed = tokens_to_free result.compacted_layers = ['conversation', 'tool_output'] result.status = 'compacted' } catch { result.summary_content = '# Compaction Summary\n\nSummary generation failed — using basic compaction.' result.tokens_freed = compact_spec.current_tokens - Math.floor(compact_spec.current_tokens * 0.6) result.compacted_layers = ['conversation'] result.status = 'compacted' } this.runtime.checkpoint('compaction_completed', { task_id: compact_spec.task_id }) return result } catch (error) { result.status = 'blocked' result.summary_content = error instanceof Error ? error.message : String(error) return result } } }