Skip to content

Commit a736fa9

Browse files
Normalize baseURL once for trigger and stream endpoints
Co-authored-by: Eric Allam <eric@trigger.dev>
1 parent c12315f commit a736fa9

File tree

2 files changed

+68
-3
lines changed

2 files changed

+68
-3
lines changed

packages/ai/src/chatTransport.test.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,68 @@ describe("TriggerChatTransport", function () {
273273
expect(observedStreamPath).toBe("/realtime/v1/streams/run_trailing_baseurl/chat-stream");
274274
});
275275

276+
it("normalizes repeated trailing slashes in baseURL for stream URLs", async function () {
277+
let observedStreamPath: string | undefined;
278+
279+
const server = await startServer(function (req, res) {
280+
if (req.method === "POST" && req.url === "/api/v1/tasks/chat-task/trigger") {
281+
res.writeHead(200, {
282+
"content-type": "application/json",
283+
"x-trigger-jwt": "pk_run_multi_trailing_baseurl",
284+
});
285+
res.end(JSON.stringify({ id: "run_multi_trailing_baseurl" }));
286+
return;
287+
}
288+
289+
if (req.method === "GET") {
290+
observedStreamPath = req.url ?? "";
291+
}
292+
293+
if (
294+
req.method === "GET" &&
295+
req.url === "/realtime/v1/streams/run_multi_trailing_baseurl/chat-stream"
296+
) {
297+
res.writeHead(200, {
298+
"content-type": "text/event-stream",
299+
});
300+
writeSSE(
301+
res,
302+
"1-0",
303+
JSON.stringify({ type: "text-start", id: "multi_trailing_1" })
304+
);
305+
writeSSE(
306+
res,
307+
"2-0",
308+
JSON.stringify({ type: "text-end", id: "multi_trailing_1" })
309+
);
310+
res.end();
311+
return;
312+
}
313+
314+
res.writeHead(404);
315+
res.end();
316+
});
317+
318+
const transport = new TriggerChatTransport({
319+
task: "chat-task",
320+
accessToken: "pk_trigger",
321+
baseURL: `${server.url}///`,
322+
stream: "chat-stream",
323+
});
324+
325+
const stream = await transport.sendMessages({
326+
trigger: "submit-message",
327+
chatId: "chat-multi-trailing-baseurl",
328+
messageId: undefined,
329+
messages: [],
330+
abortSignal: undefined,
331+
});
332+
333+
const chunks = await readChunks(stream);
334+
expect(chunks).toHaveLength(2);
335+
expect(observedStreamPath).toBe("/realtime/v1/streams/run_multi_trailing_baseurl/chat-stream");
336+
});
337+
276338
it("supports baseURL path prefixes for trigger and stream routes", async function () {
277339
let observedTriggerPath: string | undefined;
278340
let observedStreamPath: string | undefined;

packages/ai/src/chatTransport.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ export class TriggerChatTransport<
145145
this.payloadMapper = resolvePayloadMapper<UI_MESSAGE, PAYLOAD>(options.payloadMapper);
146146
this.triggerOptions = options.triggerOptions;
147147
this.runStore = options.runStore ?? new InMemoryTriggerChatRunStore();
148-
this.baseURL = options.baseURL ?? "https://api.trigger.dev";
148+
this.baseURL = normalizeBaseUrl(options.baseURL ?? "https://api.trigger.dev");
149149
this.previewBranch = options.previewBranch;
150150
this.requestOptions = options.requestOptions;
151151
this.triggerClient = new ApiClient(
@@ -374,11 +374,10 @@ export class TriggerChatTransport<
374374
}
375375

376376
private createStreamUrl(runId: string, streamKey: string): string {
377-
const normalizedBaseUrl = this.baseURL.replace(/\/$/, "");
378377
const encodedRunId = encodeURIComponent(runId);
379378
const encodedStreamKey = encodeURIComponent(streamKey);
380379

381-
return `${normalizedBaseUrl}/realtime/v1/streams/${encodedRunId}/${encodedStreamKey}`;
380+
return `${this.baseURL}/realtime/v1/streams/${encodedRunId}/${encodedStreamKey}`;
382381
}
383382

384383
private async markRunInactiveAndDelete(runState: TriggerChatRunState) {
@@ -460,6 +459,10 @@ function resolvePayloadMapper<
460459
return createDefaultPayload as TriggerChatPayloadMapper<UI_MESSAGE, PAYLOAD>;
461460
}
462461

462+
function normalizeBaseUrl(baseURL: string) {
463+
return baseURL.replace(/\/+$/, "");
464+
}
465+
463466
function createTransportRequest<UI_MESSAGE extends UIMessage>(
464467
options: TriggerChatSendMessagesOptions<UI_MESSAGE>
465468
): TriggerChatTransportRequest<UI_MESSAGE> {

0 commit comments

Comments
 (0)