Skip to content

feat(training-export): overhaul trigger system and message conversion#79703

Closed
wzhgba wants to merge 1 commit into
openclaw:mainfrom
SenseTime-FVG:wuzehuan/training-export
Closed

feat(training-export): overhaul trigger system and message conversion#79703
wzhgba wants to merge 1 commit into
openclaw:mainfrom
SenseTime-FVG:wuzehuan/training-export

Conversation

@wzhgba

@wzhgba wzhgba commented May 9, 2026

Copy link
Copy Markdown

Draft / work-in-progress — this PR is under active development. Feedback welcome on the overall direction.

Summary

Introduce a trajectory-first, trigger-driven training export system that produces episode-level JSONL data from the OpenClaw runtime — no offline reconstruction, no separate pipeline. The system is opt-in (trainingExport.enabled: true) and writes to:

~/.openclaw/training-export/episodes.jsonl

Each line is a self-contained training sample: a task episode (full agent turn with system prompt, messages, tools, metadata) or a compact-summary episode (compression prompt → summary pair for RL compaction training).

Relationship to Existing Systems

/export-trajectory (human-facing debug bundles)

The existing /export-trajectory command (docs at docs/tools/trajectory.md) produces redacted interactive support bundles for human debugging — prompt timelines, tool traces, transcript snapshots, usage metadata. It is triggered manually by users or support staff.

The training export introduced here is complementary and non-overlapping:

/export-trajectory Training Export
Purpose Human debugging, support Machine training data
Trigger Manual command Automatic (compaction, reset, export command)
Output Redacted bundle directory JSONL episodes
Format Directory of text/markdown files One JSON line per episode
Privacy Redacted (best-effort) Full content (machine-consumed; opt-in)
Audience Developers, support RL training pipelines

Both systems read from the same trajectory (trajectory capture / cache-trace). Training export simply produces a different output format for a different consumer, alongside the existing mechanism.

Compaction subsystem

Training export hooks into the Pi SDK compaction lifecycle (session_before_compact + session_compact) to capture:

  • Pre-compaction context (task episode): the full conversation before compression
  • Post-compaction summary (summary episode): the prompt sent to the summarization model + the summary it produced, with compaction metadata (tokensBefore, firstKeptEntryId, fromExtension)

This is the same data the compaction system already computes internally — training export just persists it in a structured training format before it is discarded.

Key Design Decisions

1. Trajectory-first

All training fields (system prompt, messages, tools, model metadata) come from runtime trajectory context.compiled events. Message and tool conversion delegates to the Pi SDK / provider layer (convertMessages from @mariozechner/pi-ai/openai-completions).

2. Unified compaction hook

A single Pi SDK extension (session_before_compact + session_compact) handles all compaction modes (default, safeguard, manual, overflow, timeout). No runTrainingExport calls scattered across individual compaction paths.

3. Pair-export guarantee

For compaction-triggered exports, task and summary episodes are built as a batch. If either is filtered by quality checks, the entire batch is discarded — no orphaned episodes.

4. Config-gated at every call site

getTrainingExportConfig(cfg)?.enabled === true is checked at all three entry points (extension registration, session reset, trajectory export command), so reviewers can see the opt-in gating logic without digging into implementation details.

5. compactionSummary bridging

Pi SDK's convertToLlm converts compactionSummaryuser messages, but the upstream convertMessages from @mariozechner/pi-ai/openai-completions does not handle the compactionSummary role. A pre-processing step (sharing a single map with thinking-block stripping) mirrors Pi SDK's conversion format before handing off to the upstream converter.

6. Training-quality message filtering (all triggers)

Training episodes must end with a complete assistant message — regardless of trigger type. Any snapshot (compaction, reset, or trajectory export) may end mid-turn at a non-assistant message (e.g. toolResult). Trailing non-assistant messages are trimmed from every trigger's output. The trainExampleMessagesAreUsable check requires ≥1 user + ≥1 assistant; if trimming leaves the episode unusable, it is discarded entirely. This is a universal training-data quality requirement, not a compaction-specific behavior.

7. Reset export is independent of plugin hooks

The before_reset training export call is placed outside emitGatewayBeforeResetPluginHook, so it fires regardless of whether any before_reset plugin hooks are registered.

8. Private file permissions

The export directory (~/.openclaw/training-export) and JSONL file are created with private filesystem modes (0o700 / 0o600) to prevent world-readable access to training data.

Files Changed

File Change
src/training-export.ts New — core module: snapshot collection, episode construction, JSONL I/O, prompt constants, compaction extension
src/training-export.test.ts New — test suite
docs/training-export.md New — formal feature documentation
src/config/types.openclaw.ts Add trainingExport config type (enabled, compat)
src/config/zod-schema.ts Add trainingExport schema
src/config/schema.help.ts Add field help text
src/config/schema.labels.ts Add field labels
src/agents/pi-embedded-runner/extensions.ts Register compaction extension (config-gated, opt-in)
src/gateway/session-reset-service.ts before_reset trigger (config-gated, outside hook function)
src/auto-reply/reply/commands-export-trajectory.ts trajectory_export trigger (config-gated, alongside existing command)
src/agents/openai-transport-stream.ts Minor: export convertResponsesMessages for use in conversion pipeline

Configuration

