openclaw - ✅(Solved) Fix [Bug]: GPT-5 personality overlay silently skipped for aggregator providers (OpenRouter, OpenCode) [1 pull requests, 1 comments, 1 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#63076Fetched 2026-04-09 07:58:52
View on GitHub
Comments
1
Participants
1
Timeline
11
Reactions
0
Participants
Timeline (top)
referenced ×5mentioned ×2subscribed ×2commented ×1

The GPT-5 friendly personality overlay (interaction style, output contract, execution bias) only exists in the OpenAI provider extension. Aggregator providers like OpenRouter and OpenCode that also serve GPT-5 models have no resolveSystemPromptContribution hook registered, so the overlay is silently absent for GPT-5 models served through them.

Error Message

  • Severity: Medium (personality/interaction-style silently degraded, no error or warning)

Root Cause

The GPT-5 friendly personality overlay (interaction style, output contract, execution bias) only exists in the OpenAI provider extension. Aggregator providers like OpenRouter and OpenCode that also serve GPT-5 models have no resolveSystemPromptContribution hook registered, so the overlay is silently absent for GPT-5 models served through them.

Fix Action

Fix / Workaround

The core dispatch at src/plugins/provider-runtime.ts:238-241 resolves the hook by provider ID:

resolveProviderRuntimePlugin(params)?.resolveSystemPromptContribution?.(params.context) ?? undefined

PR fix notes

PR #63077: fix(providers): apply GPT-5 personality overlay for OpenRouter and OpenCode

Description (problem / solution / changelog)

Summary

  • Problem: GPT-5 personality overlay (interaction style, output contract, execution bias) is silently skipped when GPT-5 models are served through aggregator providers like OpenRouter or OpenCode.
  • Why it matters: Users running openrouter/openai/gpt-5.4 or opencode/gpt-5.4 get degraded responses compared to openai/gpt-5.4 with no warning or indication.
  • What changed: Added resolveSystemPromptContribution hook to both the OpenRouter and OpenCode provider extensions, with a GPT-5 model ID check that handles aggregator-prefixed model IDs by extracting the last path segment.
  • What did NOT change (scope boundary): extensions/openai/prompt-overlay.ts and extensions/openai/index.ts are untouched. No new SDK entrypoints, no package.json changes. The overlay constants are duplicated into each extension rather than promoted to a shared SDK path.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #63076
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: resolveSystemPromptContribution is a per-provider hook. The OpenAI plugin registers it for "openai" and "openai-codex" only. When provider is "openrouter" or "opencode", the OpenRouter/OpenCode plugins are resolved instead, and they had no resolveSystemPromptContribution hook registered. Additionally, shouldApplyOpenAIPromptOverlay hard-gates on OPENAI_PROVIDER_IDS which excludes aggregator provider IDs, and the model ID check uses startsWith("gpt-5") which fails for prefixed IDs like "openai/gpt-5.4".
  • Missing detection / guardrail: No test coverage for GPT-5 overlay behavior through aggregator providers.
  • Contributing context (if known): The overlay was designed when GPT-5 was only available through the direct OpenAI provider. Aggregator adoption grew without updating the overlay gating logic.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: extensions/openrouter/index.test.ts, extensions/opencode/index.test.ts
  • Scenario the test should lock in: resolveSystemPromptContribution returns the GPT-5 overlay for aggregator-prefixed model IDs (openai/gpt-5.4, openrouter/gpt-5.4, plain gpt-5.4) and returns undefined for non-GPT-5 models.
  • Why this is the smallest reliable guardrail: Tests the hook directly on the registered provider object without needing full agent/gateway setup.
  • Existing test that already covers this (if any): None for aggregator providers. Only extensions/openai/index.test.ts covers the direct OpenAI path.

User-visible / Behavior Changes

  • GPT-5 models served through OpenRouter and OpenCode now receive the same personality overlay (interaction style, output contract, execution bias) as models served directly through the OpenAI provider.
  • The overlay defaults to "friendly" (always on) for both providers since neither has a personality config key. This matches the OpenAI extension's default behavior.

Diagram (if applicable)

Before:
openrouter/openai/gpt-5.4 -> resolveProviderRuntimePlugin("openrouter")
  -> OpenRouter plugin (no resolveSystemPromptContribution) -> undefined

After:
openrouter/openai/gpt-5.4 -> resolveProviderRuntimePlugin("openrouter")
  -> OpenRouter plugin -> isGpt5ModelId("openai/gpt-5.4") -> true
  -> returns overlay (output contract + execution bias + interaction style)

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: macOS 15.4
  • Runtime/container: pnpm dev
  • Model/provider: openrouter/openai/gpt-5.4, opencode/gpt-5.4
  • Integration/channel (if any): N/A
  • Relevant config (redacted): N/A

Steps

  1. Set primary model to openrouter/openai/gpt-5.4.
  2. Send a message to the agent.
  3. Inspect system prompt for ## Interaction Style section.

Expected

  • System prompt contains ## Interaction Style, ## GPT-5 Output Contract, and ## Execution Bias sections.

Actual

  • Before fix: sections are missing.
  • After fix: sections are present.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

All tests pass:

  • extensions/openrouter/index.test.ts: 6 passed (3 existing + 3 new)
  • extensions/opencode/index.test.ts: 4 passed (2 existing + 2 new)
  • extensions/openai/index.test.ts: 11 passed (no regression)
  • Pre-commit hook (pnpm check): passed (lint, typecheck, conflict markers)

Human Verification (required)

  • Verified scenarios: Ran all three extension test suites, confirmed overlay is returned for GPT-5 model IDs in all aggregator formats and undefined for non-GPT-5 models.
  • Edge cases checked: openai/gpt-5.4 (sub-provider prefixed), openrouter/gpt-5.4 (native prefixed), gpt-5.4 (plain), anthropic/claude-sonnet-4-6 (non-GPT-5), gemini-2.5-pro (non-GPT-5).
  • What you did not verify: Full end-to-end with a live OpenRouter/OpenCode API key. Per-provider personality: off config (not yet supported for these providers).

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Risks and Mitigations

  • Risk: Overlay constants are duplicated across three extensions (openai, openrouter, opencode) and could drift.
    • Mitigation: A follow-up should promote the overlay to a shared openclaw/plugin-sdk/provider-prompt-overlay subpath. Comment in each extension points to the source of truth in extensions/openai/prompt-overlay.ts.
  • Risk: No per-provider personality: off config for OpenRouter/OpenCode — overlay is always on.
    • Mitigation: Defaults to "friendly" which matches OpenAI's default. A follow-up can add personality to each provider's config schema.

Changed files

  • extensions/opencode/index.test.ts (modified, +59/-0)
  • extensions/opencode/index.ts (modified, +91/-0)
  • extensions/opencode/openclaw.plugin.json (modified, +8/-1)
  • extensions/openrouter/index.test.ts (modified, +61/-0)
  • extensions/openrouter/index.ts (modified, +92/-0)
  • extensions/openrouter/openclaw.plugin.json (modified, +8/-1)

Code Example

resolveSystemPromptContribution: (ctx) =>
  resolveOpenAISystemPromptContribution({
    mode: promptOverlayMode,
    modelProviderId: provider.id,
    modelId: ctx.modelId,
  }),

---

resolveProviderRuntimePlugin(params)?.resolveSystemPromptContribution?.(params.context) ?? undefined
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

The GPT-5 friendly personality overlay (interaction style, output contract, execution bias) only exists in the OpenAI provider extension. Aggregator providers like OpenRouter and OpenCode that also serve GPT-5 models have no resolveSystemPromptContribution hook registered, so the overlay is silently absent for GPT-5 models served through them.

Steps to reproduce

  1. Configure OpenClaw with openrouter/openai/gpt-5.4 as the primary model.
  2. Send a message to the agent.
  3. Observe that the system prompt does not contain the ## Interaction Style, ## GPT-5 Output Contract, or ## Execution Bias sections.
  4. Switch to openai/gpt-5.4 as the primary model.
  5. Send a message — the overlay sections now appear in the system prompt.

Expected behavior

The GPT-5 personality overlay should apply to GPT-5 models regardless of which provider serves them. GPT-5 is GPT-5 whether it comes through OpenAI directly, OpenRouter, OpenCode, or any other aggregator.

Actual behavior

The overlay only exists in the OpenAI extension (extensions/openai/prompt-overlay.ts). The resolveSystemPromptContribution hook is per-provider — it only runs on the provider plugin matched by provider ID. Since the OpenRouter and OpenCode extensions never registered this hook, GPT-5 models served through them get no overlay at all.

The issue is not that the OpenAI extension blocks other providers — it is that the overlay was only ever implemented in the OpenAI extension and no other provider extension has it.

Relevant code:

  • extensions/openai/index.ts:29-34 — OpenAI registers resolveSystemPromptContribution
  • extensions/openrouter/index.ts:62-113 — OpenRouter provider registration, no resolveSystemPromptContribution
  • extensions/opencode/index.ts:29-66 — OpenCode provider registration, no resolveSystemPromptContribution
  • src/plugins/provider-runtime.ts:238-241resolveProviderSystemPromptContribution resolves the hook by provider ID

Additionally, if the overlay were naively copied, there is a secondary model ID format issue: for OpenRouter, modelId arrives as "openai/gpt-5.4" (not plain "gpt-5.4"), so a check using startsWith("gpt-5") would also fail without extracting the last path segment.

Model ID formats confirmed by src/agents/model-selection.test.ts:222-238:

Config valueprovidermodelId
openai/gpt-5.4"openai""gpt-5.4"
openrouter/openai/gpt-5.4"openrouter""openai/gpt-5.4"
openrouter/gpt-5.4"openrouter""openrouter/gpt-5.4"

OpenClaw version

2026.4.9

Operating system

macOS 15.4

Install method

pnpm dev

Model

openrouter/openai/gpt-5.4

Provider / routing chain

openclaw -> openrouter -> openai

Logs, screenshots, and evidence

OpenAI extension registers the hook at extensions/openai/index.ts:29-34:

resolveSystemPromptContribution: (ctx) =>
  resolveOpenAISystemPromptContribution({
    mode: promptOverlayMode,
    modelProviderId: provider.id,
    modelId: ctx.modelId,
  }),

OpenRouter extension (extensions/openrouter/index.ts:62-113) and OpenCode extension (extensions/opencode/index.ts:29-66) have no equivalent hook.

The core dispatch at src/plugins/provider-runtime.ts:238-241 resolves the hook by provider ID:

resolveProviderRuntimePlugin(params)?.resolveSystemPromptContribution?.(params.context) ?? undefined

When provider is "openrouter", the OpenRouter plugin is resolved — which has no resolveSystemPromptContribution — so undefined is returned.

Impact and severity

  • Affected: All users running GPT-5 models through OpenRouter, OpenCode, or any non-OpenAI aggregator provider
  • Severity: Medium (personality/interaction-style silently degraded, no error or warning)
  • Frequency: Always — every GPT-5 request through an aggregator
  • Consequence: GPT-5 personality overlay (interaction style, output contract, execution bias) is missing, resulting in less tailored responses compared to direct OpenAI provider usage

Additional information

A fix requires each aggregator provider extension to register its own resolveSystemPromptContribution hook with a GPT-5 model ID check that handles prefixed model IDs (extract last /-segment, check startsWith("gpt-5")). Long-term, the overlay constants and logic should be promoted to a shared plugin SDK subpath to avoid duplication across providers.

extent analysis

TL;DR

To fix the issue, each aggregator provider extension (e.g., OpenRouter, OpenCode) needs to register its own resolveSystemPromptContribution hook with a GPT-5 model ID check that handles prefixed model IDs.

Guidance

  • Identify the provider extensions that need to register the resolveSystemPromptContribution hook, such as OpenRouter and OpenCode.
  • In each provider extension, implement the resolveSystemPromptContribution hook to check if the model ID starts with "gpt-5" after extracting the last path segment.
  • Use the resolveOpenAISystemPromptContribution function as a reference to implement the hook in each provider extension.
  • Verify that the GPT-5 personality overlay is applied correctly for GPT-5 models served through each aggregator provider.

Example

// In extensions/openrouter/index.ts
resolveSystemPromptContribution: (ctx) => {
  const modelId = ctx.modelId.split('/').pop();
  if (modelId.startsWith('gpt-5')) {
    return resolveOpenAISystemPromptContribution({
      mode: promptOverlayMode,
      modelProviderId: provider.id,
      modelId: ctx.modelId,
    });
  }
  return undefined;
}

Notes

  • The fix requires modifying each aggregator provider extension to register the resolveSystemPromptContribution hook.
  • The long-term solution is to promote the overlay constants and logic to a shared plugin SDK subpath to avoid duplication across providers.

Recommendation

Apply workaround: Register the resolveSystemPromptContribution hook in each aggregator provider extension, as described in the guidance section. This will ensure that the GPT-5 personality overlay is applied correctly for GPT-5 models served through each aggregator provider.

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…

FAQ

Expected behavior

The GPT-5 personality overlay should apply to GPT-5 models regardless of which provider serves them. GPT-5 is GPT-5 whether it comes through OpenAI directly, OpenRouter, OpenCode, or any other aggregator.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING