Merge PR #4153: fix(ai): reword GPT-5 Responses fallback prompt (@roboomp)
This commit is contained in:
@@ -13,6 +13,9 @@
|
||||
### Fixed
|
||||
|
||||
- Fixed Xiaomi MiMo standard API-key validation to use the supported `mimo-v2.5` model. ([#4063](https://github.com/can1357/oh-my-pi/issues/4063))
|
||||
### Fixed
|
||||
|
||||
- Reworded the GPT-5 Responses no-reasoning fallback developer item so it no longer says `# Juice: 0 !important` or implies a zero tool/execution budget. ([#4151](https://github.com/can1357/oh-my-pi/issues/4151))
|
||||
|
||||
## [16.2.12] - 2026-07-01
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Keep internal reasoning brief. Continue following the task and use tools normally.
|
||||
@@ -75,6 +75,7 @@ import {
|
||||
} from "./github-copilot-headers";
|
||||
import type { ChatCompletionCreateParamsStreaming } from "./openai-chat-wire";
|
||||
import type { InputItem } from "./openai-codex/request-transformer";
|
||||
import responsesReasoningSuppressionPrompt from "./openai-responses-reasoning-suppression.md" with { type: "text" };
|
||||
import type {
|
||||
ResponseContentPartAddedEvent,
|
||||
ResponseCreateParamsStreaming,
|
||||
@@ -2365,6 +2366,8 @@ export function applyCommonResponsesSamplingParams<P extends CommonResponsesPara
|
||||
applyOpenAIServiceTier(params, options?.serviceTier, model.provider);
|
||||
}
|
||||
|
||||
const RESPONSES_REASONING_SUPPRESSION_PROMPT = responsesReasoningSuppressionPrompt.trim();
|
||||
|
||||
type ReasoningOptions = {
|
||||
reasoning?: string;
|
||||
reasoningSummary?: "auto" | "detailed" | "concise" | null;
|
||||
@@ -2409,7 +2412,7 @@ export function applyResponsesCompatPolicy<P extends ResponseCreateParamsStreami
|
||||
if (policy.compat.requiresJuiceZeroHack && reasoning.requestedEffort === undefined) {
|
||||
messages.push({
|
||||
role: "developer",
|
||||
content: [{ type: "input_text", text: "# Juice: 0 !important" }],
|
||||
content: [{ type: "input_text", text: RESPONSES_REASONING_SUPPRESSION_PROMPT }],
|
||||
});
|
||||
return 1;
|
||||
}
|
||||
@@ -2441,7 +2444,7 @@ export function applyResponsesCompatPolicy<P extends ResponseCreateParamsStreami
|
||||
if (policy.compat.requiresJuiceZeroHack) {
|
||||
messages.push({
|
||||
role: "developer",
|
||||
content: [{ type: "input_text", text: "# Juice: 0 !important" }],
|
||||
content: [{ type: "input_text", text: RESPONSES_REASONING_SUPPRESSION_PROMPT }],
|
||||
});
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -154,7 +154,12 @@ describe("azure openai responses streaming", () => {
|
||||
{ role: "user", content: [{ type: "input_text", text: "Say hello" }] },
|
||||
{
|
||||
role: "developer",
|
||||
content: [{ type: "input_text", text: "# Juice: 0 !important" }],
|
||||
content: [
|
||||
{
|
||||
type: "input_text",
|
||||
text: "Keep internal reasoning brief. Continue following the task and use tools normally.",
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -123,6 +123,35 @@ describe("OpenAI compat policy", () => {
|
||||
expect(responseBody.reasoning).toBeUndefined();
|
||||
});
|
||||
|
||||
it("uses a non-budget fallback prompt for Responses no-reasoning compat", () => {
|
||||
const compat: OpenAICompat = { requiresJuiceZeroHack: true };
|
||||
const responseBody = responsesParams();
|
||||
const responseInput: ResponseInput = [];
|
||||
|
||||
const appended = applyResponsesCompatPolicy(
|
||||
responseBody,
|
||||
responseInput,
|
||||
resolveOpenAICompatPolicy(responsesModel(compat), { endpoint: "responses" }),
|
||||
undefined,
|
||||
);
|
||||
|
||||
expect(appended).toBe(1);
|
||||
expect(responseInput.at(-1)).toEqual({
|
||||
role: "developer",
|
||||
content: [
|
||||
{
|
||||
type: "input_text",
|
||||
text: "Keep internal reasoning brief. Continue following the task and use tools normally.",
|
||||
},
|
||||
],
|
||||
});
|
||||
const serialized = JSON.stringify(responseInput.at(-1));
|
||||
expect(serialized).not.toContain("Juice");
|
||||
expect(serialized).not.toContain("!important");
|
||||
expect(serialized).not.toContain("budget");
|
||||
expect(serialized).not.toContain("zero");
|
||||
});
|
||||
|
||||
it("exposes reasoning replay constraints independent of endpoint", () => {
|
||||
const compat: OpenAICompat = {
|
||||
requiresReasoningContentForToolCalls: true,
|
||||
|
||||
@@ -26,9 +26,9 @@ function createCodexToken(accountId: string): string {
|
||||
|
||||
/**
|
||||
* Returns the bundled `gpt-5-mini` model with `compat.requiresJuiceZeroHack`
|
||||
* cleared so it doesn't trigger the GPT-5 "Juice: 0" developer-message hack
|
||||
* injected by `applyResponsesReasoningParams`. The hack is exercised by its
|
||||
* own targeted tests; these history-replay tests assert raw payload shape and
|
||||
* cleared so it doesn't trigger the GPT-5 no-reasoning developer-message
|
||||
* fallback injected by `applyResponsesReasoningParams`. The fallback is
|
||||
* exercised by its own targeted tests; these history-replay tests assert raw payload shape and
|
||||
* should stay independent of it.
|
||||
*/
|
||||
function getOpenAIReasoningModel(
|
||||
|
||||
@@ -101,8 +101,8 @@ describe("openai-responses stateful chaining", () => {
|
||||
const sentRequests: Array<Record<string, unknown>> = [];
|
||||
const fetchMock = createCapturingFetch(sentRequests);
|
||||
const providerSessionState = new Map<string, ProviderSessionState>();
|
||||
// No reasoning option: applyResponsesReasoningParams appends the trailing
|
||||
// "# Juice: 0 !important" developer item to every request's input.
|
||||
// No reasoning option: applyResponsesReasoningParams appends trailing
|
||||
// no-reasoning scaffolding to every request's input.
|
||||
const options = {
|
||||
apiKey: "test-key",
|
||||
sessionId: "stateful-juice-session",
|
||||
@@ -119,7 +119,7 @@ describe("openai-responses stateful chaining", () => {
|
||||
).result();
|
||||
expect(firstResponse.stopReason).toBe("stop");
|
||||
const firstInput = sentRequests[0]?.input as unknown[];
|
||||
expect(JSON.stringify(firstInput.at(-1))).toContain("# Juice: 0");
|
||||
expect(JSON.stringify(firstInput.at(-1))).toContain("Keep internal reasoning brief");
|
||||
|
||||
const secondResponse = await streamOpenAIResponses(
|
||||
model,
|
||||
@@ -138,7 +138,7 @@ describe("openai-responses stateful chaining", () => {
|
||||
const deltaInput = sentRequests[1]?.input as Array<{ role?: string }>;
|
||||
expect(deltaInput).toHaveLength(2);
|
||||
expect(deltaInput[0]?.role).toBe("user");
|
||||
expect(JSON.stringify(deltaInput[1])).toContain("# Juice: 0");
|
||||
expect(JSON.stringify(deltaInput[1])).toContain("Keep internal reasoning brief");
|
||||
});
|
||||
|
||||
it("replays the full transcript when history mutates", async () => {
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
### Fixed
|
||||
|
||||
- Fixed the Xiaomi provider default model to use the supported `mimo-v2.5` model. ([#4063](https://github.com/can1357/oh-my-pi/issues/4063))
|
||||
### Fixed
|
||||
|
||||
- Updated the Responses compat flag docs to describe the no-reasoning fallback without the old `# Juice: 0 !important` wording. ([#4151](https://github.com/can1357/oh-my-pi/issues/4151))
|
||||
|
||||
## [16.2.12] - 2026-07-01
|
||||
|
||||
|
||||
@@ -332,11 +332,11 @@ export interface OpenAICompat {
|
||||
/** Whether the Responses API accepts the `detail: "original"` image hint. Default: auto-detected (false for GitHub Copilot, which rejects it with a 400). */
|
||||
supportsImageDetailOriginal?: boolean;
|
||||
/**
|
||||
* Append a trailing `# Juice: 0 !important` developer item when the caller
|
||||
* did not request reasoning, suppressing default reasoning on models that
|
||||
* cannot disable it via request params (Responses APIs only; see
|
||||
* Append a trailing no-reasoning developer item when the caller did not
|
||||
* request reasoning, suppressing default reasoning on models that cannot
|
||||
* disable it via request params (Responses APIs only; see
|
||||
* https://community.openai.com/t/need-reasoning-false-option-for-gpt-5/1351588/7).
|
||||
* Default: auto-detected (GPT-5-family model names).
|
||||
* The prompt must not look like an execution or tool budget. Default: auto-detected (GPT-5-family model names).
|
||||
*/
|
||||
requiresJuiceZeroHack?: boolean;
|
||||
/** Whether streamed reasoning deltas for the same field may repeat the full cumulative text snapshot. Default: false. */
|
||||
|
||||
Reference in New Issue
Block a user