trainingExport:
  enabled: true            # default: false (opt-in)
  compat: {}               # optional ModelCompatConfig override for export path

When enabled is false (the default), the extension is not registered and runTrainingExport is never called — zero overhead.

How to Test

  1. Enable via trainingExport.enabled: true
  2. Trigger a compaction in a session long enough to exceed the context threshold
  3. Check ~/.openclaw/training-export/episodes.jsonl — should contain paired task + summary episodes with compaction metadata
  4. Reset a session — should produce a task episode
  5. Run /export-trajectory — should produce a task episode via the training export path as well
  6. Disable via trainingExport.enabled: false — episodes file should receive no new entries

Open Questions for Review

  1. Default to opt-in (enabled: false) — is this the right default, or should we consider a different approach?
  2. Privacy and retention policy — the training export writes full (non-redacted) session content to disk. Should there be a retention/cleanup mechanism?

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation gateway Gateway runtime agents Agent runtime and tooling size: XL triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 9, 2026
@clawsweeper

clawsweeper Bot commented May 9, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I swept through the related work, and this is now duplicate or superseded.

Keep open, but this PR is not merge-ready. The training-export feature is unique relative to the existing trajectory bundle system, but the branch is dirty against current main, targets removed Pi runtime paths, adds a new core config and unredacted export surface, lacks real behavior proof, and bypasses the bounded trajectory parsing contract.

Canonical path: Close this stale PR. The latest review rated it F, the branch still lacks merge-ready proof, and there has been no human follow-up after the durable review.

So I’m closing this here because the remaining work is already tracked in the canonical issue.

Review details

Best possible solution:

Close this stale PR. The latest review rated it F, the branch still lacks merge-ready proof, and there has been no human follow-up after the durable review.

Do we have a high-confidence way to reproduce the issue?

Yes for the review blockers: source inspection shows stale Pi imports/runtime paths and whole-file synchronous trajectory parsing on enabled trigger paths. I did not run the feature in a real setup, and the contributor has not supplied after-fix behavior proof.

Is this the best way to solve the issue?

No. The training export direction may be useful, but this branch should first move to current OpenClaw runtime contracts, reuse bounded trajectory parsing, and settle privacy/retention policy before merge.

Security review:

Security review needs attention: Enabled export writes unredacted session-derived training examples to local JSONL while warning, retention, and redaction policy remain unresolved.

  • [medium] Unredacted automatic training data export — src/training-export.ts:824
    When enabled, the exporter writes full session-derived training examples to episodes.jsonl; private file modes reduce local exposure, but retention, warning, and redaction policy are still open product/security questions.
    Confidence: 0.88

AGENTS.md: found and applied where relevant.

What I checked:

  • stale F-rated PR: PR was opened 2026-05-09T07:16:12Z, is older than 60 days, and the latest review rated it F.
  • proof blocker: real behavior proof is missing and proof tier is F, so this branch is not merge-ready without contributor follow-up.
  • no human follow-up: live comments and timeline hydrated by apply contain no non-automation activity after the ClawSweeper review.

Likely related people:

  • scoootscooob: Authored merged trajectory export work that is the closest existing input/source system for this PR's training export path. (role: trajectory export feature contributor; confidence: high; commits: 371a169d2741; files: src/trajectory/export.ts, src/trajectory/runtime.ts, src/auto-reply/reply/commands-export-trajectory.ts)
  • Vincent Koc: Authored the recent centralization of export transcript parsing and adjacent runtime type split work around the current main surfaces this PR must rebase onto. (role: recent area contributor; confidence: medium; commits: 851601895671, 61da711b1a7e; files: src/trajectory/export.ts, src/plugins/provider-runtime-model.types.ts)
  • DhruvBhatia0: Authored the pluggable compaction provider registry, adjacent to the compaction lifecycle that this PR tries to hook for training export. (role: compaction runtime contributor; confidence: medium; commits: 12331f04631f; files: src/plugins/compaction-provider.ts, src/agents/agent-hooks/compaction-safeguard.ts)
  • Rodrigo Uroz: History shows compaction safeguard configuration work near the runtime behavior this PR wants to observe and export. (role: compaction safeguard contributor; confidence: medium; commits: 4c0b873a4dd2; files: src/agents/embedded-agent-runner/extensions.ts, src/agents/compaction.ts, src/agents/agent-hooks/compaction-safeguard.ts)

Codex review notes: model internal, reasoning high; reviewed against f55abc0606f0.

@wzhgba
wzhgba force-pushed the wuzehuan/training-export branch from b675a0d to 4f6af34 Compare May 9, 2026 08:10
@openclaw-barnacle openclaw-barnacle Bot added the triage: refactor-only Candidate: refactor/cleanup-only PR without maintainer context. label May 9, 2026
@wzhgba
wzhgba force-pushed the wuzehuan/training-export branch 3 times, most recently from 8649e3e to 9f06f41 Compare May 9, 2026 10:46
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jun 1, 2026
@clawsweeper clawsweeper Bot added the rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. label Jun 1, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Jun 2, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels Jun 2, 2026
@clawsweeper

clawsweeper Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper applied the proposed close for this PR.

@clawsweeper clawsweeper Bot closed this Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling docs Improvements or additions to documentation gateway Gateway runtime merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XL status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. triage: refactor-only Candidate: refactor/cleanup-only PR without maintainer context.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant