Files
deepseek-harness/packages/session-query/session-log-export/README.md
T
Tianyi Cui bf29247fad fix(session): namespace historical V3 extensions with plugin prefixes
V3 permits external event, source and content identities and additional
request-tool fields. Copying those values into V4 can give an old plugin
named tool a core source identity, turn old tool-addition content into a
registry instruction, or activate formerly ignored deferLoading and delivery
metadata. Rejecting such collisions would instead refuse valid source logs.

Keep historical extensions in the existing extensible JSON representation.
Prefix unknown content and ignorable event tags with plugin:, preserving
all other content fields and opaque event payloads. Prefix external source
identities with plugin:plugin: or plugin:source: so wrapper and direct kinds
cannot collide even when original names already contain a category prefix.
Known first-party mappings remain explicit and unchanged.

Prefix extra request-tool field names and block-start field names with
plugin:, retaining exact values and existing-prefix doubling. Core schema
parameters, arguments, replay state and nested plugin data are not traversed.
Keep future-generation delivery records inactive after header promotion.
Pin the V3 event vocabulary independently of the current writer and provide
an offline verifier against an explicitly selected historical source commit.

Attachment authorization and export inspect declared event content only.
Team checkpoints preserve all own keys of unknown JSON blocks while still
rejecting malformed known content and retired core tool-result blocks.
Exercise physical read/write/reopen, prefix injectivity, own __proto__ keys,
provider opacity and retained source-identity snapshots.

No generic extension block, metadata wrapper or new schema-tooling type is
introduced. V4 type declarations, persistence schema, checkpoint and frozen
V0-V3 codecs remain unchanged. Canonical tool-result lifting and incomplete
child-catalog policy remain separate concerns.

Adapted from the extension-preservation work in 7ba7e174dd1 by Tianyi Cui.
Co-authored-by: Tianyi Cui <53024+tianyicui@users.noreply.github.com>
2026-09-19 15:43:09 +08:00

8.3 KiB

description, kind
description kind
Web Session-log ZIP export: Host streaming, the authenticated download route, the Session Header action, and the /export command. package-reference

@deepseek-ai/dsh-session-log-export

English | 中文

Summary

dsh-session-log-export lets the Web interface download a session's full history: a Download session log menu item under the Session Header's more-actions button and an /export slash command both hand the session tree — the session, its sub-sessions, and attachments — to the browser as a ZIP download. The package owns the Host archive stream, its authenticated Fetch route, and the browser controls and feedback. The browser chooses the download destination. Setup and usage come first; implementation details follow.

Table of Contents


Use this package

Use this package when the Web bundle should let users export a session log. It requires Connection, the command registry, Session query and persistence, and attachments. Mount the plugin, then choose Download session log from the Session Header's more-actions menu or type /export; the browser downloads dsh-session-<id>.zip.

When ui-message-feedback is mounted, the same menu also offers Feedback, which opens its existing Session feedback dialog. Opening or dismissing that form does not export the Session or submit feedback. The feedback row follows the feedback plugin's availability; export remains available independently.

When to choose it

Choose it for a Web deployment that needs user-facing session export with a visible download dialog. Avoid it when a programmatic or Host-side export is needed: this package produces a browser download, not a Host path write. The logs are serialized from persistence read handles, so any mounted backend is supported.

Composition

- id: session-log-download
  name: '@deepseek-ai/dsh-session-log-export'

The Web bundle mounts the package with Connection, dsh-commands, dsh-client-ui-commands, and dsh-client-ui-conversation.

Configuration

Field Default Meaning
compressionLevel 6 DEFLATE level from 0 through 9 for each ZIP entry.

Command contract

Input Result
/export Records a human-command lifecycle; the submitting browser downloads the document-relative api/session.export?sessionId=<id>&includeDescendants=true (Host route /api/session.export)
/export <path> An error; browser downloads choose their destination through the browser's ordinary download behavior

What to expect

The dialog reports three phases: preparing, download started, or failed. Closing the dialog does not cancel an in-flight download, and the dialog does not reopen when that operation later settles. One session admits one active download at a time; repeated gestures share that operation. The export includes the live session's newest events: the host endpoint flushes a live root session before reading, so a slash-triggered ZIP includes the command/run and command/done pair that started the download; cold persisted sessions need no flush. Each logical log uses the current generation's canonical filename inside the archive (session.jsonl for v0, otherwise session.vN.jsonl), including beneath each sub-session directory. Images use media/<attachmentId>.<ext>, and generic files use files/<digest-prefix>/<digest>/<name>. Generic-file bytes are read and compressed as bounded chunks, so exporting a large upload does not buffer it in full.

Attachment collection reads only declared content fields of recognized Session events and completed assistant stream blocks. Unknown event payloads, unrelated fields, and extension data remain opaque; the exported log retains them unchanged.

Failures

The dialog shows a preparation error when the preflight fails before ZIP streaming starts — for example an unreachable or misconfigured host endpoint. A descendant or attachment read failure after the browser accepts the GET is reported by the browser download manager, not by the dialog.


Understand the implementation

Implementation internals — click to expand

This section explains how the package wires the export control and points at the code that realizes it; the observable behavior is fully covered in Use this package.

Design split

The package has two halves. The Host half (src/index.ts) registers the /export command and contributes the exact GET/HEAD /api/session.export Fetch route to Connection; src/archive.ts builds the bounded ZIP stream. The browser half (src/client/index.ts) provides the shared download controller and UI, and observes command/executed so only the submitting browser starts a download.

Download flow

Both entry paths issue a HEAD preflight to the document-relative api/session.export?..., then hand the GET route to the browser download manager without buffering the ZIP in JavaScript. One controller owns one in-flight download per session, collapses concurrent gestures into that operation, and cancels the preflight on plugin disposal. Modal state lives in a snapshot store keyed by session, so the button and the command share one dialog per session.

The Host route is a feature-owned exact Fetch contribution. Connection applies its Host/Origin and browser-session checks and bridges the streaming Response; this package owns query validation, live-session flushes, handle-based log reads and attachment reads, ZIP generation, and HTTP status semantics.


Further Exploration

Read these pages when the package-level contract is not enough. They move from the Web control to the host endpoint and the surrounding command and session surfaces.


Model Experience

Human /export control

What the model sees

Nothing. /export stays on the human-command plane, and the ZIP download does not enter model history.

Token effect

Zero. The command creates no model turn.

KV Cache effect

None. The log-only command lifecycle and browser download do not change the derived request prefix.

Known Limitations and Deferred Work

These limits define when this package is a poor fit or needs special operational care. They are current package constraints, not a task backlog.

  • Browser download, not a Host-path writer — the browser chooses the local destination; no Host path or native folder action is returned.
  • Preflight reports only pre-stream failures — a descendant or attachment failure after the browser accepts the GET is reported by the browser download manager, not by the dialog.

Dev Note

Working context for maintainers — click to expand

This Dev Note is working context for maintainers: open design questions and directions that are not decided. It is explicitly non-authoritative — shipped behavior, limits, and accepted rationale live in the sections above, the package code, and the linked pages.

Future: export destinations beyond the browser

The download is deliberately browser-scoped; a Host-path or native folder export would need a new endpoint contract and a decision on where the ZIP lands.

Runtime invariant: No companion is published. Connection and the command registry own both registrations, while each export reads authoritative Session services.