By default, qoderclicn keeps session history on the machine where it runs. In a multi-instance, container, or serverless deployment, the next request may reach a different machine that cannot read the earlier session.
External session storage keeps a mirror of each session in storage that your application controls. The mirror is an additional copy: qoderclicn still writes the session locally, and any host can continue a session later by using its session ID.
Use external storage when:
Two properties follow from this design:
Every host must use the same
For every query that should mirror or restore a session, pass the store in options (
Session management functions operate on the store instead of local files. In TypeScript, pass the store via the
Listing sessions requires the store to implement the session-listing method; listing subagents requires
The SDK ships no production-ready storage implementation; applications implement the
A
Failure handling. External write failures never interrupt the ongoing conversation. After the final retry fails, the SDK emits a mirror-error message (
- requests can move between service instances
- local disks are temporary or unreliable
- your application must control access, encryption, backups, or retention
How it works
- Writes are best-effort. The SDK mirrors entries in the background. A failed write is reported but never stops the running conversation; see Operations.
- Entries are opaque. Your store persists and returns SDK-defined transcript entries as-is. Your application does not need to understand qoderclicn's local file format.
Quick start
InMemorySessionStore keeps data in the current process only. Use it to validate the wiring — that queries save to and resume from a store — before you connect a shared backend. It cannot demonstrate cross-host resume, because the data is gone when the process exits; for that, implement a real store. See Implementing a store.
cwd, so the SDK identifies requests as belonging to the same project.
Using a store in your application
For every query that should mirror or restore a session, pass the store in options (sessionStore in TypeScript, session_store in Python), then choose how to identify the session:
- Known session ID — pass
resume. - The project's most recent session — pass
continue: true(TypeScript) /continue_conversation=True(Python). This requires the store to implement the session-listing method.
Managing stored sessions
Session management functions operate on the store instead of local files. In TypeScript, pass the store via the sessionStore option; in Python, each function takes the store as its first argument:
listSubkeys / list_subkeys; deleting sessions requires delete. If listSubkeys / list_subkeys is implemented, the subagent-message getters use it too.
To copy an existing local session into the store—for example when migrating a machine that previously ran without external storage—use the import function; note the session ID comes first and the store second:
Implementing a store
The SDK ships no production-ready storage implementation; applications implement the SessionStore interface (TypeScript) / protocol (Python) against the shared storage of their choice. Runnable reference implementations for Redis and PostgreSQL show the mechanics: see the TypeScript examples or Python examples. They are starting points, not production-ready implementations.
SessionKey identifies one transcript. The main session has no subpath; each subagent transcript reuses the same project key and session ID with a different subpath. Treat keys and entries as opaque—store and return them verbatim, and do not parse message contents.
The two required methods provide save and resume. Each optional method unlocks a feature:
| Method | Feature enabled |
|---|---|
append, load | Mirror a session and resume it by ID — required |
listSessions / list_sessions | Resume the most recent session; list stored sessions |
delete | Delete a session from the store |
listSubkeys / list_subkeys | Fully restore and inspect subagent transcripts |
Implementation checklist
- Preserve append order per key, and return the complete history from
load. Replay depends on order. - Isolate keys. Never return one key's entries under another.
- Make
appendidempotent. The SDK may retry a failed write with the same entries, so a retry must not duplicate history. - When listing sessions,
mtimereturns Unix-millisecond timestamps, and only main sessions—those without asubpath—are returned. - Cascade deletes. Deleting a main session must also delete its subagent transcripts.
listSubkeys/list_subkeysreturns relative identifiers only—never absolute paths, and never paths containing.or... These become storage keys, and traversal segments would let transcripts escape their namespace.- Serialize concurrent writers for the same session in the storage layer if more than one process can write it.
SessionStore conformance tests in the SDK repo; Python provides run_session_store_conformance in qodercn_agent_sdk.testing), and add concurrency and retry tests for your specific backend. Connection management, permissions, encryption, backups, migration, and retention remain the application's responsibility.
Operations
Failure handling. External write failures never interrupt the ongoing conversation. After the final retry fails, the SDK emits a mirror-error message (system/mirror_error in TypeScript, SDKMirrorErrorMessage in Python). Monitor it if mirror integrity matters—the conversation may still complete even when a write fails.
Tuning.
- External reads wait up to 60 seconds by default. Tune with
loadTimeoutMs/load_timeout_ms. - The flush strategy (
sessionStoreFlush/session_store_flush) defaults tobatched. Settingeagermirrors entries sooner at the cost of more storage requests.
- If an explicitly resumed session is missing from the store, the SDK can still fall back to a local session with the same ID.
- The store cannot be combined with file checkpointing or custom transports (in TypeScript it also cannot be combined with
persistSession: false). In TypeScript the store is supported on the built-in Process and Worker transports; Python requires the built-in subprocess transport. - A store holds session history only. It does not hold authentication state, application configuration, file checkpoints, or retention policy.