Unverified 提交 9085b531 authored 作者: Will Chen's avatar Will Chen 提交者: GitHub

Propagate request id properly for OpenAI Response API model (e.g. GPT 5.2) (#2876)

## Summary - Improve compaction prompt/provider option handling in IPC handlers - Tighten local agent tool option passing and argument defaults - Align LLM engine provider option generation across related paths ## Test plan - npm run fmt - npm run lint:fix - npm run ts 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- devin-review-badge-begin --> --- <a href="https://app.devin.ai/review/dyad-sh/dyad/pull/2876" target="_blank"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1"> <img src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1" alt="Open with Devin"> </picture> </a> <!-- devin-review-badge-end -->
上级 28bc0c04
......@@ -254,6 +254,7 @@ vi.mock("@/ipc/utils/token_utils", () => ({
vi.mock("@/ipc/utils/provider_options", () => ({
getProviderOptions: vi.fn(() => ({})),
getAiHeaders: vi.fn(() => ({})),
DYAD_INTERNAL_REQUEST_ID_HEADER: "x-dyad-internal-request-id",
}));
vi.mock("@/ipc/utils/mcp_manager", () => ({
......
......@@ -24,7 +24,11 @@ import {
type CompactionMessage,
} from "./compaction_storage";
import { getPostCompactionMessages } from "./compaction_utils";
import { getProviderOptions, getAiHeaders } from "@/ipc/utils/provider_options";
import {
getProviderOptions,
getAiHeaders,
DYAD_INTERNAL_REQUEST_ID_HEADER,
} from "@/ipc/utils/provider_options";
import { escapeXmlContent } from "../../../../shared/xmlEscape";
const logger = log.scope("compaction_handler");
......@@ -174,9 +178,12 @@ export async function performCompaction(
const summaryResult = streamText({
model: modelClient.model,
headers: getAiHeaders({
headers: {
...getAiHeaders({
builtinProviderId: modelClient.builtinProviderId,
}),
[DYAD_INTERNAL_REQUEST_ID_HEADER]: dyadRequestId,
},
providerOptions: getProviderOptions({
dyadAppId: 0,
dyadRequestId,
......
......@@ -8,6 +8,7 @@ import {
import log from "electron-log";
import { getExtraProviderOptions } from "./thinking_utils";
import { DYAD_INTERNAL_REQUEST_ID_HEADER } from "./provider_options";
import type { UserSettings } from "../../lib/schemas";
import type { LanguageModel } from "ai";
......@@ -118,6 +119,7 @@ export function createDyadEngine(
...JSON.parse(init.body),
...getExtraProviderOptions(providerId, options.settings),
};
const dyadVersionedFiles = parsedBody.dyadVersionedFiles;
if ("dyadVersionedFiles" in parsedBody) {
delete parsedBody.dyadVersionedFiles;
......@@ -126,7 +128,14 @@ export function createDyadEngine(
if ("dyadFiles" in parsedBody) {
delete parsedBody.dyadFiles;
}
const requestId = parsedBody.dyadRequestId;
// Read from body (OpenAICompatible models spread providerOptions into
// the body) with a fallback to an internal header (OpenAIResponses
// models don't forward providerOptions, so we pass it via header).
const requestId =
parsedBody.dyadRequestId ??
(init.headers as Record<string, string> | undefined)?.[
DYAD_INTERNAL_REQUEST_ID_HEADER
];
if ("dyadRequestId" in parsedBody) {
delete parsedBody.dyadRequestId;
}
......@@ -173,10 +182,12 @@ export function createDyadEngine(
}
// Return modified request with files included and requestId in headers
const { [DYAD_INTERNAL_REQUEST_ID_HEADER]: _, ...outgoingHeaders } =
(init.headers as Record<string, string>) ?? {};
const modifiedInit = {
...init,
headers: {
...init.headers,
...outgoingHeaders,
...(modifiedRequestId && {
"X-Dyad-Request-Id": modifiedRequestId,
}),
......
......@@ -86,6 +86,11 @@ export function getProviderOptions({
return providerOptions;
}
// Header used to pass the request ID through AI SDK models that don't forward
// providerOptions into the request body (e.g. OpenAIResponsesLanguageModel).
export const DYAD_INTERNAL_REQUEST_ID_HEADER =
"x-dyad-internal-request-id" as const;
export interface GetAiHeadersParams {
builtinProviderId: string | undefined;
}
......
......@@ -24,7 +24,11 @@ import { getDyadAppPath } from "@/paths/paths";
import { getModelClient } from "@/ipc/utils/get_model_client";
import { safeSend } from "@/ipc/utils/safe_sender";
import { getMaxTokens, getTemperature } from "@/ipc/utils/token_utils";
import { getProviderOptions, getAiHeaders } from "@/ipc/utils/provider_options";
import {
getProviderOptions,
getAiHeaders,
DYAD_INTERNAL_REQUEST_ID_HEADER,
} from "@/ipc/utils/provider_options";
import {
AgentToolName,
......@@ -649,9 +653,12 @@ export async function handleLocalAgentStream(
try {
const streamResult = streamText({
model: modelClient.model,
headers: getAiHeaders({
headers: {
...getAiHeaders({
builtinProviderId: modelClient.builtinProviderId,
}),
[DYAD_INTERNAL_REQUEST_ID_HEADER]: dyadRequestId,
},
providerOptions: getProviderOptions({
dyadAppId: chat.app.id,
dyadRequestId,
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论