From ecb15acb809864c60d51bf948f1f26ea1d51a43b Mon Sep 17 00:00:00 2001 From: Tat Dat Duong Date: Wed, 16 Apr 2025 17:10:44 +0200 Subject: [PATCH] feat(sdk-js): export more useStream types, allow loopback clients using globals --- docs/docs/how-tos/http/custom_routes.md | 4 ---- libs/sdk-js/package.json | 2 +- libs/sdk-js/src/client.ts | 25 ++++++++++++++++++++++--- libs/sdk-js/src/react/index.ts | 7 ++++++- libs/sdk-js/src/react/stream.tsx | 2 +- 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/docs/docs/how-tos/http/custom_routes.md b/docs/docs/how-tos/http/custom_routes.md index 8adf31186..e5d5ed5d6 100644 --- a/docs/docs/how-tos/http/custom_routes.md +++ b/docs/docs/how-tos/http/custom_routes.md @@ -8,10 +8,6 @@ Defining a custom app object lets you add any routes you'd like, so you can do a Below is an example using FastAPI. -???+ note "Python only" - - We currently only support custom authentication and authorization in Python deployments with `langgraph-api>=0.0.26`. - ## Create app Starting from an **existing** LangGraph Platform application, add the following custom route code to your `webapp.py` file. If you are starting from scratch, you can create a new app from a template using the CLI. diff --git a/libs/sdk-js/package.json b/libs/sdk-js/package.json index 3251a12aa..fa8e5150e 100644 --- a/libs/sdk-js/package.json +++ b/libs/sdk-js/package.json @@ -1,6 +1,6 @@ { "name": "@langchain/langgraph-sdk", - "version": "0.0.66", + "version": "0.0.67", "description": "Client library for interacting with the LangGraph API", "type": "module", "packageManager": "yarn@1.22.19", diff --git a/libs/sdk-js/src/client.ts b/libs/sdk-js/src/client.ts index f368da079..62a586cfe 100644 --- a/libs/sdk-js/src/client.ts +++ b/libs/sdk-js/src/client.ts @@ -84,18 +84,37 @@ class BaseClient { protected defaultHeaders: Record; constructor(config?: ClientConfig) { - this.asyncCaller = new AsyncCaller({ + const callerOptions = { maxRetries: 4, maxConcurrency: 4, ...config?.callerOptions, - }); + }; + let defaultApiUrl = "http://localhost:8123"; + if ( + !config?.apiUrl && + typeof globalThis === "object" && + globalThis != null + ) { + const fetchSmb = Symbol.for("langgraph_api:fetch"); + const urlSmb = Symbol.for("langgraph_api:url"); + + const global = globalThis as unknown as { + [fetchSmb]?: typeof fetch; + [urlSmb]?: string; + }; + + if (global[fetchSmb]) callerOptions.fetch ??= global[fetchSmb]; + if (global[urlSmb]) defaultApiUrl = global[urlSmb]; + } + + this.asyncCaller = new AsyncCaller(callerOptions); this.timeoutMs = config?.timeoutMs; // default limit being capped by Chrome // https://github.com/nodejs/undici/issues/1373 // Regex to remove trailing slash, if present - this.apiUrl = config?.apiUrl?.replace(/\/$/, "") || "http://localhost:8123"; + this.apiUrl = config?.apiUrl?.replace(/\/$/, "") || defaultApiUrl; this.defaultHeaders = config?.defaultHeaders || {}; const apiKey = getApiKey(config?.apiKey); if (apiKey) { diff --git a/libs/sdk-js/src/react/index.ts b/libs/sdk-js/src/react/index.ts index 97a58f3d1..9b7e22871 100644 --- a/libs/sdk-js/src/react/index.ts +++ b/libs/sdk-js/src/react/index.ts @@ -1 +1,6 @@ -export { useStream, type MessageMetadata } from "./stream.js"; +export { + useStream, + type MessageMetadata, + type UseStream, + type UseStreamOptions, +} from "./stream.js"; diff --git a/libs/sdk-js/src/react/stream.tsx b/libs/sdk-js/src/react/stream.tsx index b7e574cff..06ac8b4f9 100644 --- a/libs/sdk-js/src/react/stream.tsx +++ b/libs/sdk-js/src/react/stream.tsx @@ -405,7 +405,7 @@ type GetCustomEventType = Bag extends { ? Bag["CustomEventType"] : unknown; -interface UseStreamOptions< +export interface UseStreamOptions< StateType extends Record = Record, Bag extends BagTemplate = BagTemplate, > {