Lesson 18 of 19 · 9 min read
Resume a session without pretending it finished
Persist the append-only session log, understand the flush boundary, and resume a stopped agent with explicit recovery semantics.

Course syllabus · lesson 18 of 19
In this lesson
Keeping a session visible in a Web UI is not the same as making it recoverable. DeepSeek Harness's session-persistence package stores the append-only event log through a backend-independent service. The shipped JSONL backend writes one compressed .jsonl.zstd log per session.
Persistence is not a second conversation database. The session event log remains the source of truth, and the model message history is derived from it. A completed flush is the durability barrier. A background write that has not crossed that barrier is not evidence you can rely on after a crash. Compare this boundary with whatever durability guarantees your usual agent workflow provides.
Resume through the agent factory
The public API is on ctx.agents. A host that has mounted a persistence backend can resume a stored session like this:
import type { Context } from '@deepseek-ai/cordis'
import type { SessionId } from '@deepseek-ai/dsh-session'
declare const ctx: Context
declare const resumeSessionId: SessionId
const handle = await ctx.agents.resume({
resumeSessionId,
agentOptions: {
provider: 'deepseek',
model: 'deepseek-chat',
},
})
// Use the returned AgentHandle through the host's agent interface.
// The holder owns teardown, so dispose it on every exit path.
await handle.dispose()
The provider and model pair must resolve before the resumed agent makes a request. resume rejects when no session-persistence backend is configured. A plugin that creates an in-memory session by hand does not get durable storage automatically.
Run the recovery exercise
Use a disposable checkout and a mounted persistence backend. Ask the agent to inspect a file and begin a second operation. Stop the process while the second operation is active. Then restart the same composition and resume the recorded session.
Keep this prompt bounded:
Read the basket calculation and its tests.
Summarize one missing boundary case, then wait before changing anything.
Report the session id and the last completed observation.
After resuming, ask:
State which turn was interrupted, repeat the last durable observation, and propose the next read-only check.
Do not say the interrupted operation completed.
The persistence package repairs a stored mid-turn by appending synthetic closers for the interrupted tool or step and the turn. The new agent continues from the repaired history. There is no partial-turn continuation that quietly picks up an unacknowledged model response.
Model the crash windows
Session persistence has a useful set of boundaries to test. A process can stop before a tool request is written, after the request is written but before the result, after the result is written but before the next model turn, or after a filesystem side effect with no corresponding session event. Treat these as different states in your recovery worksheet.
For each boundary, record the expected resume behavior:
| Last durable fact | Safe resume action | | --- | --- | | No request recorded | Reissue a read-only inspection if the user still wants it. | | Request recorded, result absent | Inspect the target and runtime before retrying. | | Result recorded, next turn absent | Resume from the result and recheck the acceptance state. | | Mutating side effect uncertain | Freeze the task, inspect the workspace, then decide. |
The table is a policy for the operator, not a promise that every backend exposes the same flush timing. Test it with a disposable session and local failures. Put a sequence number or event id on checkpoints so a replay can reject an older checkpoint. Make writes idempotent where possible, and require a fresh read before repeating an operation that could have changed state.
When you resume, ask the agent to separate remembered session context from current filesystem evidence. Compare its answer with the reopened files and the last durable event. A correct recovery may say “the session remembers a requested edit, but the file state is unknown.” That is a useful result. A confident “the edit was applied” without a current read is not.
Respect the storage boundaries
Only the agent-loop publication path acquires the active write handle for a live session. ctx.sessions.create() alone does not persist anything. Within one backend instance, one writer owns a session. A read handle can inspect it without taking write ownership.
The package does not provide retention or deletion. Plan storage cleanup outside the harness, and treat session logs as potentially sensitive. Review the backend path, permissions, provider credentials, and workspace before enabling persistence on a real repository.
The final advanced lesson uses durable discipline while coordinating many independent reviews.
Before you move on
Try it in your workspace
Simulate a stopped run at each durability boundary. Distinguish a missing result from a failed write, inspect the current filesystem, and document the safe resume decision.
Keep a short note of what you tried, what passed, and what you still need to check.
0 of 3 checked.
Saved in this browser when storage is available. Uncheck any item to revisit it. This is your own record, not an assessment.