LLP 0265: the OpenClaw sweep reads the run trajectory for system_text and tools - #869
Draft
bgmcmullen wants to merge 1 commit into
Draft
LLP 0265: the OpenClaw sweep reads the run trajectory for system_text and tools#869bgmcmullen wants to merge 1 commit into
bgmcmullen wants to merge 1 commit into
Conversation
… and tools OpenClaw rows were the thinnest in ai_gateway_messages: system_text and tools null on every one, because the session transcript records the conversation and nothing about the run that produced it. The run trajectory OpenClaw already writes beside every session does, so the sweep now reads it. A new one-reader module takes exactly two facts from context.compiled, the compiled system prompt and the tool definitions, and the backfill stamps them onto the messages of the run whose window covers them. The match is on the session file's recording time, not the message's own timestamp: a webchat prompt carries the moment the user sent it, which can predate its own run's compile, so the reader now surfaces recordedAtMs alongside timestampMs. Stamping is per message, so AiGatewayProjectedMessage gains system_text and tools and the row builder prefers them over the exchange pair, the precedence model (LLP 0026) and provider (LLP 0194) already had. An OpenClaw session recompiles per run: one observed session ran with 23, then 21, then 26 tools under three different prompts. OpenClaw truncates a recorded prompt at two caps and announces only one: past 32768 characters the value is replaced by a stub, and below that a long prompt is clipped to 20000 characters plus an ellipsis and written as an ordinary string. Truncation is therefore detected (stub, a recorded string shorter than the run's own reported size, or the trailing ellipsis) rather than assumed absent, and attributes.openclaw.system_prompt carries chars, hash, recorded_chars, and truncated. On the corpus this was verified against, no real agent run recorded a complete system prompt, so complete prompt text still depends on the live lane and LLP 0175. LLP 0171's trajectory-file non-goal is lifted for these two columns only; the probe-session stream and live tail stay out. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
OpenClaw rows were the thinnest in
ai_gateway_messages. On the machine this was developed against: 73 rows,cwdon all of them,modelon half, andsystem_text/toolsnull on every one. The session transcript records the conversation and nothing about the run that produced it; the run trajectory OpenClaw already writes beside every session does.What changed
openclaw/src/trajectory_file.js, the one reader of<sessionId>.trajectory.jsonl(resolved through OpenClaw's.trajectory-path.jsonpointer when present). It takes exactly two facts fromcontext.compiled, the compiled system prompt and the tool definitions, and leaves the rest of the stream on disk.AiGatewayProjectedMessagegainssystem_textandtools, and the row builder prefers them over the exchange-level pair, the precedencemodel(LLP 0026) andprovider(LLP 0194) already had. An OpenClaw session recompiles per run: one observed session ran with 23, then 21, then 26 tools under three different system prompts, so an exchange-level value would present one turn's answer as every turn's. No live projector sets either field, so live rows are unchanged.context.compiledand closes at itssession.ended; a message outside every window is stamped with nothing, because a run that failed before compiling (or one an embedded CLI harness owned) is not described by whatever the previous run compiled.OpenclawSessionMessagenow surfacesrecordedAtMs(the record line's timestamp) alongsidetimestampMs(the envelope's, still whatmessage_created_atuses). A webchat prompt carries the moment the user sent it, seconds before its own run compiled.The truncation problem
OpenClaw truncates a recorded system prompt at two caps and announces only one:
TRAJECTORY_RUNTIME_DATA_STRING_MAX_CHARS, hard-coded) the value is replaced by a{ truncated: true, originalChars, limitChars }stub;Truncation is therefore detected rather than assumed absent: the stub, a recorded string shorter than the
charsthe run's owntrace.metadatareports, or the trailing ellipsis. Clipped text is kept (a 20000-char prefix is useful) and flagged;attributes.openclaw.system_promptcarrieschars,hash,recorded_chars, andtruncated.Across the 33 verified runs, no real agent run recorded a complete system prompt (24 stubbed at 36k-41k, 9 clipped at exactly 20001 chars, 2 complete two-line probes). Complete prompt text still depends on the wire, so LLP 0175 remains the path to it.
Effect on real data (73 rows)
toolssystem_text, completesystem_text, clipped and flaggedEnrichment applies from the next import onward: backfill dedupe skips rows already committed under the same
part_id, the same boundary LLP 0194 accepted.Docs
LLP 0265 is new. LLP 0171 gains an
Extended-byand a narrowed non-goal: the trajectory-file half is lifted for these two columns only; the probe-session stream and the live tail stay out.Testing
test/plugins/openclaw-trajectory.test.js(new, 12 cases): pointer resolution and its refusals, per-run contexts, both truncation caps, the report cross-check, window matching.test/plugins/openclaw-backfill.test.js(+8 cases): end-to-end stamping through the real materializer, two runs in one session, the recording-time rule, both truncation states, untraced sessions, and the run's log counters.npm run smoke -- backfill_openclaw_session_shapenow stages a trajectory and asserts both columns through the query path. Its existing two-level timestamp disagreement doubles as the recording-time proof: the assistant envelope's 10:00:09 falls outside the run window, its record line's 10:00:02 falls inside.npm testat the 28 pre-existing failures (unchanged),npm run typecheckat its 3 pre-existing errors,backfill_openclaw_fixturegreen.🤖 Generated with Claude Code