Skip to content

agents: add OpenAI/Codex tool compatibility and replay/liveness state#64300

Merged
steipete merged 14 commits intoopenclaw:mainfrom
electricsheephq:feat/openai-codex-tool-compat
Apr 11, 2026
Merged

agents: add OpenAI/Codex tool compatibility and replay/liveness state#64300
steipete merged 14 commits intoopenclaw:mainfrom
electricsheephq:feat/openai-codex-tool-compat

Conversation

@100yenadmin
Copy link
Copy Markdown
Contributor

@100yenadmin 100yenadmin commented Apr 10, 2026

Summary

  • keep the provider-owned OpenAI/Codex tool-compat layer via the existing provider hook surface
  • add replay/liveness state surfacing so long-running embedded runs stop disappearing silently
  • compact the original Contracts 2 and 5 into one execution-correctness PR in the GPT-5.4 / Codex parity program tracked by GPT-5.4 / Codex agentic runtime parity in OpenClaw #64227

Scope

What changed

  • add an openai tool-compat family to buildProviderToolCompatFamilyHooks(...)
  • gate the family to native OpenAI/OpenAI Codex response routes only
  • normalize provider-owned parameter-free and missing-object-shape tool schemas for strict OpenAI/Codex routes
  • surface provider-owned diagnostics for remaining strict-schema incompatibilities
  • attach the compat hooks in extensions/openai/index.ts so OpenAI and OpenAI Codex providers both expose them
  • add replay/liveness state to embedded run results and lifecycle surfaces
  • classify replay/liveness outcomes as observable working, paused, blocked, or abandoned states instead of silent disappearance
  • preserve replay-invalid truth across compaction retries after mutating tool side effects
  • add focused regressions for replay/liveness surfacing alongside the existing tool-compat coverage

Validation

  • pnpm build
  • CI=1 pnpm exec vitest run src/agents/pi-embedded-subscribe.handlers.lifecycle.test.ts src/agents/pi-embedded-subscribe.handlers.compaction.test.ts src/agents/pi-embedded-subscribe.handlers.tools.test.ts src/agents/pi-embedded-runner/run/attempt.spawn-workspace.test.ts src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.subscribeembeddedpisession.test.ts

Non-goals

Copy link
Copy Markdown
Contributor Author

@steipete @vincentkoc PR3 for #64230 is live and intentionally narrow: provider-owned OpenAI/Codex tool compatibility only, with no generic-runner dialect, auth, permission, or replay scope mixed in.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2363afa4de

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/plugin-sdk/provider-tools.ts
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 10, 2026

Greptile Summary

