Files
oh-my-pi/docs/tools/checkpoint.md
T
can1357 64fcdc308f refactor(coding-agent)!: removed StringEnum helper and shortened tool schema descriptions
- Replaced all StringEnum(...) usages with z.enum([...]) across tools, examples, and tests.
- Removed StringEnum re-export from @oh-my-pi/pi-coding-agent public API.
- Condensed verbose tool parameter descriptions to minimal lowercase phrases.
- Renamed AuthCredentialStore to SqliteAuthCredentialStore at usage sites.
2026-05-16 19:26:32 +02:00

85 lines
5.0 KiB
Markdown

# checkpoint
> Mark the current top-level conversation state so later `rewind` can collapse exploratory context into a report.
## Source
- Entry: `packages/coding-agent/src/tools/checkpoint.ts`
- Model-facing prompt: `packages/coding-agent/src/prompts/tools/checkpoint.md`
- Key collaborators:
- `packages/coding-agent/src/session/agent-session.ts` — captures the active checkpoint after tool success.
- `packages/coding-agent/src/session/session-manager.ts` — persists the normal session entry stream; not the active checkpoint marker.
- `packages/coding-agent/src/tools/index.ts` — registers the tool and gates it behind `checkpoint.enabled`.
- `packages/coding-agent/src/config/settings-schema.ts` — defines the disabled-by-default feature flag.
## Inputs
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `goal` | `string` | Yes | Investigation goal. Required by the schema and echoed in the tool result. |
## Outputs
The tool returns a single text result plus structured details:
- text body:
- `Checkpoint created.`
- `Goal: <goal>`
- `Run your investigation, then call rewind with a concise report.`
- `details`:
- `goal: string`
- `startedAt: string` — ISO timestamp created inside `CheckpointTool.execute()`
No checkpoint ID, artifact URI, job handle, file path, or restore token is returned.
## Flow
1. `CheckpointTool.createIf()` in `packages/coding-agent/src/tools/checkpoint.ts` returns `null` for subagents by checking `session.taskDepth`; only top-level sessions can see the tool.
2. `CheckpointTool.execute()` rejects subagent calls again with `ToolError("Checkpoint not available in subagents.")`.
3. It rejects nested checkpoints with `ToolError("Checkpoint already active.")` when `session.getCheckpointState?.()` is already set.
4. It creates `startedAt = new Date().toISOString()` and returns a normal `toolResult()` payload. The tool itself does not persist anything.
5. On the later `tool_execution_end` event, `AgentSession` in `packages/coding-agent/src/session/agent-session.ts` detects successful `checkpoint` execution and captures three in-memory fields:
- `checkpointMessageCount` — current `agent.state.messages.length`, after the checkpoint tool result has already been appended
- `checkpointEntryId` — `sessionManager.getEntries().at(-1)?.id ?? null`, i.e. the last persisted session entry ID at checkpoint time
- `startedAt` — copied from tool details or regenerated
6. `AgentSession` stores that object in its private `#checkpointState` field and clears `#pendingRewindReport`.
## Side Effects
- Session state (transcript, memory, jobs, checkpoints, registries)
- Sets `AgentSession.#checkpointState` in memory.
- Records the checkpoint boundary as a message count plus a session entry ID.
- Enables the later yield guard: if a checkpoint is active and no rewind report is pending, `#enforceRewindBeforeYield()` injects a developer-role warning and schedules another turn.
- User-visible prompts / interactive UI
- The tool result tells the model to call `rewind` after the investigation.
- If the agent tries to `yield` first, `AgentSession` injects:
```text
<system-warning>
You are in an active checkpoint. You MUST call rewind with your investigation findings before yielding. Do NOT yield without completing the checkpoint.
</system-warning>
```
## Limits & Caps
- Availability is gated by `checkpoint.enabled`, default `false`, in `packages/coding-agent/src/config/settings-schema.ts`.
- The tool is registered as discoverable in `packages/coding-agent/src/tools/index.ts`.
- Only one active checkpoint is allowed per top-level session.
- Checkpoint state is not persisted as a dedicated session entry. If the process exits, a resumed session can reload the conversation history, but not the live `#checkpointState` guard.
- Session persistence still applies to the ordinary checkpoint tool call message. Global session persistence truncation is `MAX_PERSIST_CHARS = 500_000` in `packages/coding-agent/src/session/session-manager.ts`.
## Errors
- `ToolError("Checkpoint not available in subagents.")` — thrown for subagent sessions.
- `ToolError("Checkpoint already active.")` — thrown when a prior checkpoint has not been rewound or cleared.
- The tool body has no local `try/catch`; unexpected exceptions propagate.
## Notes
- Despite the summary string `Create a git-based checkpoint to save and restore session state`, the implementation does not call git and does not snapshot filesystem state.
- Captured state is conversation/session metadata only:
- in-memory message count
- session entry ID in the session tree
- timestamp
- Not captured:
- working tree contents
- staged changes
- artifacts
- blob-store contents
- SQLite history rows from `packages/coding-agent/src/session/history-storage.ts`
- auth or agent records from `packages/coding-agent/src/session/agent-storage.ts`
- If the turn ends with `stopReason === "aborted"` while a checkpoint is active, `AgentSession` clears `#checkpointState` and `#pendingRewindReport` instead of preserving a half-finished checkpoint.