MMSP-RFC-0010 Trace Recording
- Feature Name:
trace_recording - Start Date: 2026-10-24
- RFC PR: #301
- Kind: spec
Abstract
A trace is the record MMSP writes of a conversation when a request's UniConfig carries a trace_id: the messages sent, the assistant message that answered them and the config, written as two files under the cache directory before the stop event is yielded. This document specifies when a trace is saved, which trace ids are accepted, what a trace contains, the files and their format, and how the tracer's viewer reads them.
1. Introduction
The owner asked for this specification in these words: 写一下 trace 的逻辑. A caller that can read every turn as it happened finds a wrong tool argument or a runaway thought in seconds rather than reconstructing it from logs, and a harness that reviews its own traces can change its prompts, tools or code and run again. The trace is one record in one format for every model, so it is specified with the protocol rather than left to each client.
#17 added trace_id and the tracer, which saved the history after a stateful turn; #34 and #38 brought the writer and the viewer to TypeScript; #96 added created_at and the viewer's rounds; #223 moved the save into streaming_response, before the stop is yielded, so that a caller who stops reading at the stop still finds the trace. The two writers differed in how they named the files, in the timestamp, and in where a trace id could reach; #300 made them one and has streaming_response refuse an id outside the cache directory.
2. Conventions and Terminology
The key words MUST, MUST NOT, SHOULD, SHOULD NOT and MAY in this document are to be interpreted as described in BCP 14 (RFC 2119, RFC 8174) when, and only when, they appear in all capitals.
- Trace id: the
trace_idstring of a request'sUniConfig, a path relative to the cache directory in which/separates directories. - Cache directory: the directory the environment variable
MMSP_CACHE_DIRnames, orcachewithout it, relative to the working directory, read each timestreaming_responsehandles a trace id. - Tracer: the
Tracerclass ofmmsp.integration.tracer/integration/tracer, which writes the trace files and serves the viewer.
3. When a Trace Is Saved
streaming_response/streamingResponseMUST save the trace when the config carries atrace_id, after the stream's items are closed and itsstopis built and immediately before thestopis yielded, so the trace is on disk when the caller sees thestop. It MUST NOT save it at any other point.- A
streaming_responsethat raises before it yields itsstop, whether with a provider's error,IncompleteStreamError,EmptyResponseError,StreamProtocolErroror the abort error (MMSP-RFC-0008 §3), saves no trace, and neither does one whose generator is closed before itsstop. - A stateful call saves through
streaming_response, so its trace is the whole conversation so far. - Through the
mmspclient thetrace_idtravels in the config: the server's upstream client saves the trace under the server's cache directory, and themmspclient MUST NOT save one. moonshot-officialalso sends the trace id asprompt_cache_keyon the Kimi K2 generation. No other provider client sends it to its provider.
4. Trace Ids
- A trace id names files under the cache directory; a
/in it makes subdirectories. streaming_responseMUST reject a trace id whose files would resolve outside the cache directory, such as an absolute path, an id whose..segments leave the directory, or an id that names the directory itself (.,agent/..), before the request goes out. It raisesUnsupportedParameterErrornamingtrace_id(MMSP-RFC-0007 §3.1), whose message reads<client> does not support trace_id '<id>': it must be a relative path that stays inside the cache directory.An id whose files resolve inside the cache directory is normalized aspath.resolvenormalizes a path, soagent/../keptwriteskept.json; an emptytrace_idsaves no trace.- Through the
mmspclient the server's upstream client checks the id against the server's cache directory, and the caller gets anUpstreamErrorwhoseerror_type(errorType) isUnsupportedParameterError(MMSP-RFC-0007 §4).
5. What a Trace Contains
- The history: the request's messages, with legacy item types converted and
created_atstamped (MMSP-RFC-0004 §6.3), followed by the assistant message built from the stream, with its complete items, itsusage_metadataandfinish_reason, and thecreated_atof thestopevent. - The config as given, with
modeladded, the model id of the client that saved it;trace_idstays in it. - The time of the save.
- The assistant message MUST NOT carry
fidelity.item_id, whichStreamItemsstrips before an item goes out (MMSP-RFC-0002 §5). A trace holds no delta and no turn that did not complete (§3). - A client's key, base URL and headers are constructor arguments, not
UniConfigkeys, so they never reach a trace. A caller SHOULD NOT put a secret into the config, because the trace keeps the config.
6. Files and Format
- A save writes
<trace_id>.jsonand<trace_id>.txtunder the cache directory, each suffix appended to the normalized id, sorun.v2writesrun.v2.jsonandrun.v2.txt. Missing directories are created. Each save MUST rewrite both files whole: a later save under the same id replaces the earlier one, so one trace id holds one conversation at its latest state. <trace_id>.jsonis{"history": [...], "config": {...}, "timestamp": "..."}, written as UTF-8 with CJK text unescaped and with every bytes value, such as thedataof aninline_data.doneorinline_thinking.doneitem, as base64 text.timestampis the time of the save in UTC, in ISO 8601 with milliseconds and a trailingZ, the form of JavaScript'stoISOString():2026-10-24T09:30:00.000Z.<trace_id>.txtis a transcript for a reader: the config withouttrace_id, then each message numbered, with its role, its items, its usage and its finish reason. A program SHOULD read the.json; the layout of the transcript is not specified.
7. Reading Traces
- The tracer's viewer (
create_web_app/createWebApp, orstart_web_server/startWebServeron port 25750 by default) lists the cache directory, renders a.jsontrace round by round, and shows any other file as plain text. - It converts the item types of trace files written before 0.5.0 when it loads them (MMSP-RFC-0009 §7).
- It MUST refuse, with 403, a requested path that, with symlinks resolved, is neither the cache directory nor inside it, by the same check the writer uses, and it MUST leave such entries out of its listings.
- The playground serves the viewer at
/tracer/on its cache directory; an MMSP server the playground starts runs in the playground's process, so its traces appear there too.
8. Conformance
src_py/mmsp/base_client.py/src_ts/src/baseClient.ts, which save the trace before thestop;src_py/mmsp/integration/tracer.py/src_ts/src/integration/tracer.ts, the writer and the viewer;src_py/mmsp/mmsp/client.py/src_ts/src/mmsp/client.ts, which save nothing.src_py/tests/test_tracer.py/src_ts/tests/tracer.test.ts: a traced response is on disk before its stop event reaches the caller; its fidelity is saved withoutitem_id; both files are written, a later save overwrites them and their directories are created; trace files saved before 0.5.0 render with the current item types; file names append the suffix to the normalized id; the timestamp is UTC with milliseconds and aZ; ids that leave the cache directory are refused; and the viewer refuses, with 403, a path outside the cache directory, symlinks included.src_py/tests/test_stream_protocol.py/src_ts/tests/stream-protocol.test.ts, which check that a refused trace id raisesUnsupportedParameterErrorbefore the client's request.src_py/tests/test_interruption.py/src_ts/tests/interruption.test.ts, which stream with atrace_idand check that a stream aborted, closed or left before itsstopsaves nothing.site/src/docs/tracing.en.md/tracing.zh.md; the Traces section ofserver.en.md/server.zh.md; thetrace_idtable ofconfiguration.en.md/configuration.zh.md.