Exec mode: auto-save session metadata via self_metadata tool before exit

Resolved 💬 0 comments Opened Sep 9, 2025 by buihongduc132 Closed Sep 9, 2025

Problem
Non-interactive exec mode (aka codex e / codex exec) finishes after a single task with no built-in way for the agent to persist a discoverable “name” and metadata that helps users find and resume that session later. Today, naming requires a follow-up codex save <name> and metadata is implicit in the rollout file path/contents.

Proposal
Introduce a built-in tool exposed to the model in exec sessions to persist session metadata and a friendly name, and invoke it automatically just before exit.

High-level design

  • New built-in tool: self_metadata.save
  • Purpose: persist a lightweight record that maps a friendly name and rich metadata to the underlying rollout file so users can discover and resume sessions later.
  • Reusable: implemented in core so it can be reused outside exec (e.g., TUI, MCP server) when desired.
  • Annotations: no-approval, safe, idempotent; visible to the model as a normal tool.
  • Input shape (strings unless noted):
  • name (optional): user- or model-provided session label
  • current_branch
  • datetime (ISO 8601, UTC)
  • working_dir (absolute)
  • repo (remote URL if known, else repo root path)
  • commit (full SHA)
  • worktree (path or null)
  • summarize (short summary by the model)
  • Exec-mode behavior:

1) On session start, make self_metadata.save available to the model (Responses tool list and Chat Completions mapping).
2) On TaskComplete/Shutdown (just before exit), enqueue a final turn that instructs the model to call self_metadata.save:

  • Pre-populate all fields except summarize from host info (git, cwd, time).
  • Ask the model to fill summarize only. Use the existing compact prompt to keep it concise and stable.
  • If the model doesn’t call the tool within a small budget, fallback to generating the summary via a programmatic compact step and then call the tool ourselves (so exit stays deterministic).

3) Tool implementation persists to ~/.codex/saves.json by inserting an entry in by_name and by_id that points to the current rollout file path. Optionally also write a small sidecar (e.g., ~/.codex/saves/<id>.json) containing the metadata for search/filtering later.

  • Configuration (opt-in/opt-out):
  • exec.auto_save_metadata (bool, default: true)
  • exec.save_name_pattern (string template for default name if none provided; can include tokens like {branch}, {date}, {cwd_basename})
  • TUI parity (future):
  • Expose the same tool so the assistant can save metadata mid-session or on /save.

Why this helps

  • Makes exec discoverable: users can list and resume sessions without remembering a manual name.
  • Standardizes metadata capture for portability (branch/commit/cwd/worktree) and allows richer UX (filter by branch/repo/time).
  • Keeps LLM use minimal and deterministic: the model only produces the summarize string; everything else is host-filled.

Implementation notes

  • The saving path can reuse the existing codex save logic (saves.json) to avoid duplicating index semantics.
  • For Responses, add the tool to the tools array; for Chat Completions, map to a function tool and capture arguments as JSON.
  • Ensure the final “save” turn does not produce noisy output in exec; suppress streaming and only print a short confirmation.
  • Consider rate-limiting/throttling to avoid extra tokens when exec runs very short tasks.

Acceptance criteria

  • In codex exec, sessions auto-save a name + metadata before exit by default.
  • saves.json contains a new entry for the session, with a friendly name and id mapping.
  • The summary is either model-provided (tool call) or fallback-generated via compact.
  • Feature can be disabled via config.

Related

  • Current manual save command: codex save <name>
  • Rollout format: first JSONL line contains session id; this feature ties that id to a name + metadata.

View original on GitHub ↗