Skip to content

Sub-agent resume and transcript persistence #966

@bug-ops

Description

@bug-ops

Part of #974

Background

Claude Code assigns each sub-agent invocation a unique ID and stores the full conversation transcript. A subsequent call can resume from an existing transcript, preserving tool results, intermediate reasoning, and multi-turn history. This is essential for long-running background agents that may be interrupted, and for audit/replay.

Current state in Zeph

SubAgentManager tracks status (running, completed, failed) per agent instance via a HashMap<AgentId, AgentHandle>. No transcript is persisted to disk. When an agent completes or the process exits, all context is lost.

Implementation

  1. Transcript model: define AgentTranscript { id: AgentId, name: String, started_at: DateTime<Utc>, messages: Vec<Message>, status: AgentStatus }. Serialize to JSON.

  2. Storage: persist transcripts under {data_dir}/zeph/agents/transcripts/{id}.json using async write after each turn. Use tokio::fs for non-blocking I/O.

  3. AgentId generation: use uuid::Uuid::new_v4() — already a workspace dep.

  4. Resume API: add SubAgentManager::resume(id: AgentId) -> Result<AgentHandle> that loads transcript and injects it as initial conversation history into the new LLM session.

  5. CLI flag: --resume <agent-id> for the agent run subcommand.

  6. Transcript listing: SubAgentManager::list_transcripts() -> Vec<TranscriptMeta> for TUI/CLI display.

  7. TTL cleanup: transcripts older than transcript_ttl_days (config, default 30) are deleted on startup.

Acceptance criteria

  • Each sub-agent run is assigned a stable AgentId (UUID v4).
  • Transcript is written to disk after each turn (not just at completion).
  • SubAgentManager::resume(id) successfully restores message history.
  • --resume <id> CLI flag works end-to-end.
  • Transcripts older than TTL are pruned at startup.
  • Unit tests: write transcript, read it back, verify message count.
  • cargo nextest run -p zeph-core passes.

Technical notes

  • Use serde_json for transcript serialization (already a dep).
  • data_dir resolution: dirs::data_dir() + "zeph", configurable via ZEPH_DATA_DIR env or data_dir config key.
  • Keep transcript writes non-blocking: spawn a tokio::task::spawn per write, do not await in hot path.
  • The Message type is already defined in zeph-llm; reference it from zeph-core via the existing dependency.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestfeatureNew functionalitymemoryPersistence and memory

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions