Skip to content

refactor(native): extract shared session-adoption parsers from live forwarders#1973

Draft
apple-techie wants to merge 2 commits into
omnigent-ai:mainfrom
apple-techie:polly/session-adoption-foundation
Draft

refactor(native): extract shared session-adoption parsers from live forwarders#1973
apple-techie wants to merge 2 commits into
omnigent-ai:mainfrom
apple-techie:polly/session-adoption-foundation

Conversation

@apple-techie

Copy link
Copy Markdown

Summary

Foundation slice for session adoption (importing existing native harness sessions into Omnigent conversations — see designs/session-adoption.md). This PR is a pure refactor with zero behavior change: it extracts the inline "native record → Omnigent conversation item" translation out of the three live forwarders into shared, side-effect-free modules, so that adoption can reuse the exact same parsers the live forwarders use (rather than reimplementing them).

What changed

Extracted pure parsers, rewrote each forwarder to call them, and re-exported every moved symbol under its original name so existing callers/tests are untouched:

New module Extracted from Key exports
omnigent/hermes_native_items.py hermes_native_forwarder.py HermesMirrorItem, message_to_items, assistant_row_has_tool_calls
omnigent/claude_transcript_parser.py claude_native_bridge.py read_transcript_items_from_offset/_since/_since_with_position, read_assistant_text_since, JSONL record readers, entry→items builders, usage/model extraction
omnigent/codex_native_items.py codex_native_forwarder.py tool-call normalization + builders, terminal-error classification, resume-status edges, and the new pure iter_resume_items(response)

codex_native_forwarder._replay_resume_response now drives replay through iter_resume_items (the same normalization path adoption will use). The new modules are pure — no IO/DB/network/polling (Claude's transcript file reads are the one inherent exception).

Verification

  • 705 passed across all Hermes/Claude/Codex forwarder + bridge suites — unchanged (the only test file added is the new tests/test_native_adoption_parsers.py).
  • 16 characterization tests feed representative native records through each extracted helper and assert byte-identical outputs.
  • 72 re-export regression tests assert every moved symbol is importable from its original module path and is the same object — locking the "moved-without-alias" bug class permanently.
  • Independent cross-vendor review confirmed the extraction is logically identical (straight code motion) and caught + verified-fixed a missing-re-export gap.
  • ruff + full pre-commit: pass.

No behavior change; no existing test modified. Later slices (server adoption API, per-harness discover/adopt/resume, web UI) build on this.

🤖 Generated with Claude Code

dokploy-bot and others added 2 commits July 4, 2026 17:34
…orwarders

Slice 1 (foundation) of seamless external-session adoption. Pure refactor with
ZERO behavior change: factor the native-record -> Omnigent-item translation
logic out of the three live forwarders into standalone, side-effect-free modules
so a later adoption path can reuse the exact forwarder parsers instead of a
second, simplified transcript parser.

New modules (no IO / DB / network — pure translation):
- omnigent/hermes_native_items.py: HermesMirrorItem, message_to_items,
  assistant_row_has_tool_calls (from hermes_native_forwarder).
- omnigent/claude_transcript_parser.py: ClaudeTranscriptItem, TranscriptReadResult,
  the JSONL record reader, read_transcript_items_* readers, _transcript_items_from_entry
  and all subhelpers, and per-entry usage/model extraction (from claude_native_bridge).
- omnigent/codex_native_items.py: terminal-error derivation (_terminal_error_from_turn
  and friends), resume turn -> status derivation, built-in tool-call normalization,
  turn/source ids, and a new pure iter_resume_items() helper (from codex_native_forwarder).

Each live forwarder now imports the extracted helpers and re-exports them under
their original names (redundant `as` aliases) so every existing caller and test
keeps importing them unchanged. codex _replay_resume_response() now drives the
replay loop through iter_resume_items(), the same normalization path adoption
will use.

Behavior is byte-identical: all existing forwarder/bridge suites pass unmodified
(741 across hermes/claude/codex native suites). Adds tests/test_native_adoption_parsers.py
characterizing the extracted helpers directly from the new modules.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cross-review found a missing-re-export gap: `_ATTACHMENT_MARKER_RE` and
`_SKILL_INVOKE_RE` were moved from hermes_native_forwarder into
hermes_native_items but were not restored as re-exports, so
`from omnigent.hermes_native_forwarder import _ATTACHMENT_MARKER_RE` (and
attribute access) would break — a violation of the zero-behaviour transition
contract that every moved symbol stays importable under its original name.

- Re-export both regexes from hermes_native_forwarder via `as`-aliases.
- Swept every import site + attribute access of the three original modules
  (omnigent/ and tests/); confirmed all 5 hermes / 37 claude / 29 codex moved
  symbols (+ the new iter_resume_items) resolve from their original module.
  Claude/Codex were already complete (blanket `as`-alias re-export); only the
  two Hermes regexes were missing.
- Add parametrized re-export tests covering all moved symbols to lock the
  moved-without-alias regression class.

Repr note: kept the design's public class name `HermesMirrorItem` with the
`_MirrorItem = HermesMirrorItem` alias (no caller/test depends on repr); did not
rename the runtime class back.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the size/XL Pull request size: XL label Jul 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XL Pull request size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant