Expand description
Deterministic transcript segmentation for the compile_transcript MCP
tool (V2b-2): splits a raw agent-session transcript into turns and, within
each turn, into code/log/body sub-segments — pure, zero-regex, zero-clock,
so the same transcript + policy always segments byte-identically. See
segment::segment_transcript.
Deterministic transcript segmentation for the compile_transcript MCP
tool (V2b-2, see the crate’s PLAN.md, section V2b).
segment_transcript turns a raw agent-session transcript — plain text
with role markers, or JSONL — into an ordered list of
TranscriptSegments, each wrapping an ordinary [super::ContextFragment]
plus the audit metadata (turn, role, kind, byte range) the
compile_transcript tool reports alongside the compiled context. The
resulting fragments feed the existing, unmodified super::ContextCompiler
pipeline — this module only decides how to cut the transcript up, never
what to keep or drop.
Zero regex, zero clock, single linear scan per stage — same
determinism contract as [super::chunk]: the same transcript + the same
SegmentationPolicy always segment byte-identically (see
segmentation_twice_is_byte_identical in the test suite).
§Pipeline
- Format detection ([
detect_and_segment]):jsonlwhen every non-empty line parses as a{role, content}JSON object,plainotherwise. A caller-forced format that does not parse is a hard error — never a silent fallback to the other format — surfaced ascrate::error::MemoryError::SegmentationError(a FORMAT failure, distinct from a budget/cap breach; see below). - Turns:
jsonl— one line, one turn,roletaken directly from the parsed JSON.plain— a CLOSED table of markers ("System:","User:","Human:","Assistant:","AI:","Tool:","### User","### Assistant"), first match at the start of a line opens a new turn; a transcript with no marker at all is one turn withrole: None. - Sub-segmentation (
plainturns only — ajsonlturn’scontentis a JSON-decoded string, not a byte-aligned slice of the transcript, so it is never re-scanned; the underlyingcontent.contains("```")/ value-density rules in [super::classify] still see it, unaffected): fenced code blocks ([super::chunk::fence_segments]) become atomiccodesegments; runs of at least 8 consecutive log-like lines (a volatile timestamp/pid prefix — [super::log_normalize::mask_volatile_prefix] — or a raw-text repeat) becomelogsegments; everything else isbody. - Normalization: an unsplittable fence over
crate::limits::MAX_FRAGMENT_BYTESis a hard error (never silently truncated); an oversizedbodysegment is re-split with [super::chunk_text]; segments underSegmentationPolicy::min_segment_bytesmerge into an adjacent segment of the same turn and kind; more thancrate::limits::MAX_FRAGMENTSsegments after merging is a hard, actionable error (“raisemin_segment_bytes”) — never a silent drop.
A genuine budget/cap breach (transcript over
crate::limits::MAX_TRANSCRIPT_BYTES, an unsplittable oversized fence,
or too many fragments after merging) surfaces as
crate::error::MemoryError::ContextOverLimit; a FORMAT/parsing failure
(a forced jsonl line that does not parse) surfaces as the distinct
crate::error::MemoryError::SegmentationError (issue #1516, m2 — kept
separate precisely so a caller filtering on the error message cannot
confuse a malformed-input error for a size breach, even though both map
to the same INVALID_PARAMS-category MCP code). A path-sourced
transcript can additionally fail with
crate::error::MemoryError::IngestDisabled/crate::error::MemoryError::IngestOutsideRoots/
crate::error::MemoryError::IngestPath, via
[super::ingest::resolve_transcript_path].
Structs§
- Segmentation
Outcome - The full result of
segment_transcript: the detected format, the segments, and how much normalization merging did. - Segmentation
Policy - Tuning knobs for
segment_transcript.Defaultis the recommended profile. - Transcript
Segment - One segmented piece of the transcript: an ordinary
ContextFragment(ready to feedsuper::ContextCompiler) plus the audit metadata thecompile_transcripttool reports in itssegmentation.segmentslist.
Enums§
- Segment
Format - Which transcript format to assume, or detect automatically.
- Segment
Kind - What kind of content a sub-segment carries — decides whether it was cut
out as an atomic fence, a detected log run, or ordinary prose/dialogue
left for [
super::classify]’s rule table to judge.
Functions§
- segment_
transcript - Segment
textunderpolicy— see the module docs for the full pipeline. Pure: no I/O, no clock, no randomness; the sametext+policyalways produce byte-identical output.