This PR adds an "openai" family to buildProviderToolCompatFamilyHooks in src/plugin-sdk/provider-tools.ts and wires the resulting hooks into both the OpenAI and Codex providers in extensions/openai/index.ts. It correctly normalizes empty-parameter tool schemas and emits strict-schema diagnostics for remaining incompatibilities, gated to native OpenAI/Codex response routes only.

  • P1 — normalizeOpenAIStrictCompatSchemaRecursive corrupts properties: {} maps: The generic recursive descent passes every object value through itself, including the properties map. An empty {} map triggers the "missing params" guard at line 237 and is expanded into a full schema object, changing the API payload for any tool defined with an explicit parameters: { type: \"object\", properties: {} }. The fix is to handle the properties key specially (iterate property schemas by name, not the container), matching what stripUnsupportedSchemaKeywords already does.

Confidence Score: 4/5

Safe to merge after fixing the recursive normalization bug that corrupts explicit empty properties maps.

One P1 correctness bug: the recursive normalizer incorrectly expands any empty {} it encounters, which corrupts the properties: {} container in tool schemas before they are sent to the API. The common parameters: {} and parameters: { type: "object" } inputs work correctly and are covered by tests, but the explicit properties: {} case is untested and broken. All other logic — route gating, violation reporting, Codex/OpenAI routing, hook wiring — looks correct.

src/plugin-sdk/provider-tools.ts — the normalizeOpenAIStrictCompatSchemaRecursive function needs special-case handling for the properties key, matching the pattern used in stripUnsupportedSchemaKeywords.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/plugin-sdk/provider-tools.ts
Line: 231-244

Comment:
**Empty-object guard corrupts the properties map**

The generic recursive descent calls `normalizeOpenAIStrictCompatSchemaRecursive(value)` for every entry in the record. When the entry is `properties: {}`, the value `{}` is an empty object and triggers the guard at line 237, turning the property-name map into a full JSON Schema `{ type: "object", ... }`. A tool with `parameters: { type: "object", properties: {} }` would therefore have its `properties` field corrupted before the API call.

The fix is to handle the `properties` key specially — iterate its sub-keys and normalize each property schema individually, not the container map itself. This is exactly how `stripUnsupportedSchemaKeywords` treats the same key. Adding a test for the `{ type: "object", properties: {} }` input would catch this regression.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "agents: add openai provider-owned tool c..." | Re-trigger Greptile

Comment thread src/plugin-sdk/provider-tools.ts
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a provider-owned tool-schema compatibility layer for OpenAI/Codex native Responses routes, enabling stricter schema compliance without introducing a generic-runner Codex dialect.

Changes:

  • Introduces an openai compat family with native-route gating, schema normalization for parameter-free/missing-object-shape cases, and strict-schema diagnostics.
  • Registers the compat hooks in the bundled OpenAI plugin so both openai and openai-codex providers expose them.
  • Adds focused unit tests covering normalization, diagnostics, bypass on non-native routes, and plugin registration.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/plugin-sdk/provider-tools.ts Implements OpenAI/Codex strict-tool schema normalization + violation inspection; adds openai compat family hooks.
src/plugin-sdk/provider-tools.test.ts Adds unit coverage for OpenAI compat family behavior (normalize/inspect, bypass, diagnostics).
extensions/openai/index.ts Wires provider-owned tool compat hooks into bundled OpenAI + Codex provider registrations.
extensions/openai/index.test.ts Verifies OpenAI plugin registers and exposes the tool compat hooks for both providers.

Comment thread src/plugin-sdk/provider-tools.ts Outdated
Copy link
Copy Markdown
Contributor Author

Pushed a minimal follow-up on d733bee4 to align the curated provider-family inventory with the new OpenAI tool-compat hook.

Scope stays narrow to #64230:

  • adds toolCompatFamilies: ["openai"] to the curated openai shared-family expectation
  • no new compat behavior, no alias bridge, no generic runner changes

I also re-derived the actual shared-family assignment inventory from source before pushing so this stays a contract-alignment fix rather than a speculative patch. This should be ready for maintainer review once GitHub checks refresh on the new head.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5372ced11e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/plugin-sdk/provider-tools.ts
@100yenadmin 100yenadmin force-pushed the feat/openai-codex-tool-compat branch from 5372ced to 7a5fc23 Compare April 10, 2026 14:18
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7a5fc2307b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/plugin-sdk/provider-tools.ts
Comment thread src/plugin-sdk/provider-tools.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 26a3a495be

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/plugin-sdk/provider-tools.ts
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a provider-owned tool-schema compatibility layer for native OpenAI Responses and OpenAI Codex Responses routes, implemented via the existing provider hook surface (no generic runner dialect changes).

Changes:

  • Introduces an openai tool-compat family with schema normalization and strict-schema diagnostics.
  • Registers the new compat hooks in the bundled OpenAI provider plugin so both openai and openai-codex expose them.
  • Adds targeted unit tests covering normalization behavior, bypass conditions, diagnostics, and plugin registration.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/plugin-sdk/provider-tools.ts Adds OpenAI/Codex compat gating, strict-schema normalization helpers, and violation inspection; extends the compat family matrix.
src/plugin-sdk/provider-tools.test.ts Adds unit tests for the new openai compat family normalization + diagnostics behavior.
extensions/openai/index.ts Wires openai tool-compat hooks into both OpenAI and Codex provider registrations.
extensions/openai/index.test.ts Adds a plugin-boundary test asserting OpenAI/Codex providers expose the compat hooks.

Comment thread src/plugin-sdk/provider-tools.ts Outdated
Comment thread extensions/openai/index.ts
@100yenadmin 100yenadmin force-pushed the feat/openai-codex-tool-compat branch from 26a3a49 to 9c81e58 Compare April 10, 2026 17:57
@openclaw-barnacle openclaw-barnacle Bot added the agents Agent runtime and tooling label Apr 10, 2026
@100yenadmin 100yenadmin changed the title agents: add OpenAI/Codex provider-owned tool compatibility agents: add OpenAI/Codex tool compatibility and replay/liveness state Apr 10, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9c81e58df6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/pi-embedded-subscribe.handlers.compaction.ts Outdated
Comment thread src/agents/pi-embedded-subscribe.handlers.lifecycle.ts Outdated
Copy link
Copy Markdown
Contributor Author

Addressed the current execution-correctness review pass on this branch.

This push:

  • treats missing parameters as an empty strict object schema for OpenAI/Codex parameter-free tools
  • preserves root-object strictness checks when the root schema is an array or primitive
  • updates the provider-family contract expectation for the new OpenAI tool-compat family
  • preserves paused liveness state when compaction ends in an aborted state
  • propagates final replayInvalid / liveness metadata from the runner outcome back into lifecycle state

Local validation:

  • pnpm build passed

I also retried focused vitest locally, but the linked-worktree run still fails before loading tests with the existing test/vitest/test/non-isolated-runner.ts module-resolution issue. Because that fails before test execution, I’m using CI as the source of truth for the actual branch logic here.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1f501b4461

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/pi-embedded-runner/run.ts
@100yenadmin 100yenadmin force-pushed the feat/openai-codex-tool-compat branch from 1f501b4 to 7f8a3bc Compare April 10, 2026 18:45
Copy link
Copy Markdown
Contributor Author

Rebased this branch onto current main and folded the execution-correctness fixes into the updated upstream lifecycle shape.

What changed in the latest push:

  • resolved the merge-conflict on the rebased branch without widening scope
  • kept the strict OpenAI/Codex parameter-free schema handling and root-object enforcement
  • preserved paused state on aborted compaction
  • propagated terminal replayInvalid / liveness metadata into lifecycle end/error emission
  • set terminal lifecycle metadata before the prompt-error early returns that immediately return blocked errors

Local validation after the rebase:

  • pnpm build

Focused linked-worktree vitest is still unreliable here because of the existing test/vitest/test/non-isolated-runner.ts resolution issue before test execution, so CI remains the source of truth for branch-level test results.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7f8a3bc64a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/pi-embedded-runner/run.ts
Comment thread src/agents/pi-embedded-runner/run.ts Outdated
Copy link
Copy Markdown
Contributor Author

Addressed the rebase fallout on this branch and pushed follow-up commit c0acf1b08e.

What changed:

  • restored type-safe handling for the legacy browser SSRF allowPrivateNetwork alias so the rebased branch compiles cleanly against current main
  • added the new setTerminalLifecycleMeta noop to the spawn-workspace subscription mocks
  • updated the lifecycle test to exercise the intended working -> blocked terminal-error path instead of assuming blocked-by-default

Local validation on the new head:

  • pnpm build
  • CI=1 pnpm exec vitest run src/agents/pi-embedded-subscribe.handlers.lifecycle.test.ts src/agents/pi-embedded-subscribe.handlers.compaction.test.ts src/agents/pi-embedded-runner/run/attempt.spawn-workspace.test.ts

GitHub is rerunning CI on the new head now.

@steipete steipete force-pushed the feat/openai-codex-tool-compat branch from 3f684ed to f2bb4ca Compare April 11, 2026 00:27
@steipete steipete merged commit 5c0d1c6 into openclaw:main Apr 11, 2026
9 checks passed
@steipete
Copy link
Copy Markdown
Contributor

Landed via rebase merge. Thanks @100yenadmin.

Source tip before merge: f2bb4ca
Landed tip: 5c0d1c6

Local validation before merge:

  • pnpm test src/plugin-sdk/provider-tools.test.ts src/agents/pi-embedded-subscribe.handlers.lifecycle.test.ts src/agents/pi-embedded-subscribe.handlers.tools.test.ts src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.subscribeembeddedpisession.test.ts src/agents/pi-embedded-runner/run.overflow-compaction.test.ts src/agents/pi-embedded-runner/run.incomplete-turn.test.ts src/agents/pi-embedded-runner/run.timeout-triggered-compaction.test.ts extensions/browser/src/browser/config.test.ts
  • pnpm check

Merged without waiting for fresh CI per maintainer request.

@steipete
Copy link
Copy Markdown
Contributor

Follow-up landed on main after the PR branch became non-modifiable from this checkout.

  • Follow-up commit: 07edaff
  • Verified: pnpm test src/agents/pi-embedded-subscribe.handlers.lifecycle.test.ts src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.subscribeembeddedpisession.test.ts src/agents/pi-embedded-runner/run.incomplete-turn.test.ts src/agents/pi-embedded-runner/run.overflow-compaction.test.ts
  • Earlier full local test passed with OPENCLAW_TEST_PROJECTS_PARALLEL=2 pnpm test before the final main rebase. Current origin/main has unrelated tsgo/plugin SDK declaration failures outside this PR's final diff.

Thanks @100yenadmin.

100yenadmin pushed a commit to electricsheephq/openclaw-local-test that referenced this pull request Apr 11, 2026
…i + pruning-defaults)

