Skip to content

fix(core): preserve OMP reasoning and add host protocol contracts - #162

Open
patlux wants to merge 2 commits into
mainfrom
host-protocol-contracts
Open

patlux wants to merge 2 commits into
mainfrom
host-protocol-contracts

Conversation

@patlux

@patlux patlux commented Oct 15, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add shared real-host contracts for Pi and OMP over Chat Completions, Responses and Anthropic Messages: system instructions, reasoning replay (including encrypted/signed reasoning), parallel tool call/result IDs and image results on the follow-up wire.
  • The new regression test exposed dropped Chat Completions reasoning on OMP 18.11.1. Opt into its replayReasoningContent compatibility flag. Verified failure before the flag and success after.
  • Pin PR hosts to Pi 1.1.0 / OMP 18.11.1; test latest releases weekly in a separate workflow. Run correctness CI for stacked PR bases too.
  • Run the contracts on the installed tarball; allow explicitly selected comma-separated live model profiles.

Verification

  • Full npm test, both real hosts required: PASS.
  • Packed npm artifact smoke with both hosts and all six wire/host contracts: PASS.
  • Formatting, diff checks and actionlint 1.7.7: PASS.
  • Loopback mocks and isolated homes only; no paid live API calls, account credentials, model-switch benchmark or upstream performance claim.

No npm release or merge is part of this PR. Independent of the routing/diagnostics stack; resolve the small compatForModel overlap when combining them.

@github-actions

Copy link
Copy Markdown
Contributor

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 2 package(s) with unknown licenses.
See the Details below.

License Issues

.github/workflows/latest-hosts.yml

PackageVersionLicenseIssue Type
actions/checkout4.*.*NullUnknown License
actions/setup-node4.*.*NullUnknown License
Allowed Licenses: MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC, 0BSD

OpenSSF Scorecard

PackageVersionScoreDetails
actions/actions/checkout 4.*.* 🟢 6.3
Details
CheckScoreReason
Code-Review🟢 10all changesets reviewed
Maintained🟢 45 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 4
Binary-Artifacts🟢 10no binaries found in the repo
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Pinned-Dependencies🟢 3dependency not pinned by hash detected -- score normalized to 3
Fuzzing⚠️ 0project is not fuzzed
Packaging⚠️ -1packaging workflow not detected
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
SAST🟢 10SAST tool is run on all commits
Branch-Protection🟢 6branch protection is not maximal on development and all release branches
actions/actions/setup-node 4.*.* 🟢 6.4
Details
CheckScoreReason
Binary-Artifacts🟢 9binaries present in source code
Maintained🟢 1022 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 10all changesets reviewed
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies🟢 5dependency not pinned by hash detected -- score normalized to 5
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST🟢 10SAST tool is run on all commits
actions/oven-sh/setup-bun 2.2.0 UnknownUnknown

Scanned Files

  • .github/workflows/latest-hosts.yml

@github-actions

Copy link
Copy Markdown
Contributor

Memory benchmark

Compared base 3e43a7c with PR head b34f59e on the same GitHub-hosted darwin runner. Lower values are better.

Metric Base PR PR − Base Change
Stable RSS 120.6 MiB ± 0.2 MiB 119.6 MiB ± 0.8 MiB -1.1 MiB ± 0.9 MiB -0.9%
Physical footprint 66.6 MiB ± 1.0 MiB 65.6 MiB ± 0.5 MiB -0.7 MiB ± 1.4 MiB -1.1%
Physical peak 77.4 MiB ± 1.0 MiB 75.8 MiB ± 0.8 MiB -2.2 MiB ± 1.6 MiB -2.9%

Interpretation: Differences larger than their measured MAD: Stable RSS -1.1 MiB ± 0.9 MiB, Physical peak -2.2 MiB ± 1.6 MiB.

Extension overhead above pi baseline

Metric Base overhead PR overhead Difference
Stable RSS +6.6 MiB ± 0.5 MiB +5.1 MiB ± 0.5 MiB -1.1 MiB ± 0.9 MiB
Physical footprint +3.5 MiB ± 0.7 MiB +2.8 MiB ± 1.6 MiB -0.7 MiB ± 1.4 MiB
Physical peak +3.7 MiB ± 0.8 MiB +2.7 MiB ± 1.4 MiB -2.2 MiB ± 1.6 MiB

Values are medians of 6 alternating, paired runs. The value after ± is the median absolute deviation (MAD). Each process was sampled 12 times after a 2500 ms warm-up.

Environment: pi 0.84.4, Bun 1.4.0, darwin arm64. RSS comes from ps; physical footprint and peak come from macOS footprint.

This is a comparative signal, not a pass/fail threshold. GitHub-hosted runner noise can affect absolute values.

@patlux patlux left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The contract test is a genuinely useful addition — it found a real OMP bug and covers all three wires on both hosts. The one thing I'd block on is the Pi pin version; the rest are comments/nits.

Comment thread .github/workflows/ci.yml
- name: Install pi
run: |
npm install -g @earendil-works/pi-coding-agent@latest
npm install -g @earendil-works/pi-coding-agent@1.1.0

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pinning Pi to 1.1.0 is a coverage regression: 1.2.0 (2026-10-12) and 1.3.0 (2026-10-15, published before this PR was opened) are out, and CI previously tested @latest. A PR that breaks on 1.3.0 now merges green and only shows up in the weekly job, after the fact.

Suggest:

  • pin to the current latest (1.3.0) and make "bump the pins" part of the release checklist, or
  • keep a pinned job as the required gate and add a latest job with continue-on-error: true in PR CI, so drift is visible on the PR rather than a week later.

Either way, CONTRIBUTING should say who bumps the pin and when (a green Latest host compatibility run should be the trigger).

- name: Record versions
run: |
{ "$PI_BIN" --version; "$OMP_BIN" --version; node --version; bun --version; } | tee -a "$GITHUB_STEP_SUMMARY"
- run: npm test

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On its own this job fails silently into the Actions tab (no issue, no notification beyond the default email). Fine if #163 lands; if this merges without it, note in CONTRIBUTING that someone has to look at the weekly run.

const root = fileURLToPath(new URL("../", import.meta.url))
const extension = resolve(process.env.COMMANDCODE_TEST_PACKAGE_DIR ?? root, "index.ts")
const fixture = join(root, "tests/fixtures/protocol-tools-extension.ts")
const models = [

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These three ids encode assumptions about the static catalog: deepseek/deepseek-v4.1-flash must be reasoning: true in commandcode-catalog.ts for the reasoning_content replay assert, and claude-sonnet-4-6 must resolve to Anthropic via apiForModelId. A catalog refresh that changes either will fail this test with an unrelated-looking assertion deep in the mock server. Add a comment stating the dependencies, or assert them up front with a clear message.

Comment thread index.ts
supportsStore: false,
supportsDeveloperRole: false,
supportsReasoningEffort: MODEL_EFFORTS[model.id] !== undefined,
replayReasoningContent: model.reasoning,

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This flag is now also sent to Pi. The comment says Pi ignores it — a link to the OMP flag definition (or a one-line note on which OMP version introduced it) would make the "OMP requires explicit opt-in" claim verifiable later when either host changes behavior.

Comment thread CHANGELOG.md

## Unreleased

- Preserve Chat Completions reasoning history on OMP with an explicit replay compatibility flag, verified by real Pi/OMP follow-up requests rather than only visible thinking deltas.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"verified by real Pi/OMP follow-up requests rather than only visible thinking deltas" is verification detail for the PR, not a user-facing note. Suggest: "Preserve Chat Completions reasoning history on OMP; previous reasoning was dropped from follow-up requests."

@pierreraby pierreraby left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved, with one P1 test-hardening note below that I deliberately leave non-blocking. Verified locally at the exact head in an isolated worktree (npm ci): tsc --noEmit PASS, test:host-protocols 6/6 (pi + omp x chat/responses/messages, incl. reasoning replay, parallel tool pairing, and the #141 call_id <= 64 pin on the Responses wire), full test:unit exit 0 (401 checks), Prettier + git diff --check PASS. I also had this head independently reviewed in a fresh context: the OMP fix itself is judged correct and minimal (one compat flag confined to the Chat Completions branch, Pi unaffected, no reach into generate/diagnostics), contracts largely non-vacuous, CI pinning + weekly @latest separation sane, no routing regression. I closed the reviewer's committed-range check myself (git diff --stat 3e43a7c..HEAD: 10 files, 2 commits, all consistent with the description).

P1 (test-only, non-blocking): the "image results on follow-up" assertion (test-host-protocols.mjs:88, assert.match(history, /image|image_url/)) is vacuous — the follow-up history always contains the tool-call arguments ({"image":"A"}), so the regex matches even if image tool results were dropped. One-line fix suggested: assert the payload instead, e.g. /data:image\/png;base64,iVBORw0KGgo|"type":"image"|image_url/. I approve because the shipped fix is solid and image forwarding is already pinned non-vacuously elsewhere (test-pi-local provider path) — but please land that line with or right after this PR since it is the PR's own acceptance criterion.

This branch has not been deployed

No deployments
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.

2 participants