Skip to content

feat(wire): mirror constructors for primeFold projections (Phase 2) - #114

Merged
ranxianglei merged 1 commit into
masterfrom
2026-08-22_wire-mirror-constructors
Aug 22, 2026
Merged

feat(wire): mirror constructors for primeFold projections (Phase 2)#114
ranxianglei merged 1 commit into
masterfrom
2026-08-22_wire-mirror-constructors

Conversation

@ranxianglei

Copy link
Copy Markdown
Owner

What

Phase 2 of the protocol consolidation (#112 follow-up, plan in issue #64 discussion): the kernel now owns the wire mirror constructors — the "what will the host put on the wire after a restart" projections that primeFold needs to land a resumed session's preview in the same ref/fingerprint space as the live request.

Until now these were three hand-rolled builders inside the omp plugin (wire-fold.ts): exactly the scattered-protocol-knowledge pattern that produced the issue-#64 class of restart divergences (fix one place, break another).

New module src/wire/mirror.ts

Export Purpose
MirrorMessage / MirrorBlock Neutral view type. Contract: caller maps its persisted shape and pre-normalizes text (ref-tag stripping stays a host-app concern)
mirrorOpenaiMessages(view, systemText) completions layout: system msg first, thinking as reasoning_content field, tool_calls JSON
mirrorAnthropicMessages(view) messages layout: no system (top-level field, out of fold space), thinking as signed blocks, tool results folded into user turns
mirrorResponsesInput(view) /v1/responses layout: input item array, assistant blocks in content order, reasoning items
mirrorOpenaiToCore / mirrorAnthropicToCore / mirrorResponsesToCore fold each mirror through the matching codec → BiliMessage[]

Byte-level wire rules are ported verbatim from the omp builders (whitespace-only text kept on openai, dropped on anthropic/responses; empty turns dropped; tool argument JSON shapes), so existing omp behavior is preserved exactly when it switches over.

Parity tests (tests/wire-mirror.test.ts, 9 tests)

Full suite: 413 pass, 0 fail (was 404). tsc --noEmit clean.

Follow-ups (separate PRs)

  1. omp consumes acp-kernel@0.0.35 mirror constructors and deletes its three hand-rolled builders (~170 lines).
  2. Proxy is unaffected (mitm sees real bytes, never mirrors).

Move the three hand-rolled wire mirrors out of the omp plugin
(wire-fold.ts) into the kernel, next to the codecs that define
their identity space. Protocol knowledge stops being scattered:
one place fixed no longer breaks another (issue #64 class).

- MirrorMessage/MirrorBlock: neutral view, caller pre-normalizes
  text (ref-tag stripping stays a host-app concern)
- mirrorOpenaiMessages / mirrorAnthropicMessages /
  mirrorResponsesInput: host-encoder wire rules per protocol
  family (thinking placement, whitespace handling, tool shapes)
- mirrorOpenaiToCore / mirrorAnthropicToCore /
  mirrorResponsesToCore: fold through the matching codec
- parity tests: mirror ids == live reasoning_content wire ==
  live inline-<think> wire (issues #103, #64 and its demoted +
  responses variants)
@ranxianglei
ranxianglei merged commit d5338a0 into master Aug 22, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant