Skip to content

Commit e8d005a

Browse files
committed
fix(sdk): preserve x-trigger-branch on override POSTs and handle Request input in SSE wrapper
When chat.createStartSessionAction was given a baseURL or fetch override, the inline POSTs for /api/v1/sessions and /api/v1/auth/jwt/claims forgot to forward apiClientManager.branchName as the x-trigger-branch header. Callers running against a preview branch (via TRIGGER_PREVIEW_BRANCH or VERCEL_GIT_COMMIT_REF) would route to the wrong environment in override mode. Extracted the header builder to a shared helper. The SSE fetch wrappers in TriggerChatTransport.subscribeToSessionStream and AgentChat.subscribeToSessionStream cast to typeof fetch but coerced non-string input via .toString(), which yields "[object Request]" on Request objects and discards the Request's intrinsic method/headers/ signal. Replaced the coercion with explicit branches for string, URL, and Request — Request inputs now extract url + init properly with any caller-provided init taking precedence (matches fetch(Request, init) semantics).
1 parent f21c318 commit e8d005a

3 files changed

Lines changed: 61 additions & 22 deletions

File tree

packages/trigger-sdk/src/v3/ai.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8648,6 +8648,22 @@ function resolveChatStartBaseURL(
86488648
return raw.replace(/\/$/, "");
86498649
}
86508650

8651+
function overrideRequestHeaders(accessToken: string): Record<string, string> {
8652+
const headers: Record<string, string> = {
8653+
"Content-Type": "application/json",
8654+
Authorization: `Bearer ${accessToken}`,
8655+
"x-trigger-source": "sdk",
8656+
};
8657+
// Forward the preview-branch hint so override-mode requests land on the
8658+
// same env the standard ApiClient path would have routed to. Mirrors
8659+
// ApiClient.#getHeaders. Read from TRIGGER_PREVIEW_BRANCH /
8660+
// VERCEL_GIT_COMMIT_REF via apiClientManager.branchName.
8661+
if (apiClientManager.branchName) {
8662+
headers["x-trigger-branch"] = apiClientManager.branchName;
8663+
}
8664+
return headers;
8665+
}
8666+
86518667
async function callSessionsCreateWithOverride(args: {
86528668
chatId: string;
86538669
body: { type: "chat.agent"; externalId: string; taskIdentifier: string; triggerConfig: SessionTriggerConfig; metadata?: Record<string, unknown> };
@@ -8664,11 +8680,7 @@ async function callSessionsCreateWithOverride(args: {
86648680
const url = `${resolveChatStartBaseURL("sessions", args.chatId, args.baseURLOption)}/api/v1/sessions`;
86658681
const init: RequestInit = {
86668682
method: "POST",
8667-
headers: {
8668-
"Content-Type": "application/json",
8669-
Authorization: `Bearer ${accessToken}`,
8670-
"x-trigger-source": "sdk",
8671-
},
8683+
headers: overrideRequestHeaders(accessToken),
86728684
body: JSON.stringify(args.body),
86738685
};
86748686
const response = args.fetchOverride
@@ -8698,11 +8710,7 @@ async function mintPublicTokenWithOverride(args: {
86988710
const url = `${resolveChatStartBaseURL("auth", args.chatId, args.baseURLOption)}/api/v1/auth/jwt/claims`;
86998711
const init: RequestInit = {
87008712
method: "POST",
8701-
headers: {
8702-
"Content-Type": "application/json",
8703-
Authorization: `Bearer ${accessToken}`,
8704-
"x-trigger-source": "sdk",
8705-
},
8713+
headers: overrideRequestHeaders(accessToken),
87068714
};
87078715
const response = args.fetchOverride
87088716
? await args.fetchOverride(url, init, ctx)

packages/trigger-sdk/src/v3/chat-client.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -683,13 +683,28 @@ export class AgentChat<TAgent = unknown> {
683683
const onTurnComplete = this.onTurnComplete;
684684
const chatId = this.chatId;
685685
const sseCtx: AgentChatEndpointContext = { endpoint: "out", chatId };
686-
const sseFetchClient: typeof fetch | undefined = this.fetchOverride
687-
? ((input, init) =>
688-
this.fetchOverride!(
689-
typeof input === "string" ? input : (input as URL | Request).toString(),
690-
init ?? {},
686+
const fetchOverride = this.fetchOverride;
687+
const sseFetchClient: typeof fetch | undefined = fetchOverride
688+
? ((input, init) => {
689+
if (typeof input === "string") {
690+
return fetchOverride(input, init ?? {}, sseCtx);
691+
}
692+
if (input instanceof URL) {
693+
return fetchOverride(input.toString(), init ?? {}, sseCtx);
694+
}
695+
// Request — preserve its url + intrinsic init, let any provided
696+
// init override on top (matches fetch(Request, init) semantics).
697+
return fetchOverride(
698+
input.url,
699+
{
700+
method: input.method,
701+
headers: input.headers,
702+
signal: input.signal,
703+
...(init ?? {}),
704+
},
691705
sseCtx
692-
)) as typeof fetch
706+
);
707+
}) as typeof fetch
693708
: undefined;
694709

695710
const internalAbort = new AbortController();

packages/trigger-sdk/src/v3/chat.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,13 +1191,29 @@ export class TriggerChatTransport implements ChatTransport<UIMessage> {
11911191
: () => {};
11921192

11931193
const sseCtx: ChatTransportEndpointContext = { endpoint: "out", chatId };
1194-
const sseFetchClient: typeof fetch | undefined = this.fetchOverride
1195-
? ((input, init) =>
1196-
this.fetchOverride!(
1197-
typeof input === "string" ? input : (input as URL | Request).toString(),
1198-
init ?? {},
1194+
const fetchOverride = this.fetchOverride;
1195+
const sseFetchClient: typeof fetch | undefined = fetchOverride
1196+
? ((input, init) => {
1197+
if (typeof input === "string") {
1198+
return fetchOverride(input, init ?? {}, sseCtx);
1199+
}
1200+
if (input instanceof URL) {
1201+
return fetchOverride(input.toString(), init ?? {}, sseCtx);
1202+
}
1203+
// Request — preserve its url + intrinsic init, let any
1204+
// provided init override on top (matches fetch(Request, init)
1205+
// semantics).
1206+
return fetchOverride(
1207+
input.url,
1208+
{
1209+
method: input.method,
1210+
headers: input.headers,
1211+
signal: input.signal,
1212+
...(init ?? {}),
1213+
},
11991214
sseCtx
1200-
)) as typeof fetch
1215+
);
1216+
}) as typeof fetch
12011217
: undefined;
12021218
const connectSseOnce = async (token: string) => {
12031219
const subscription = new SSEStreamSubscription(streamUrl, {

0 commit comments

Comments
 (0)