Fixes three inherited failures that are red on every recent main commit
since PR B (openclaw#64439) and PR C (openclaw#64300) landed. Each failure is a stale
test surface that a production change forgot to update.

1) target-resolver.test.ts is mocking plugins/runtime.js with only
   getActivePluginChannelRegistryVersion. After src/channels/registry.ts
   started calling getActivePluginChannelRegistry + getActivePluginRegistry
   through listRegisteredChannelPluginEntries(), every resolveMessagingTarget
   test that reaches normalizeTargetForProvider fails with
   'No getActivePluginChannelRegistry export is defined on the
   ../../plugins/runtime.js mock'. Adds both exports to the mock factory
   with a registry seeded from the channels the test cases actually use
   (discord, imessage, mattermost, slack, telegram) so normalizeAnyChannelId
   resolves them the way real runtime would.

2) memory-wiki/index.test.ts expects 16 gateway methods, but
   src/gateway.ts now registers 19 after wiki.importRuns, wiki.importInsights,
   and wiki.palace were added between wiki.status and wiki.init. Extends
   the expected list to match the real registration order.

3) test/extension-test-boundary.test.ts flags
   src/config/config.pruning-defaults.test.ts as a core test that deep-imports
   extensions/anthropic/provider-policy-api.js, which violates the
   extension-test-boundary rule. Moves the test to
   extensions/anthropic/config-pruning-defaults.test.ts with inferred types
   from applyAnthropicConfigDefaults's parameter/return shape, matching the
   pattern used by the sibling provider-policy-api.test.ts.

Local validation:
- pnpm test src/infra/outbound/target-resolver.test.ts
- pnpm test extensions/memory-wiki/index.test.ts
- pnpm test extensions/anthropic/config-pruning-defaults.test.ts
- pnpm test test/extension-test-boundary.test.ts

Refs openclaw#64227
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants