openclaw - ✅(Solved) Fix CI: plugin contract fixtures stale after `@mariozechner/pi-ai` 0.70.x added google-vertex / qwencloud / etc. [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#72743Fetched 2026-04-28 06:32:39
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Timeline (top)
closed ×1commented ×1cross-referenced ×1referenced ×1

@mariozechner/pi-ai 0.70.2 (current package.json pin) exposes additional plugin providers (google-vertex under the google plugin, qwencloud plus 2 others under the qwen plugin) that aren't reflected in test/helpers/plugins/plugin-registration-contract-cases.ts or in the provider contract registry. As a result, checks-fast-contracts-plugins and checks-node-extensions-shard-6 and checks-node-core-src-security fail on main itself.

Error Message

× extensions/google/plugin-registration.contract.test.ts

google plugin registration contract > keeps bundled provider ownership explicit AssertionError: expected [ 'google', 'google-gemini-cli', …(1) ] to deeply equal [ 'google', 'google-gemini-cli' ]

× extensions/qwen/plugin-registration.contract.test.ts

qwen plugin registration contract > keeps bundled provider ownership explicit AssertionError: expected [ 'qwen', 'qwencloud', …(2) ] to deeply equal [ 'qwen' ]

× src/plugins/contracts/plugin-registration.google.contract.test.ts

google plugin registration contract > keeps bundled provider ownership explicit AssertionError: expected [ 'google', 'google-gemini-cli', …(1) ] to deeply equal [ 'google', 'google-gemini-cli' ]

× src/plugins/contracts/providers.contract.test.ts

google:google-vertex provider contract > satisfies the base provider plugin contract Error: provider contract entry missing for google:google-vertex

× src/plugin-activation-boundary.test.ts

plugin activation boundary > keeps generic boundaries cold and loads only narrow browser helper surfaces on use AssertionError: expected { provider: 'google', …(1) } to deeply equal { provider: 'google', …(1) }

Root Cause

test/helpers/plugins/plugin-registration-contract-cases.ts:54-62 (the google case) declares:

google: {
  pluginId: "google",
  providerIds: ["google", "google-gemini-cli"],
  ...
},

But the runtime contract (after pi-ai 0.70.x) exposes a third provider, google-vertex, under the google plugin. Same drift for qwen (1 declared vs 4 runtime).

The providers.contract.test.ts failure is a downstream consequence: it iterates providerIds from the contract registry, encounters google-vertex (which the registry knows about because the runtime exposes it), then can't find a contract entry for it. So the registry side and the case-side need to be updated together.

Fix Action

Fixed

PR fix notes

PR #72276: [codex] Consolidate embedded runner structural splits

Description (problem / solution / changelog)

@steipete @pashpashpash

Summary

This PR is the single maintainer-facing RuntimePlan finalization and embedded-runner structural cleanup package for RFC #72072. It consolidates the earlier cleanup package plus the follow-up structural split PRs, then applies the actionable bot-review fixes from those PRs.

GitHub shows a cumulative diff against main; the tables below preserve the original PR/commit traceability so maintainers can review by logical slice instead of by archeology.

Superseded PRs

Superseded PRRole
#72134Consolidated RuntimePlan finalization cleanup package
#72259Split attempt prompt and transport preparation
#72261Extract embedded run attempt factory
#72269Extract attempt stream wrappers and diagnostic lifecycle
#72272Extract embedded run lane/workspace helpers, auto-closed by active PR limit
#72274Extract embedded run terminal result shaping, auto-closed by active PR limit

Commit Stack Map

CommitSourceScope
39b0afb525#72134Capture finalization baseline doc.
e754112b25#72134Add native AgentHarnessV2 factory registry.
fe4f272510#72134Extract attempt tool-policy helpers.
ecf2cd44fc#72134Extract attempt message summary helpers.
0689e41814#72134Extract run orchestration helpers.
755616970b#72134Add canonical/deprecated embedded-runner barrels.
9c6a61dc07#72134Add RuntimePlan finalization handoff doc.
83a1f03b52, 7dca2ad3e8, ae5a5cb7bb#72134Stabilization/review fixes and QA retrigger.
1cdfd2c5be#72259Split prompt/bootstrap-context and transport setup out of attempt.ts.
cc8c5f289f#72261Extract embedded run attempt input / RuntimePlan factory from run.ts.
96e08f50a5#72269Extract run diagnostic lifecycle emitter.
d1bf5e6e1a#72269Extract ordered stream wrapper stack from attempt.ts.
5b54353fc1#72269Relax diagnostic lifecycle params to match narrow production/test callers.
7b50588a14#72272Extract lane/workspace/channel-format/abort helpers from run.ts.
556cad03df#72274Extract success terminal-result shaping from run.ts.
c961ad9c25Review loopFix actionable bot comments from the superseded PRs.
42d927d7d7CI fixStringify the prior transport before logging transport overrides.
58ff685083Review loopRemove redundant attempt wrapper imports flagged on the consolidated PR.

Architecture

flowchart TD
  RFC["RFC #72072"] --> Contracts["RuntimePlan cleanup package (#72134)"]
  Contracts --> Harness["AgentHarnessV2 native factory registry"]
  Contracts --> Barrels["embedded-runner compatibility barrels"]
  Contracts --> Docs["baseline + handoff docs"]

  Harness --> AttemptPrep["attempt prompt + transport helpers"]
  AttemptPrep --> AttemptRuntime["attempt lifecycle + stream wrappers"]
  AttemptRuntime --> RunFactory["run attempt factory"]
  RunFactory --> LaneWorkspace["run lane/workspace helpers"]
  LaneWorkspace --> TerminalResult["run terminal result helper"]

  AttemptPrep --> AttemptTs["attempt.ts thinner orchestration"]
  AttemptRuntime --> AttemptTs
  RunFactory --> RunTs["run.ts thinner orchestration"]
  LaneWorkspace --> RunTs
  TerminalResult --> RunTs

File Map

File / AreaChange
docs/refactor/runtime-plan-finalization-baseline.mdDocuments baseline health and known drift before structural cleanup.
docs/refactor/runtime-plan-finalization-complete.mdMaintainer handoff for completed/deferred RuntimePlan finalization work.
src/agents/harness/v2.ts and harness testsAdds internal native V2 factory registry while preserving public V1 compatibility. Review fix: test comments now rely on explicit cleanup, not Vitest isolation.
src/agents/embedded-runner/index.ts, src/agents/pi-embedded-runner/index.ts, alias testsAdds neutral embedded-runner barrels while keeping Pi-named compatibility aliases.
src/agents/pi-embedded-runner/run/attempt-tools.tsTool allow-list/policy helper extraction.
src/agents/pi-embedded-runner/run/attempt-message-summary.tsDiagnostic message/transcript summary helper extraction.
src/agents/pi-embedded-runner/run/attempt-prompt.tsBootstrap routing/context injection and prompt-boundary preparation helper.
src/agents/pi-embedded-runner/run/attempt-transport.tsPer-turn streamFn, transport override, text-transform, extra-param, and prompt-cache-retention helper. Review fix: streamFn is required and activeSession.sessionId is the single source of truth.
src/agents/pi-embedded-runner/run/attempt-lifecycle.tsDiagnostic run.started / once-only run.completed lifecycle emitter. Review fix: hoisted mock and aborted outcome coverage.
src/agents/pi-embedded-runner/run/attempt-stream-wrappers.tsOrdered stream wrapper stack for cache tracing, transcript sanitation, yield abort, malformed tool-call cleanup/repair, payload logging, and stop-reason recovery.
src/agents/pi-embedded-runner/run/runtime-plan-factory.tsAttempt input builder and RuntimePlan wiring from run.ts.
src/agents/pi-embedded-runner/run/lane-workspace.tsQueue lane planning, tool-result format selection, probe-session detection, abort normalization, workspace context resolution, and fallback logging. Review fix: documents that caller-supplied enqueue opts out of lane routing.
src/agents/pi-embedded-runner/run/terminal-result.tsSuccess terminal EmbeddedPiRunResult shaping, stop-reason priority, execution trace, request shaping, completion trace, pending hosted tool calls, and silent-empty payloads.
src/agents/pi-embedded-runner/run.ts, run/attempt.tsDelegates extracted seams while keeping core run/recovery behavior in place.

Review Comments Addressed

SourceFix
#72134 Copilot commentReworded V2 registry test comment to avoid claiming Vitest test-file isolation; explicit cleanup is the invariant.
#72259/#72261 Copilot commentsMade AttemptTransportSession.agent.streamFn required and removed duplicated sessionId parameter.
#72269 Greptile/Copilot commentsAdded aborted lifecycle diagnostic test and switched to vi.hoisted mock setup.
#72272 Greptile commentAdded comment documenting that caller-provided enqueue opts out of lane routing and the cron deadlock guard.
#72276 Copilot commentRemoved redundant direct imports from attempt.ts; the existing re-export statements now carry those helpers alone.
#72276 check-lintFixed the restrict-template-expressions failure in attempt-transport.ts by normalizing the previous transport value before interpolation.

What Changed

  • The RuntimePlan finalization cleanup docs/barrels/Harness V2 registry and the structural helper extractions are in one package.
  • attempt.ts and run.ts are thinner by ownership boundary, not cosmetic convenience.
  • Extracted helpers have focused tests for behavior that used to be buried in long functions.
  • The most closure-heavy retry/error recovery paths remain inline to avoid behavioral drift.

What Did Not Change

  • No public plugin API removal.
  • No Harness V2 public plugin API expansion.
  • No pi-embedded-runner package rename beyond compatibility barrels.
  • No WS pooling.
  • No retry/error recovery extraction from the stream loop.
  • No work on prototype PRs #70743 or #70772.

Validation

Passed locally on this branch:

node scripts/run-vitest.mjs run --config test/vitest/vitest.agents.config.ts \
  src/agents/harness/v2.test.ts --reporter verbose

./node_modules/.bin/vitest run --config test/vitest/vitest.unit-fast.config.ts \
  src/agents/pi-embedded-runner/run/terminal-result.test.ts --reporter verbose

node scripts/run-vitest.mjs run --config test/vitest/vitest.agents.config.ts \
  src/agents/pi-embedded-runner/run/attempt-lifecycle.test.ts \
  src/agents/pi-embedded-runner/run/attempt.test.ts \
  src/agents/pi-embedded-runner/run/attempt.tool-call-normalization.test.ts \
  src/agents/pi-embedded-runner/run/llm-idle-timeout.test.ts \
  src/agents/pi-embedded-runner/run/lane-workspace.test.ts --reporter verbose

./node_modules/.bin/oxlint --tsconfig tsconfig.oxlint.core.json \
  src/agents/harness/v2.test.ts \
  src/agents/pi-embedded-runner/run/attempt.ts \
  src/agents/pi-embedded-runner/run/attempt-transport.ts \
  src/agents/pi-embedded-runner/run/attempt-lifecycle.test.ts \
  src/agents/pi-embedded-runner/run/lane-workspace.ts \
  src/agents/pi-embedded-runner/run.ts \
  src/agents/pi-embedded-runner/run/terminal-result.ts \
  src/agents/pi-embedded-runner/run/terminal-result.test.ts

git diff --check
pnpm check:architecture

OPENCLAW_OXLINT_SKIP_LOCK=1 OPENCLAW_OXLINT_SKIP_PREPARE=1 \
  node scripts/run-oxlint.mjs --tsconfig tsconfig.oxlint.core.json src ui packages --threads=8

Known current-main / stack baseline:

pnpm check:test-types

Still fails on existing ModelCompatConfig.supportsLongCacheRetention / missing @vincentkoc/qrcode-tui drift. No files introduced by this PR appear in the remaining failure list.

Deferred Work

  • Model/auth plan extraction from run.ts if maintainers want another structural slice.
  • Full neutral embedded-runner import guard after compatibility aliases settle.
  • Final GPT-5.4 smoke/handoff doc after this package lands.

Changed files

  • docs/refactor/runtime-plan-finalization-baseline.md (added, +154/-0)
  • docs/refactor/runtime-plan-finalization-complete.md (added, +123/-0)
  • extensions/feishu/src/outbound.test.ts (modified, +8/-7)
  • extensions/feishu/src/outbound.ts (modified, +11/-7)
  • src/agents/embedded-runner/index.ts (added, +31/-0)
  • src/agents/harness/builtin-pi.test.ts (added, +106/-0)
  • src/agents/harness/builtin-pi.ts (modified, +51/-2)
  • src/agents/harness/selection.test.ts (modified, +32/-0)
  • src/agents/harness/selection.ts (modified, +2/-2)
  • src/agents/harness/v2.test.ts (modified, +128/-1)
  • src/agents/harness/v2.ts (modified, +42/-0)
  • src/agents/pi-embedded-runner/aliases.test.ts (modified, +27/-0)
  • src/agents/pi-embedded-runner/index.ts (added, +42/-0)
  • src/agents/pi-embedded-runner/run.ts (modified, +111/-412)
  • src/agents/pi-embedded-runner/run/attempt-lifecycle.test.ts (added, +89/-0)
  • src/agents/pi-embedded-runner/run/attempt-lifecycle.ts (added, +78/-0)
  • src/agents/pi-embedded-runner/run/attempt-message-summary.ts (added, +90/-0)
  • src/agents/pi-embedded-runner/run/attempt-prompt.ts (added, +165/-0)
  • src/agents/pi-embedded-runner/run/attempt-stream-wrappers.test.ts (added, +369/-0)
  • src/agents/pi-embedded-runner/run/attempt-stream-wrappers.ts (added, +227/-0)
  • src/agents/pi-embedded-runner/run/attempt-tools.ts (added, +155/-0)
  • src/agents/pi-embedded-runner/run/attempt-transport.ts (added, +177/-0)
  • src/agents/pi-embedded-runner/run/attempt.ts (modified, +84/-655)
  • src/agents/pi-embedded-runner/run/lane-workspace.test.ts (added, +149/-0)
  • src/agents/pi-embedded-runner/run/lane-workspace.ts (added, +135/-0)
  • src/agents/pi-embedded-runner/run/run-orchestration-helpers.ts (added, +121/-0)
  • src/agents/pi-embedded-runner/run/runtime-plan-factory.test.ts (added, +96/-0)
  • src/agents/pi-embedded-runner/run/runtime-plan-factory.ts (added, +244/-0)
  • src/agents/pi-embedded-runner/run/terminal-result.test.ts (added, +183/-0)
  • src/agents/pi-embedded-runner/run/terminal-result.ts (added, +162/-0)
  • src/gateway/server-chat.stream-text-merge.test.ts (modified, +1/-4)
  • src/gateway/server/health-state.test.ts (modified, +3/-1)
  • ui/src/ui/app-channels.test.ts (modified, +5/-2)

Code Example

× extensions/google/plugin-registration.contract.test.ts
  > google plugin registration contract > keeps bundled provider ownership explicit
  AssertionError: expected [ 'google', 'google-gemini-cli', (1) ] to deeply equal [ 'google', 'google-gemini-cli' ]

× extensions/qwen/plugin-registration.contract.test.ts
  > qwen plugin registration contract > keeps bundled provider ownership explicit
  AssertionError: expected [ 'qwen', 'qwencloud', (2) ] to deeply equal [ 'qwen' ]

× src/plugins/contracts/plugin-registration.google.contract.test.ts
  > google plugin registration contract > keeps bundled provider ownership explicit
  AssertionError: expected [ 'google', 'google-gemini-cli', (1) ] to deeply equal [ 'google', 'google-gemini-cli' ]

× src/plugins/contracts/providers.contract.test.ts
  > google:google-vertex provider contract > satisfies the base provider plugin contract
  Error: provider contract entry missing for google:google-vertex

× src/plugin-activation-boundary.test.ts
  > plugin activation boundary > keeps generic boundaries cold and loads only narrow browser helper surfaces on use
  AssertionError: expected { provider: 'google', (1) } to deeply equal { provider: 'google', (1) }

---

google: {
  pluginId: "google",
  providerIds: ["google", "google-gemini-cli"],
  ...
},

---

pnpm test extensions/google/plugin-registration.contract.test.ts
pnpm test extensions/qwen/plugin-registration.contract.test.ts
pnpm test src/plugins/contracts/plugin-registration.google.contract.test.ts
pnpm test src/plugins/contracts/providers.contract.test.ts
pnpm test src/plugin-activation-boundary.test.ts
RAW_BUFFERClick to expand / collapse

Summary

@mariozechner/pi-ai 0.70.2 (current package.json pin) exposes additional plugin providers (google-vertex under the google plugin, qwencloud plus 2 others under the qwen plugin) that aren't reflected in test/helpers/plugins/plugin-registration-contract-cases.ts or in the provider contract registry. As a result, checks-fast-contracts-plugins and checks-node-extensions-shard-6 and checks-node-core-src-security fail on main itself.

Reproduction

The most recent non-cancelled main CI run (commit 7d9dc8cf24, run 24987122406, 2026-04-27 09:25 UTC) shows three failing jobs with the same root cause:

× extensions/google/plugin-registration.contract.test.ts
  > google plugin registration contract > keeps bundled provider ownership explicit
  AssertionError: expected [ 'google', 'google-gemini-cli', …(1) ] to deeply equal [ 'google', 'google-gemini-cli' ]

× extensions/qwen/plugin-registration.contract.test.ts
  > qwen plugin registration contract > keeps bundled provider ownership explicit
  AssertionError: expected [ 'qwen', 'qwencloud', …(2) ] to deeply equal [ 'qwen' ]

× src/plugins/contracts/plugin-registration.google.contract.test.ts
  > google plugin registration contract > keeps bundled provider ownership explicit
  AssertionError: expected [ 'google', 'google-gemini-cli', …(1) ] to deeply equal [ 'google', 'google-gemini-cli' ]

× src/plugins/contracts/providers.contract.test.ts
  > google:google-vertex provider contract > satisfies the base provider plugin contract
  Error: provider contract entry missing for google:google-vertex

× src/plugin-activation-boundary.test.ts
  > plugin activation boundary > keeps generic boundaries cold and loads only narrow browser helper surfaces on use
  AssertionError: expected { provider: 'google', …(1) } to deeply equal { provider: 'google', …(1) }

Root cause

test/helpers/plugins/plugin-registration-contract-cases.ts:54-62 (the google case) declares:

google: {
  pluginId: "google",
  providerIds: ["google", "google-gemini-cli"],
  ...
},

But the runtime contract (after pi-ai 0.70.x) exposes a third provider, google-vertex, under the google plugin. Same drift for qwen (1 declared vs 4 runtime).

The providers.contract.test.ts failure is a downstream consequence: it iterates providerIds from the contract registry, encounters google-vertex (which the registry knows about because the runtime exposes it), then can't find a contract entry for it. So the registry side and the case-side need to be updated together.

Fix shape

  1. Update test/helpers/plugins/plugin-registration-contract-cases.ts:
    • google.providerIds: add "google-vertex". Audit related capability lists (realtimeVoiceProviderIds, speechProviderIds, mediaUnderstandingProviderIds, imageGenerationProviderIds) for whether google-vertex should appear.
    • qwen.providerIds: add the 3 missing providers (likely "qwencloud" and 2 others — full list visible in the runtime contract registry).
  2. Add a contract entry for google:google-vertex in src/plugins/contracts/registry.ts (or wherever the bundled provider registry lives) so providers.contract.test.ts stops reporting provider contract entry missing.
  3. If google-vertex is not intended to ship as a google-plugin provider yet, alternative is to pin pi-ai to a prior version OR to filter the provider list at the OpenClaw boundary.

Verification

After fixing, the following should pass (currently fail on main):

pnpm test extensions/google/plugin-registration.contract.test.ts
pnpm test extensions/qwen/plugin-registration.contract.test.ts
pnpm test src/plugins/contracts/plugin-registration.google.contract.test.ts
pnpm test src/plugins/contracts/providers.contract.test.ts
pnpm test src/plugin-activation-boundary.test.ts

Impact

  • checks-fast-contracts-plugins, checks-node-extensions-shard-6, checks-node-core-src-security fail on main → all PRs targeting main inherit a red CI even if the PR itself is clean. Specifically: PR #72276 was clean locally and after merge but inherits these failures.
  • bug:behavior not bug:crash — incorrect test-fixture state, no runtime crash.

Discovered

While driving PR #72276 to mergeable; comparison of PR's CI failures against main's most-recent non-cancelled run identified the failures as pre-existing main breakage rather than PR-introduced. PR #72276 carries the same failures on the same files (untouched by that PR's diff).

extent analysis

TL;DR

Update the plugin-registration-contract-cases.ts file and add a contract entry for google:google-vertex to fix the failing tests.

Guidance

  • Update test/helpers/plugins/plugin-registration-contract-cases.ts to include the missing provider IDs for google and qwen plugins.
  • Add a contract entry for google:google-vertex in src/plugins/contracts/registry.ts to resolve the provider contract entry missing error.
  • Verify the fixes by running the tests that currently fail, such as pnpm test extensions/google/plugin-registration.contract.test.ts and pnpm test src/plugins/contracts/providers.contract.test.ts.
  • Consider auditing the capability lists for google-vertex to ensure it is correctly configured.

Example

// Update the google case in plugin-registration-contract-cases.ts
google: {
  pluginId: "google",
  providerIds: ["google", "google-gemini-cli", "google-vertex"],
  // ...
},

Notes

The fixes assume that google-vertex is intended to be a part of the google plugin. If it's not, an alternative solution would be to pin the pi-ai version or filter the provider list.

Recommendation

Apply the workaround by updating the plugin-registration-contract-cases.ts file and adding a contract entry for google:google-vertex, as this will resolve the immediate test failures and allow for further development and testing.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix CI: plugin contract fixtures stale after `@mariozechner/pi-ai` 0.70.x added google-vertex / qwencloud / etc. [1 pull requests, 1 comments, 2 participants]