fix(openai): normalize prompt overlay personality config

This commit is contained in:
Vincent Koc
2026-04-06 17:24:09 +01:00
parent 6dc3e1f770
commit e7fe087677
5 changed files with 66 additions and 3 deletions

View File

@@ -41,6 +41,7 @@ Docs: https://docs.openclaw.ai
- Providers/Google: recognize Gemma model ids in native Google forward-compat resolution, keep the requested provider when cloning fallback templates, and force Gemma reasoning off so Gemma 4 routes stop failing through the Google catalog fallback. (#61507) Thanks @eyjohn.
- Providers/Anthropic: skip `service_tier` injection for OAuth-authenticated stream wrapper requests so Claude OAuth requests stop failing with HTTP 401. (#60356) thanks @openperf.
- Providers/OpenAI: keep WebSocket text buffered until a real assistant phase arrives, even when text deltas land before a phaseless `output_item.added` announcement. (#61954) Thanks @100yenadmin.
- Providers/OpenAI: accept case-insensitive `plugins.entries.openai.config.personality` values, keep unknown overrides on the friendly overlay path, and add `on` as an alias for `friendly`. Thanks @vincentkoc.
- Discord/thread titles: stop forcing a hardcoded temperature for generated auto-thread names so Codex-backed thread title generation works on `openai-codex/*` models again. (#59525)
- Agents/message tool: add a `read` plus `threadId` discoverability hint when the configured channel actions support threaded message reads.
- Agents/context overflow: combine oversized and aggregate tool-result recovery in one repair pass, and restore a total-context overflow backstop during tool loops so recoverable sessions retry instead of failing early. (#61651) Thanks @Takhoffman.
@@ -56,6 +57,7 @@ Docs: https://docs.openclaw.ai
- Docs/i18n: relocalize final localized-page links after translation so generated locale pages stop keeping stale English-root links when targets appear later in the same run. (#61796) thanks @hxy91819.
- Docs/i18n: remove the zh-CN homepage redirect override so Mintlify can resolve the localized Chinese homepage without self-redirecting `/zh-CN/index`.
- Tools/web_fetch and web_search: fix `TypeError: fetch failed` caused by undici 8.0 enabling HTTP/2 by default; pinned SSRF-guard dispatchers now explicitly set `allowH2: false` to restore HTTP/1.1 behavior and keep the custom DNS-pinning lookup compatible. (#61738, #61777) Thanks @zozo123.
## 2026.4.5
### Breaking

View File

@@ -28,6 +28,7 @@ Config key:
Allowed values:
- `"friendly"`: default; enable the OpenAI-specific overlay.
- `"on"`: alias for `"friendly"`.
- `"off"`: disable the overlay and use the base OpenClaw prompt only.
Scope:
@@ -77,6 +78,9 @@ You can also set it directly with the config CLI:
openclaw config set plugins.entries.openai.config.personality off
```
OpenClaw normalizes this setting case-insensitively at runtime, so values like
`"Off"` still disable the friendly overlay.
## Option A: OpenAI API key (OpenAI Platform)
**Best for:** direct API access and usage-based billing.

View File

@@ -387,6 +387,32 @@ describe("openai plugin", () => {
});
});
it("treats mixed-case off values as disabling the friendly prompt overlay", async () => {
const { providers } = await registerOpenAIPluginWithHook({
pluginConfig: { personality: "Off" },
});
const openaiProvider = requireRegisteredProvider(providers, "openai");
expect(
openaiProvider.resolveSystemPromptContribution?.({
config: undefined,
agentDir: undefined,
workspaceDir: undefined,
provider: "openai",
modelId: "gpt-5.4",
promptMode: "full",
runtimeChannel: undefined,
runtimeCapabilities: undefined,
agentId: undefined,
}),
).toEqual({
stablePrefix: OPENAI_GPT5_OUTPUT_CONTRACT,
sectionOverrides: {
execution_bias: OPENAI_GPT5_EXECUTION_BIAS,
},
});
});
it("supports explicitly configuring the friendly prompt overlay", async () => {
const { on, providers } = await registerOpenAIPluginWithHook({
pluginConfig: { personality: "friendly" },
@@ -414,4 +440,31 @@ describe("openai plugin", () => {
},
});
});
it("treats on as an alias for the friendly prompt overlay", async () => {
const { providers } = await registerOpenAIPluginWithHook({
pluginConfig: { personality: "on" },
});
const openaiProvider = requireRegisteredProvider(providers, "openai");
expect(
openaiProvider.resolveSystemPromptContribution?.({
config: undefined,
agentDir: undefined,
workspaceDir: undefined,
provider: "openai",
modelId: "gpt-5.4",
promptMode: "full",
runtimeChannel: undefined,
runtimeCapabilities: undefined,
agentId: undefined,
}),
).toEqual({
stablePrefix: OPENAI_GPT5_OUTPUT_CONTRACT,
sectionOverrides: {
interaction_style: OPENAI_FRIENDLY_PROMPT_OVERLAY,
execution_bias: OPENAI_GPT5_EXECUTION_BIAS,
},
});
});
});

View File

@@ -49,9 +49,9 @@
"properties": {
"personality": {
"type": "string",
"enum": ["friendly", "off"],
"enum": ["friendly", "on", "off"],
"default": "friendly",
"description": "Controls the default OpenAI-specific personality used for OpenAI and OpenAI Codex runs."
"description": "Controls the default OpenAI-specific personality used for OpenAI and OpenAI Codex runs. `friendly` and `on` enable the overlay; `off` disables it."
}
}
}

View File

@@ -54,7 +54,11 @@ export type OpenAIPromptOverlayMode = "friendly" | "off";
export function resolveOpenAIPromptOverlayMode(
pluginConfig?: Record<string, unknown>,
): OpenAIPromptOverlayMode {
return pluginConfig?.personality === "off" ? "off" : "friendly";
const normalized =
typeof pluginConfig?.personality === "string"
? pluginConfig.personality.trim().toLowerCase()
: "";
return normalized === "off" ? "off" : "friendly";
}
export function shouldApplyOpenAIPromptOverlay(params: {