Commit Graph

18 Commits

  • refactor(coding-agent): fix compaction for branched sessions, consolidate hook context types
    Compaction API:
    - prepareCompaction() now takes (pathEntries, settings) only
    - CompactionPreparation restructured: removed cutPoint/messagesToKeep/boundaryStart, added turnPrefixMessages/isSplitTurn/previousSummary/fileOps/settings
    - compact() now takes (preparation, model, apiKey, customInstructions?, signal?)
    - Fixed token overflow by using getPath() instead of getEntries()
    
    Hook types:
    - HookEventContext renamed to HookContext
    - HookCommandContext removed, RegisteredCommand.handler takes (args, ctx)
    - HookContext now includes model field
    - SessionBeforeCompactEvent: removed previousCompactions/model, added branchEntries
    - SessionBeforeTreeEvent: removed model (use ctx.model)
    - HookRunner.initialize() added for modes to set up callbacks
  • Refactor: move compaction code to src/core/compaction/
    - Move compaction.ts to src/core/compaction/compaction.ts
    - Extract branch summarization to src/core/compaction/branch-summarization.ts
    - Add index.ts to re-export all compaction utilities
    - Update all imports across the codebase
  • refactor(hooks): split session events into individual typed events
    Major changes:
    - Replace monolithic SessionEvent with reason discriminator with individual
      event types: session_start, session_before_switch, session_switch,
      session_before_new, session_new, session_before_branch, session_branch,
      session_before_compact, session_compact, session_shutdown
    - Each event has dedicated result type (SessionBeforeSwitchResult, etc.)
    - HookHandler type now allows bare return statements (void in return type)
    - HookAPI.on() has proper overloads for each event with correct typing
    
    Additional fixes:
    - AgentSession now always subscribes to agent in constructor (was only
      subscribing when external subscribe() called, breaking internal handlers)
    - Standardize on undefined over null throughout codebase
    - HookUIContext methods return undefined instead of null
    - SessionManager methods return undefined instead of null
    - Simplify hook exports to 'export type * from types.js'
    - Add detailed JSDoc for skipConversationRestore vs cancel
    - Fix createBranchedSession to rebuild index in persist mode
    - newSession() now returns the session file path
    
    Updated all example hooks, tests, and emission sites to use new event types.
  • Use exhaustive switch on message.role throughout coding-agent
    - addMessageToChat: exhaustive switch for all AgentMessage roles
    - renderSessionContext: delegates to addMessageToChat, special handling for assistant tool calls and tool results
    - export-html formatMessage: exhaustive switch for all AgentMessage roles
    - Removed isHookMessage, isBashExecutionMessage type guards in favor of role checks
    - Fixed imports and removed unused getLatestCompactionEntry
  • WIP: Refactor agent package - not compiling
    - Renamed AppMessage to AgentMessage throughout
    - New agent-loop.ts with AgentLoopContext, AgentLoopConfig
    - Removed transport abstraction, Agent now takes streamFn directly
    - Extracted streamProxy to proxy.ts utility
    - Removed agent-loop from pi-ai (now in agent package)
    - Updated consumers (coding-agent, mom) for AgentMessage rename
    - Tests updated but some consumers still need migration
    
    Known issues:
    - AgentTool, AgentToolResult not exported from pi-ai
    - Attachment not exported from pi-agent-core
    - ProviderTransport removed but still referenced
    - messageTransformer -> convertToLlm migration incomplete
    - CustomMessages declaration merging not working properly
  • Refactor session manager: migration chain, validation, tests
    - Add migrateV1ToV2/migrateToCurrentVersion for extensible migrations
    - createSummaryMessage now takes timestamp from entry
    - loadEntriesFromFile validates session header
    - findMostRecentSession only returns valid session files (reads first 512 bytes)
    - Remove ConversationEntry alias
    - Fix mom context.ts TreeNode type
    
    Tests:
    - migration.test.ts: v1 migration, idempotency
    - build-context.test.ts: 14 tests covering trivial, compaction, branches
    - file-operations.test.ts: loadEntriesFromFile, findMostRecentSession
  • Fix SessionEntry type to exclude SessionHeader
    - SessionEntry now only contains conversation entries (messages, compaction, etc.)
    - SessionHeader is separate, not part of SessionEntry
    - FileEntry = SessionHeader | SessionEntry (for file storage)
    - getEntries() filters out header, returns SessionEntry[]
    - Added getHeader() for accessing session metadata
    - Updated compaction and tests to not expect header in entries
    - Updated mom package to use FileEntry for internal storage
  • Session tree structure with id/parentId linking
    - Add TreeNode base type with id, parentId, timestamp
    - Add *Content types for clean input/output separation
    - Entry types are now TreeNode & *Content intersections
    - SessionManager assigns id/parentId on save, tracks leafId
    - Add migrateSessionEntries() for v1 to v2 conversion
    - Migration runs on load, rewrites file
    - buildSessionContext() uses tree traversal from leaf
    - Compaction returns CompactionResult (content only)
    - Hooks return compaction content, not full entries
    - Add firstKeptEntryId to before_compact hook event
    - Update mom package for tree fields
    - Better error messages for compaction failures
  • Fix session-manager simplification issues
    - Remove unused inspector import from session-manager.ts
    - Remove dead code in _persist()
    - Update tests for simplified SessionHeader
    - Update mom context.ts: remove unused AgentState import, fix startSession(), rename isEnabled to isPersisted
  • feat(coding-agent): implement new compaction system with overflow recovery
    Phase 1: Updated compaction.ts
    - findCutPoint now returns CutPointResult with isSplitTurn and turnStartIndex
    - Can cut at user, assistant, or bashExecution messages (never tool results)
    - Added turnPrefixSummary support for split turns (parallel summarization)
    - estimateTokens helper for context size estimation
    
    Phase 2: Updated session-manager.ts
    - CompactionEntry now has optional turnPrefixSummary field
    - loadSessionFromEntries injects both summaries when turn was split
    
    Phase 3: Updated agent-session.ts
    - Overflow detection via isContextOverflow after agent_end
    - Proactive compaction check on turn_end before next LLM call
    - _abortingForCompaction flag to skip saving aborted messages
    - Auto-retry after overflow recovery or proactive compaction
    - New event fields: reason (overflow/threshold), willRetry
    
    Phase 4: Updated interactive-mode.ts
    - Shows reason in compaction status (Context overflow detected...)
    - Shows retry status after compaction
    
    Tests updated for new CutPointResult return type.
  • Add bash mode for executing shell commands
    - Add ! prefix in TUI editor to execute shell commands directly
    - Output streams in real-time and is added to LLM context
    - Supports multiline commands, cancellation (Escape), truncation
    - Preview mode shows last 20 lines, Ctrl+O expands full output
    - Commands persist in session history as bashExecution messages
    - Add bash command to RPC mode via {type:'bash',command:'...'}
    - Add RPC tests for bash command execution and context inclusion
    - Update docs: rpc.md, session.md, README.md, CHANGELOG.md
    
    Closes #112
    
    Co-authored-by: Markus Ylisiurunen <markus.ylisiurunen@gmail.com>
  • Add totalTokens field to Usage type
    - Added totalTokens field to Usage interface in pi-ai
    - Anthropic: computed as input + output + cacheRead + cacheWrite
    - OpenAI/Google: uses native total_tokens/totalTokenCount
    - Fixed openai-completions to compute totalTokens when reasoning tokens present
    - Updated calculateContextTokens() to use totalTokens field
    - Added comprehensive test covering 13 providers
    
    fixes #130
  • WIP: Context compaction core logic (#92)
    - Add CompactionEntry type with firstKeptEntryIndex
    - Add loadSessionFromEntries() for compaction-aware loading
    - Add compact() function that returns CompactionEntry
    - Add token calculation and cut point detection
    - Add tests with real session fixture and LLM integration
    
    Still TODO: settings, /compact and /autocompact commands, auto-trigger in TUI, /branch rework