63 lines
1.9 KiB
TypeScript
63 lines
1.9 KiB
TypeScript
"use client";
|
|
|
|
import { Client as LangGraphClient } from "@langchain/langgraph-sdk/client";
|
|
|
|
import { getAuthorizationHeaderValue } from "../auth";
|
|
import { getCanvasLangGraphBaseURL } from "../config";
|
|
|
|
import { withCsrfHeaders } from "./csrf";
|
|
import { sanitizeRunStreamOptions } from "./stream-mode";
|
|
|
|
/**
|
|
* Dedicated LangGraph client for the Canvas page.
|
|
*
|
|
* Keeping this separate from getAPIClient() means:
|
|
* - Canvas API calls can be pointed at a different server via VITE_CANVAS_LANGGRAPH_BASE_URL
|
|
* - Canvas-specific HTTP-level logic (headers, retries, middleware) lives here
|
|
* - Changes here never touch the main page's API path
|
|
*/
|
|
function createCanvasClient(): LangGraphClient {
|
|
const client = new LangGraphClient({
|
|
apiUrl: getCanvasLangGraphBaseURL(),
|
|
onRequest(_url, init) {
|
|
const headers = withCsrfHeaders(init.headers);
|
|
const authHeader = getAuthorizationHeaderValue();
|
|
if (authHeader && !headers.has("Authorization")) {
|
|
headers.set("Authorization", authHeader);
|
|
}
|
|
return {
|
|
...init,
|
|
credentials: init.credentials ?? "include",
|
|
headers,
|
|
};
|
|
},
|
|
});
|
|
|
|
const originalRunStream = client.runs.stream.bind(client.runs);
|
|
client.runs.stream = ((threadId, assistantId, payload) =>
|
|
originalRunStream(
|
|
threadId,
|
|
assistantId,
|
|
sanitizeRunStreamOptions(payload),
|
|
)) as typeof client.runs.stream;
|
|
|
|
const originalJoinStream = client.runs.joinStream.bind(client.runs);
|
|
client.runs.joinStream = ((threadId, runId, options) =>
|
|
originalJoinStream(
|
|
threadId,
|
|
runId,
|
|
sanitizeRunStreamOptions(options),
|
|
)) as typeof client.runs.joinStream;
|
|
|
|
return client;
|
|
}
|
|
|
|
let _canvasClient: LangGraphClient | null = null;
|
|
|
|
export function getCanvasAPIClient(): LangGraphClient {
|
|
if (!_canvasClient) {
|
|
_canvasClient = createCanvasClient();
|
|
}
|
|
return _canvasClient;
|
|
}
|