@langchain/react 0.3.5 → 0.4.0-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/_rolldown/runtime.cjs +23 -0
- package/dist/index.cjs +1 -56
- package/dist/index.d.cts +3 -5
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +3 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -4
- package/dist/libs/langgraph-core/dist/channels/base.d.cts +83 -0
- package/dist/libs/langgraph-core/dist/channels/base.d.cts.map +1 -0
- package/dist/libs/langgraph-core/dist/channels/base.d.ts +83 -0
- package/dist/libs/langgraph-core/dist/channels/base.d.ts.map +1 -0
- package/dist/libs/langgraph-core/dist/constants.d.cts +42 -0
- package/dist/libs/langgraph-core/dist/constants.d.cts.map +1 -0
- package/dist/libs/langgraph-core/dist/constants.d.ts +42 -0
- package/dist/libs/langgraph-core/dist/constants.d.ts.map +1 -0
- package/dist/libs/langgraph-core/dist/graph/zod/index.d.cts +2 -0
- package/dist/libs/langgraph-core/dist/graph/zod/index.d.ts +2 -0
- package/dist/libs/langgraph-core/dist/graph/zod/meta.d.cts +109 -0
- package/dist/libs/langgraph-core/dist/graph/zod/meta.d.cts.map +1 -0
- package/dist/libs/langgraph-core/dist/graph/zod/meta.d.ts +109 -0
- package/dist/libs/langgraph-core/dist/graph/zod/meta.d.ts.map +1 -0
- package/dist/libs/langgraph-core/dist/graph/zod/zod-registry.d.cts +49 -0
- package/dist/libs/langgraph-core/dist/graph/zod/zod-registry.d.cts.map +1 -0
- package/dist/libs/langgraph-core/dist/graph/zod/zod-registry.d.ts +49 -0
- package/dist/libs/langgraph-core/dist/graph/zod/zod-registry.d.ts.map +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/ReactAgent.d.cts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/ReactAgent.d.ts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/index.d.cts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/index.d.ts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/contextEditing.d.cts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/contextEditing.d.ts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/dynamicSystemPrompt.d.cts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/dynamicSystemPrompt.d.ts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/hitl.d.cts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/hitl.d.ts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/llmToolSelector.d.cts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/llmToolSelector.d.ts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/modelCallLimit.d.cts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/modelCallLimit.d.ts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/modelFallback.d.cts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/modelFallback.d.ts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/modelRetry.d.cts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/modelRetry.d.ts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/pii.d.cts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/pii.d.ts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/piiRedaction.d.cts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/piiRedaction.d.ts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/provider/anthropic/promptCaching.d.cts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/provider/anthropic/promptCaching.d.ts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/provider/openai/moderation.d.cts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/provider/openai/moderation.d.ts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/summarization.d.cts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/summarization.d.ts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/todoListMiddleware.d.cts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/todoListMiddleware.d.ts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/toolCallLimit.d.cts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/toolCallLimit.d.ts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/toolEmulator.d.cts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/toolEmulator.d.ts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/toolRetry.d.cts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/toolRetry.d.ts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/types.d.cts +2 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware/types.d.ts +2 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware.d.cts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/middleware.d.ts +1 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/types.d.cts +2 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/agents/types.d.ts +2 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/index.d.cts +2 -0
- package/dist/node_modules/.pnpm/langchain@1.2.33-dev-1773786580575_@langchain_core@1.1.32_@opentelemetry_api@1.9.0_open_a3480def1aaae3092a33e9a20fdaa4bd/node_modules/langchain/dist/index.d.ts +2 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/checks.d.cts +29 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/checks.d.cts.map +1 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/checks.d.ts +29 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/checks.d.ts.map +1 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/core.d.cts +29 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/core.d.cts.map +1 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/core.d.ts +29 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/core.d.ts.map +1 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/errors.d.cts +105 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/errors.d.cts.map +1 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/errors.d.ts +105 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/errors.d.ts.map +1 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/json-schema.d.cts +70 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/json-schema.d.cts.map +1 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/json-schema.d.ts +70 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/json-schema.d.ts.map +1 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/registries.d.cts +24 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/registries.d.cts.map +1 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/registries.d.ts +24 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/registries.d.ts.map +1 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/schemas.d.cts +97 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/schemas.d.cts.map +1 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/schemas.d.ts +97 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/schemas.d.ts.map +1 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/standard-schema.d.cts +79 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/standard-schema.d.cts.map +1 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/standard-schema.d.ts +79 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/standard-schema.d.ts.map +1 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/to-json-schema.d.cts +52 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/to-json-schema.d.cts.map +1 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/to-json-schema.d.ts +52 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/to-json-schema.d.ts.map +1 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/util.d.cts +17 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/util.d.cts.map +1 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/util.d.ts +17 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/util.d.ts.map +1 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/versions.d.cts +9 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/versions.d.cts.map +1 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/versions.d.ts +9 -0
- package/dist/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/versions.d.ts.map +1 -0
- package/dist/react-ui/client.cjs +136 -0
- package/dist/react-ui/client.cjs.map +1 -0
- package/dist/react-ui/client.d.cts +88 -0
- package/dist/react-ui/client.d.cts.map +1 -0
- package/dist/react-ui/client.d.ts +88 -0
- package/dist/react-ui/client.d.ts.map +1 -0
- package/dist/react-ui/client.js +130 -0
- package/dist/react-ui/client.js.map +1 -0
- package/dist/react-ui/index.cjs +14 -0
- package/dist/react-ui/index.cjs.map +1 -0
- package/dist/react-ui/index.d.cts +3 -0
- package/dist/react-ui/index.d.ts +3 -0
- package/dist/react-ui/index.js +8 -0
- package/dist/react-ui/index.js.map +1 -0
- package/dist/react-ui/server/index.cjs +5 -0
- package/dist/react-ui/server/index.d.cts +3 -0
- package/dist/react-ui/server/index.d.ts +3 -0
- package/dist/react-ui/server/index.js +3 -0
- package/dist/react-ui/server/server.cjs +56 -0
- package/dist/react-ui/server/server.cjs.map +1 -0
- package/dist/react-ui/server/server.d.cts +54 -0
- package/dist/react-ui/server/server.d.cts.map +1 -0
- package/dist/react-ui/server/server.d.ts +54 -0
- package/dist/react-ui/server/server.d.ts.map +1 -0
- package/dist/react-ui/server/server.js +55 -0
- package/dist/react-ui/server/server.js.map +1 -0
- package/dist/react-ui/types.cjs +37 -0
- package/dist/react-ui/types.cjs.map +1 -0
- package/dist/react-ui/types.d.cts +25 -0
- package/dist/react-ui/types.d.cts.map +1 -0
- package/dist/react-ui/types.d.ts +25 -0
- package/dist/react-ui/types.d.ts.map +1 -0
- package/dist/react-ui/types.js +35 -0
- package/dist/react-ui/types.js.map +1 -0
- package/dist/stream.cjs +4 -5
- package/dist/stream.cjs.map +1 -1
- package/dist/stream.custom.cjs +28 -38
- package/dist/stream.custom.cjs.map +1 -1
- package/dist/stream.custom.js +29 -40
- package/dist/stream.custom.js.map +1 -1
- package/dist/stream.d.cts +49 -5
- package/dist/stream.d.cts.map +1 -1
- package/dist/stream.d.ts +49 -5
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +3 -5
- package/dist/stream.js.map +1 -1
- package/dist/stream.lgp.cjs +31 -40
- package/dist/stream.lgp.cjs.map +1 -1
- package/dist/stream.lgp.js +32 -42
- package/dist/stream.lgp.js.map +1 -1
- package/dist/thread.cjs +1 -0
- package/dist/thread.cjs.map +1 -1
- package/dist/thread.js.map +1 -1
- package/dist/types.d.cts +3 -19
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts +3 -19
- package/dist/types.d.ts.map +1 -1
- package/package.json +16 -15
- package/LICENSE +0 -21
- package/dist/context.cjs +0 -108
- package/dist/context.cjs.map +0 -1
- package/dist/context.d.cts +0 -109
- package/dist/context.d.cts.map +0 -1
- package/dist/context.d.ts +0 -109
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -107
- package/dist/context.js.map +0 -1
- package/dist/suspense-stream.cjs +0 -203
- package/dist/suspense-stream.cjs.map +0 -1
- package/dist/suspense-stream.d.cts +0 -81
- package/dist/suspense-stream.d.cts.map +0 -1
- package/dist/suspense-stream.d.ts +0 -81
- package/dist/suspense-stream.d.ts.map +0 -1
- package/dist/suspense-stream.js +0 -201
- package/dist/suspense-stream.js.map +0 -1
package/dist/stream.custom.js
CHANGED
|
@@ -1,26 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useControllableThreadId } from "./thread.js";
|
|
3
3
|
import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from "react";
|
|
4
|
-
import { FetchStreamTransport, MessageTupleManager, StreamManager, ensureMessageInstances, extractInterrupts, toMessageClass
|
|
4
|
+
import { FetchStreamTransport, MessageTupleManager, StreamManager, ensureMessageInstances, extractInterrupts, toMessageClass } from "@langchain/langgraph-sdk/ui";
|
|
5
5
|
import { getToolCallsWithResults } from "@langchain/langgraph-sdk/utils";
|
|
6
|
-
import {
|
|
6
|
+
import { handleHeadlessToolInterrupt, isHeadlessToolInterrupt } from "@langchain/langgraph-sdk";
|
|
7
7
|
//#region src/stream.custom.tsx
|
|
8
|
-
function createCustomTransportThreadState(values, threadId) {
|
|
9
|
-
return {
|
|
10
|
-
values,
|
|
11
|
-
next: [],
|
|
12
|
-
tasks: [],
|
|
13
|
-
metadata: void 0,
|
|
14
|
-
created_at: null,
|
|
15
|
-
checkpoint: {
|
|
16
|
-
thread_id: threadId,
|
|
17
|
-
checkpoint_id: null,
|
|
18
|
-
checkpoint_ns: "",
|
|
19
|
-
checkpoint_map: null
|
|
20
|
-
},
|
|
21
|
-
parent_checkpoint: null
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
8
|
function useStreamCustom(options) {
|
|
25
9
|
const [messageManager] = useState(() => new MessageTupleManager());
|
|
26
10
|
const [stream] = useState(() => new StreamManager(messageManager, {
|
|
@@ -87,7 +71,6 @@ function useStreamCustom(options) {
|
|
|
87
71
|
input: values,
|
|
88
72
|
context: submitOptions?.context,
|
|
89
73
|
command: submitOptions?.command,
|
|
90
|
-
streamSubgraphs: submitOptions?.streamSubgraphs,
|
|
91
74
|
signal,
|
|
92
75
|
config: {
|
|
93
76
|
...submitOptions?.config,
|
|
@@ -102,11 +85,7 @@ function useStreamCustom(options) {
|
|
|
102
85
|
setMessages,
|
|
103
86
|
initialValues: {},
|
|
104
87
|
callbacks: options,
|
|
105
|
-
onSuccess: () =>
|
|
106
|
-
if (!usableThreadId) return void 0;
|
|
107
|
-
const finalValues = stream.values ?? historyValues;
|
|
108
|
-
options.onFinish?.(createCustomTransportThreadState(finalValues, usableThreadId), void 0);
|
|
109
|
-
},
|
|
88
|
+
onSuccess: () => void 0,
|
|
110
89
|
onError(error) {
|
|
111
90
|
options.onError?.(error, void 0);
|
|
112
91
|
submitOptions?.onError?.(error, void 0);
|
|
@@ -116,24 +95,30 @@ function useStreamCustom(options) {
|
|
|
116
95
|
const submit = async (values, submitOptions) => {
|
|
117
96
|
await submitDirect(values, submitOptions);
|
|
118
97
|
};
|
|
119
|
-
const
|
|
98
|
+
const toolsRef = useRef(options.tools);
|
|
99
|
+
toolsRef.current = options.tools;
|
|
100
|
+
const onToolRef = useRef(options.onTool);
|
|
101
|
+
onToolRef.current = options.onTool;
|
|
102
|
+
const handledBrowserToolsRef = useRef(/* @__PURE__ */ new Set());
|
|
120
103
|
useEffect(() => {
|
|
121
|
-
|
|
104
|
+
handledBrowserToolsRef.current.clear();
|
|
122
105
|
}, [threadId]);
|
|
123
106
|
useEffect(() => {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
107
|
+
const tools = toolsRef.current;
|
|
108
|
+
if (!tools?.length) return;
|
|
109
|
+
if (!stream.values) return;
|
|
110
|
+
const interrupts = stream.values.__interrupt__;
|
|
111
|
+
if (!Array.isArray(interrupts) || interrupts.length === 0) return;
|
|
112
|
+
for (const interrupt of interrupts) {
|
|
113
|
+
if (!isHeadlessToolInterrupt(interrupt.value)) continue;
|
|
114
|
+
const interruptId = interrupt.id ?? interrupt.value.toolCall.id ?? "";
|
|
115
|
+
if (handledBrowserToolsRef.current.has(interruptId)) continue;
|
|
116
|
+
handledBrowserToolsRef.current.add(interruptId);
|
|
117
|
+
handleHeadlessToolInterrupt(interrupt.value, tools, onToolRef.current).then((result) => {
|
|
118
|
+
submit(null, { command: { resume: result.toolCallId ? { [result.toolCallId]: result.value } : result.value } });
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}, [stream.values, submit]);
|
|
137
122
|
return {
|
|
138
123
|
get values() {
|
|
139
124
|
return stream.values ?? {};
|
|
@@ -156,7 +141,11 @@ function useStreamCustom(options) {
|
|
|
156
141
|
};
|
|
157
142
|
},
|
|
158
143
|
get interrupts() {
|
|
159
|
-
if (stream.values != null && "__interrupt__" in stream.values && Array.isArray(stream.values.__interrupt__))
|
|
144
|
+
if (stream.values != null && "__interrupt__" in stream.values && Array.isArray(stream.values.__interrupt__)) {
|
|
145
|
+
const valueInterrupts = stream.values.__interrupt__;
|
|
146
|
+
if (valueInterrupts.length === 0) return [{ when: "breakpoint" }];
|
|
147
|
+
return valueInterrupts;
|
|
148
|
+
}
|
|
160
149
|
return [];
|
|
161
150
|
},
|
|
162
151
|
get interrupt() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.custom.js","names":[],"sources":["../src/stream.custom.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport {\n StreamManager,\n MessageTupleManager,\n extractInterrupts,\n userFacingInterruptsFromValuesArray,\n FetchStreamTransport,\n toMessageClass,\n ensureMessageInstances,\n type EventStreamEvent,\n type GetUpdateType,\n type GetCustomEventType,\n type GetInterruptType,\n type GetToolCallsType,\n type GetConfigurableType,\n type AnyStreamCustomOptions,\n type CustomSubmitOptions,\n type MessageMetadata,\n} from \"@langchain/langgraph-sdk/ui\";\nimport { getToolCallsWithResults } from \"@langchain/langgraph-sdk/utils\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type {\n BagTemplate,\n Message,\n Interrupt,\n ThreadState,\n} from \"@langchain/langgraph-sdk\";\nimport { flushPendingHeadlessToolInterrupts } from \"@langchain/langgraph-sdk\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport type { UseStreamCustom } from \"./types.js\";\n\nexport { FetchStreamTransport };\n\nfunction createCustomTransportThreadState<\n StateType extends Record<string, unknown>,\n>(values: StateType, threadId: string): ThreadState<StateType> {\n return {\n values,\n next: [],\n tasks: [],\n metadata: undefined,\n created_at: null,\n checkpoint: {\n thread_id: threadId,\n checkpoint_id: null,\n checkpoint_ns: \"\",\n checkpoint_map: null,\n },\n parent_checkpoint: null,\n };\n}\n\nexport function useStreamCustom<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: AnyStreamCustomOptions<StateType, Bag>\n): UseStreamCustom<StateType, Bag> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n type InterruptType = GetInterruptType<Bag>;\n type ConfigurableType = GetConfigurableType<Bag>;\n type ToolCallType = GetToolCallsType<StateType>;\n\n const [messageManager] = useState(() => new MessageTupleManager());\n const [stream] = useState(\n () =>\n new StreamManager<StateType, Bag>(messageManager, {\n throttle: options.throttle ?? false,\n subagentToolNames: options.subagentToolNames,\n filterSubagentMessages: options.filterSubagentMessages,\n toMessage: options.toMessage ?? toMessageClass,\n })\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot\n );\n\n const [branch, _setBranch] = useState(\"\");\n\n const [threadId, onThreadId] = useControllableThreadId(options);\n const threadIdRef = useRef<string | null>(threadId);\n\n // Cancel the stream if thread ID has changed\n useEffect(() => {\n if (threadIdRef.current !== threadId) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n }, [threadId, stream]);\n\n const switchThread = useCallback(\n (newThreadId: string | null) => {\n if (newThreadId !== threadIdRef.current) {\n threadIdRef.current = newThreadId;\n stream.clear();\n }\n },\n [stream]\n );\n\n const getMessages = (value: StateType): Message[] => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return Array.isArray(value[messagesKey])\n ? (value[messagesKey] as Message[])\n : [];\n };\n\n const setMessages = (current: StateType, messages: Message[]): StateType => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return { ...current, [messagesKey]: messages };\n };\n\n const historyValues = options.initialValues ?? ({} as StateType);\n\n // Reconstruct subagents from initialValues when:\n // 1. Subagent filtering is enabled\n // 2. Not currently streaming\n // 3. initialValues has messages\n // This ensures subagent visualization works with cached/persisted state\n const historyMessages = getMessages(historyValues);\n const shouldReconstructSubagents =\n options.filterSubagentMessages &&\n !stream.isLoading &&\n historyMessages.length > 0;\n\n useEffect(() => {\n if (shouldReconstructSubagents) {\n // skipIfPopulated: true ensures we don't overwrite subagents from active streaming\n stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });\n }\n // We intentionally only run this when shouldReconstructSubagents changes\n // to avoid unnecessary reconstructions during streaming\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [shouldReconstructSubagents, historyMessages.length]);\n\n const stop = () => stream.stop(historyValues, { onStop: options.onStop });\n\n const submitDirect = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>\n ) => {\n if (threadId !== threadIdRef.current) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n\n let usableThreadId = threadIdRef.current ?? submitOptions?.threadId;\n\n stream.setStreamValues(() => {\n if (submitOptions?.optimisticValues != null) {\n return {\n ...historyValues,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(historyValues)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...historyValues };\n });\n\n await stream.start(\n async (signal: AbortSignal) => {\n if (!usableThreadId) {\n usableThreadId = crypto.randomUUID();\n threadIdRef.current = usableThreadId;\n onThreadId(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n return options.transport.stream({\n input: values,\n context: submitOptions?.context,\n command: submitOptions?.command,\n streamSubgraphs: submitOptions?.streamSubgraphs,\n signal,\n config: {\n ...submitOptions?.config,\n configurable: {\n thread_id: usableThreadId,\n ...submitOptions?.config?.configurable,\n } as unknown as GetConfigurableType<Bag>,\n },\n }) as Promise<\n AsyncGenerator<EventStreamEvent<StateType, UpdateType, CustomType>>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: {} as StateType,\n callbacks: options,\n\n onSuccess: () => {\n if (!usableThreadId) return undefined;\n\n const finalValues = stream.values ?? historyValues;\n options.onFinish?.(\n createCustomTransportThreadState(finalValues, usableThreadId),\n undefined\n );\n\n return undefined;\n },\n onError(error) {\n options.onError?.(error, undefined);\n submitOptions?.onError?.(error, undefined);\n },\n }\n );\n };\n\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>\n ) => {\n await submitDirect(values, submitOptions);\n };\n\n const handledToolsRef = useRef<Set<string>>(new Set());\n useEffect(() => {\n handledToolsRef.current.clear();\n }, [threadId]);\n\n useEffect(() => {\n flushPendingHeadlessToolInterrupts(\n stream.values as Record<string, unknown> | null,\n options.tools,\n handledToolsRef.current,\n {\n onTool: options.onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n submit(null, {\n command,\n }),\n }\n );\n }, [options.onTool, options.tools, stream.values, submit]);\n\n return {\n get values() {\n return stream.values ?? ({} as StateType);\n },\n\n error: stream.error,\n isLoading: stream.isLoading,\n\n stop,\n submit,\n switchThread,\n\n branch,\n setBranch: _setBranch,\n\n getMessagesMetadata(\n message: BaseMessage,\n index?: number\n ): MessageMetadata<StateType> | undefined {\n const streamMetadata = messageManager.get(message.id)?.metadata;\n if (streamMetadata != null) {\n return {\n messageId: message.id ?? String(index),\n firstSeenState: undefined,\n branch: undefined,\n branchOptions: undefined,\n streamMetadata,\n } as MessageMetadata<StateType>;\n }\n return undefined;\n },\n\n get interrupts(): Interrupt<InterruptType>[] {\n if (\n stream.values != null &&\n \"__interrupt__\" in stream.values &&\n Array.isArray(stream.values.__interrupt__)\n ) {\n return userFacingInterruptsFromValuesArray<InterruptType>(\n stream.values.__interrupt__ as Interrupt<InterruptType>[]\n );\n }\n\n return [];\n },\n\n get interrupt(): Interrupt<InterruptType> | undefined {\n return extractInterrupts<InterruptType>(stream.values);\n },\n\n get messages(): BaseMessage[] {\n if (!stream.values) return [];\n return ensureMessageInstances(\n getMessages(stream.values)\n ) as BaseMessage[];\n },\n\n get toolCalls() {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n return getToolCallsWithResults<ToolCallType>(msgs);\n },\n\n getToolCalls(message) {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n const allToolCalls = getToolCallsWithResults<ToolCallType>(msgs);\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n },\n\n get subagents() {\n return stream.getSubagents();\n },\n\n get activeSubagents() {\n return stream.getActiveSubagents();\n },\n\n getSubagent(toolCallId: string) {\n return stream.getSubagent(toolCallId);\n },\n\n getSubagentsByType(type: string) {\n return stream.getSubagentsByType(type);\n },\n\n getSubagentsByMessage(messageId: string) {\n return stream.getSubagentsByMessage(messageId);\n },\n\n queue: {\n get entries() {\n return [];\n },\n get size() {\n return 0;\n },\n async cancel() {\n return false;\n },\n async clear() {},\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stream.custom.js","names":[],"sources":["../src/stream.custom.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport {\n StreamManager,\n MessageTupleManager,\n extractInterrupts,\n FetchStreamTransport,\n toMessageClass,\n ensureMessageInstances,\n type EventStreamEvent,\n type GetUpdateType,\n type GetCustomEventType,\n type GetInterruptType,\n type GetToolCallsType,\n type GetConfigurableType,\n type AnyStreamCustomOptions,\n type CustomSubmitOptions,\n type MessageMetadata,\n} from \"@langchain/langgraph-sdk/ui\";\nimport { getToolCallsWithResults } from \"@langchain/langgraph-sdk/utils\";\nimport type { BagTemplate, Message, Interrupt } from \"@langchain/langgraph-sdk\";\nimport {\n isHeadlessToolInterrupt,\n handleHeadlessToolInterrupt,\n} from \"@langchain/langgraph-sdk\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport type { UseStreamCustom } from \"./types.js\";\n\nexport { FetchStreamTransport };\n\nexport function useStreamCustom<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: AnyStreamCustomOptions<StateType, Bag>,\n): UseStreamCustom<StateType, Bag> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n type InterruptType = GetInterruptType<Bag>;\n type ConfigurableType = GetConfigurableType<Bag>;\n type ToolCallType = GetToolCallsType<StateType>;\n\n const [messageManager] = useState(() => new MessageTupleManager());\n const [stream] = useState(\n () =>\n new StreamManager<StateType, Bag>(messageManager, {\n throttle: options.throttle ?? false,\n subagentToolNames: options.subagentToolNames,\n filterSubagentMessages: options.filterSubagentMessages,\n toMessage: options.toMessage ?? toMessageClass,\n }),\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot,\n );\n\n const [branch, _setBranch] = useState(\"\");\n\n const [threadId, onThreadId] = useControllableThreadId(options);\n const threadIdRef = useRef<string | null>(threadId);\n\n // Cancel the stream if thread ID has changed\n useEffect(() => {\n if (threadIdRef.current !== threadId) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n }, [threadId, stream]);\n\n const switchThread = useCallback(\n (newThreadId: string | null) => {\n if (newThreadId !== threadIdRef.current) {\n threadIdRef.current = newThreadId;\n stream.clear();\n }\n },\n [stream],\n );\n\n const getMessages = (value: StateType): Message[] => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return Array.isArray(value[messagesKey])\n ? (value[messagesKey] as Message[])\n : [];\n };\n\n const setMessages = (current: StateType, messages: Message[]): StateType => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return { ...current, [messagesKey]: messages };\n };\n\n const historyValues = options.initialValues ?? ({} as StateType);\n\n // Reconstruct subagents from initialValues when:\n // 1. Subagent filtering is enabled\n // 2. Not currently streaming\n // 3. initialValues has messages\n // This ensures subagent visualization works with cached/persisted state\n const historyMessages = getMessages(historyValues);\n const shouldReconstructSubagents =\n options.filterSubagentMessages &&\n !stream.isLoading &&\n historyMessages.length > 0;\n\n useEffect(() => {\n if (shouldReconstructSubagents) {\n // skipIfPopulated: true ensures we don't overwrite subagents from active streaming\n stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });\n }\n // We intentionally only run this when shouldReconstructSubagents changes\n // to avoid unnecessary reconstructions during streaming\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [shouldReconstructSubagents, historyMessages.length]);\n\n const stop = () => stream.stop(historyValues, { onStop: options.onStop });\n\n const submitDirect = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>,\n ) => {\n if (threadId !== threadIdRef.current) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n\n let usableThreadId = threadIdRef.current ?? submitOptions?.threadId;\n\n stream.setStreamValues(() => {\n if (submitOptions?.optimisticValues != null) {\n return {\n ...historyValues,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(historyValues)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...historyValues };\n });\n\n await stream.start(\n async (signal: AbortSignal) => {\n if (!usableThreadId) {\n usableThreadId = crypto.randomUUID();\n threadIdRef.current = usableThreadId;\n onThreadId(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n return options.transport.stream({\n input: values,\n context: submitOptions?.context,\n command: submitOptions?.command,\n signal,\n config: {\n ...submitOptions?.config,\n configurable: {\n thread_id: usableThreadId,\n ...submitOptions?.config?.configurable,\n } as unknown as GetConfigurableType<Bag>,\n },\n }) as Promise<\n AsyncGenerator<EventStreamEvent<StateType, UpdateType, CustomType>>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: {} as StateType,\n callbacks: options,\n\n onSuccess: () => undefined,\n onError(error) {\n options.onError?.(error, undefined);\n submitOptions?.onError?.(error, undefined);\n },\n },\n );\n };\n\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>,\n ) => {\n await submitDirect(values, submitOptions);\n };\n\n // Headless tools handling\n const toolsRef = useRef(options.tools);\n toolsRef.current = options.tools;\n\n const onToolRef = useRef(options.onTool);\n onToolRef.current = options.onTool;\n\n const handledBrowserToolsRef = useRef<Set<string>>(new Set());\n\n useEffect(() => {\n handledBrowserToolsRef.current.clear();\n }, [threadId]);\n\n useEffect(() => {\n const tools = toolsRef.current;\n if (!tools?.length) return;\n if (!stream.values) return;\n\n const interrupts = stream.values.__interrupt__;\n if (!Array.isArray(interrupts) || interrupts.length === 0) return;\n\n for (const interrupt of interrupts) {\n if (!isHeadlessToolInterrupt(interrupt.value)) continue;\n\n const interruptId = interrupt.id ?? interrupt.value.toolCall.id ?? \"\";\n if (handledBrowserToolsRef.current.has(interruptId)) continue;\n handledBrowserToolsRef.current.add(interruptId);\n\n void handleHeadlessToolInterrupt(\n interrupt.value,\n tools,\n onToolRef.current,\n ).then((result) => {\n void submit(null, {\n command: {\n resume: result.toolCallId\n ? { [result.toolCallId]: result.value }\n : result.value,\n },\n });\n });\n }\n }, [stream.values, submit]);\n\n return {\n get values() {\n return stream.values ?? ({} as StateType);\n },\n\n error: stream.error,\n isLoading: stream.isLoading,\n\n stop,\n submit,\n switchThread,\n\n branch,\n setBranch: _setBranch,\n\n getMessagesMetadata(\n message: BaseMessage,\n index?: number,\n ): MessageMetadata<StateType> | undefined {\n const streamMetadata = messageManager.get(message.id)?.metadata;\n if (streamMetadata != null) {\n return {\n messageId: message.id ?? String(index),\n firstSeenState: undefined,\n branch: undefined,\n branchOptions: undefined,\n streamMetadata,\n } as MessageMetadata<StateType>;\n }\n return undefined;\n },\n\n get interrupts(): Interrupt<InterruptType>[] {\n if (\n stream.values != null &&\n \"__interrupt__\" in stream.values &&\n Array.isArray(stream.values.__interrupt__)\n ) {\n const valueInterrupts = stream.values.__interrupt__;\n if (valueInterrupts.length === 0) return [{ when: \"breakpoint\" }];\n return valueInterrupts;\n }\n\n return [];\n },\n\n get interrupt(): Interrupt<InterruptType> | undefined {\n return extractInterrupts<InterruptType>(stream.values);\n },\n\n get messages(): BaseMessage[] {\n if (!stream.values) return [];\n return ensureMessageInstances(\n getMessages(stream.values),\n ) as BaseMessage[];\n },\n\n get toolCalls() {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n return getToolCallsWithResults<ToolCallType>(msgs);\n },\n\n getToolCalls(message) {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n const allToolCalls = getToolCallsWithResults<ToolCallType>(msgs);\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n },\n\n get subagents() {\n return stream.getSubagents();\n },\n\n get activeSubagents() {\n return stream.getActiveSubagents();\n },\n\n getSubagent(toolCallId: string) {\n return stream.getSubagent(toolCallId);\n },\n\n getSubagentsByType(type: string) {\n return stream.getSubagentsByType(type);\n },\n\n getSubagentsByMessage(messageId: string) {\n return stream.getSubagentsByMessage(messageId);\n },\n\n queue: {\n get entries() {\n return [];\n },\n get size() {\n return 0;\n },\n async cancel() {\n return false;\n },\n async clear() {},\n },\n };\n}\n"],"mappings":"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"}
|
package/dist/stream.d.cts
CHANGED
|
@@ -1,8 +1,52 @@
|
|
|
1
|
-
import { UseStreamCustomOptions
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { UseStreamCustomOptions } from "./types.cjs";
|
|
2
|
+
import { AIMessage, BaseMessage, ToolMessage } from "@langchain/core/messages";
|
|
3
|
+
import { BagTemplate, DefaultToolCall, ToolCallWithResult } from "@langchain/langgraph-sdk";
|
|
4
|
+
import { AcceptBaseMessages, HistoryWithBaseMessages, InferBag, InferStateType, MessageMetadata, ResolveStreamInterface, ResolveStreamOptions, SubagentStreamInterface } from "@langchain/langgraph-sdk/ui";
|
|
4
5
|
|
|
5
6
|
//#region src/stream.d.ts
|
|
7
|
+
type ClassToolCallWithResult<T> = T extends ToolCallWithResult<infer TC, unknown, unknown> ? ToolCallWithResult<TC, ToolMessage, AIMessage> : T;
|
|
8
|
+
type ClassSubagentStreamInterface<StateType = Record<string, unknown>, ToolCall = DefaultToolCall, SubagentName extends string = string> = Omit<SubagentStreamInterface<StateType, ToolCall, SubagentName>, "messages"> & {
|
|
9
|
+
messages: BaseMessage[];
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Maps a stream interface to use @langchain/core BaseMessage class instances
|
|
13
|
+
* instead of plain Message objects for the `messages` property, and remaps
|
|
14
|
+
* tool call types to use @langchain/core message classes.
|
|
15
|
+
*/
|
|
16
|
+
type WithClassMessages<T> = Omit<T, "messages" | "history" | "getMessagesMetadata" | "toolCalls" | "getToolCalls" | "submit" | "subagents" | "activeSubagents" | "getSubagent" | "getSubagentsByType" | "getSubagentsByMessage"> & {
|
|
17
|
+
messages: BaseMessage[];
|
|
18
|
+
getMessagesMetadata: (message: BaseMessage, index?: number) => MessageMetadata<Record<string, unknown>> | undefined;
|
|
19
|
+
} & ("history" extends keyof T ? {
|
|
20
|
+
history: HistoryWithBaseMessages<T["history"]>;
|
|
21
|
+
} : unknown) & ("submit" extends keyof T ? {
|
|
22
|
+
submit: T extends {
|
|
23
|
+
submit: (values: infer V, options?: infer O) => infer Ret;
|
|
24
|
+
} ? (values: AcceptBaseMessages<Exclude<V, null | undefined>> | null | undefined, options?: O) => Ret : never;
|
|
25
|
+
} : unknown) & ("toolCalls" extends keyof T ? {
|
|
26
|
+
toolCalls: T extends {
|
|
27
|
+
toolCalls: (infer TC)[];
|
|
28
|
+
} ? ClassToolCallWithResult<TC>[] : never;
|
|
29
|
+
} : unknown) & ("getToolCalls" extends keyof T ? {
|
|
30
|
+
getToolCalls: T extends {
|
|
31
|
+
getToolCalls: (message: infer _M) => (infer TC)[];
|
|
32
|
+
} ? (message: AIMessage) => ClassToolCallWithResult<TC>[] : never;
|
|
33
|
+
} : unknown) & ("subagents" extends keyof T ? {
|
|
34
|
+
subagents: T extends {
|
|
35
|
+
subagents: Map<string, SubagentStreamInterface<infer S, infer TC, infer N>>;
|
|
36
|
+
} ? Map<string, ClassSubagentStreamInterface<S, TC, N>> : never;
|
|
37
|
+
activeSubagents: T extends {
|
|
38
|
+
activeSubagents: SubagentStreamInterface<infer S, infer TC, infer N>[];
|
|
39
|
+
} ? ClassSubagentStreamInterface<S, TC, N>[] : never;
|
|
40
|
+
getSubagent: T extends {
|
|
41
|
+
getSubagent: (id: string) => SubagentStreamInterface<infer S, infer TC, infer N> | undefined;
|
|
42
|
+
} ? (toolCallId: string) => ClassSubagentStreamInterface<S, TC, N> | undefined : never;
|
|
43
|
+
getSubagentsByType: T extends {
|
|
44
|
+
getSubagentsByType: (type: string) => SubagentStreamInterface<infer S, infer TC, infer N>[];
|
|
45
|
+
} ? (type: string) => ClassSubagentStreamInterface<S, TC, N>[] : never;
|
|
46
|
+
getSubagentsByMessage: T extends {
|
|
47
|
+
getSubagentsByMessage: (id: string) => SubagentStreamInterface<infer S, infer TC, infer N>[];
|
|
48
|
+
} ? (messageId: string) => ClassSubagentStreamInterface<S, TC, N>[] : never;
|
|
49
|
+
} : unknown);
|
|
6
50
|
/**
|
|
7
51
|
* A React hook that provides seamless integration with LangGraph streaming capabilities.
|
|
8
52
|
*
|
|
@@ -168,7 +212,7 @@ declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate
|
|
|
168
212
|
*
|
|
169
213
|
* @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}
|
|
170
214
|
*/
|
|
171
|
-
declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: UseStreamCustomOptions
|
|
215
|
+
declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: UseStreamCustomOptions<InferStateType<T>, InferBag<T, Bag>>): WithClassMessages<ResolveStreamInterface<T, InferBag<T, Bag>>>;
|
|
172
216
|
//#endregion
|
|
173
|
-
export {
|
|
217
|
+
export { ClassSubagentStreamInterface, useStream };
|
|
174
218
|
//# sourceMappingURL=stream.d.cts.map
|
package/dist/stream.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.cts","names":[],"sources":["../src/stream.tsx"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"stream.d.cts","names":[],"sources":["../src/stream.tsx"],"mappings":";;;;;;KAqCK,uBAAA,MACH,CAAA,SAAU,kBAAA,+BACN,kBAAA,CAAmB,EAAA,EAAI,WAAA,EAAiB,SAAA,IACxC,CAAA;AAAA,KAEM,4BAAA,aACE,MAAA,8BACD,eAAA,0CAET,IAAA,CACF,uBAAA,CAAwB,SAAA,EAAW,QAAA,EAAU,YAAA;EAG7C,QAAA,EAAU,WAAA;AAAA;;;;;;KAQP,iBAAA,MAAuB,IAAA,CAC1B,CAAA;EAaA,QAAA,EAAU,WAAA;EACV,mBAAA,GACE,OAAA,EAAS,WAAA,EACT,KAAA,cACG,eAAA,CAAgB,MAAA;AAAA,6BACM,CAAA;EACrB,OAAA,EAAS,uBAAA,CAAwB,CAAA;AAAA,uCAEf,CAAA;EAElB,MAAA,EAAQ,CAAA;IACN,MAAA,GAAS,MAAA,WAAiB,OAAA;EAAA,KAGtB,MAAA,EACI,kBAAA,CAAmB,OAAA,CAAQ,CAAA,yCAG/B,OAAA,GAAU,CAAA,KACP,GAAA;AAAA,0CAIY,CAAA;EAErB,SAAA,EAAW,CAAA;IAAY,SAAA;EAAA,IACnB,uBAAA,CAAwB,EAAA;AAAA,6CAIJ,CAAA;EAExB,YAAA,EAAc,CAAA;IACZ,YAAA,GAAe,OAAA;EAAA,KAEZ,OAAA,EAAS,SAAA,KAAkB,uBAAA,CAAwB,EAAA;AAAA,0CAInC,CAAA;EAErB,SAAA,EAAW,CAAA;IACT,SAAA,EAAW,GAAA,SAET,uBAAA;EAAA,IAGA,GAAA,SAAY,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;EAEpD,eAAA,EAAiB,CAAA;IACf,eAAA,EAAiB,uBAAA;EAAA,IAMf,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;EAExC,WAAA,EAAa,CAAA;IACX,WAAA,GACE,EAAA,aACG,uBAAA;EAAA,KAGD,UAAA,aACG,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;EAE7C,kBAAA,EAAoB,CAAA;IAClB,kBAAA,GACE,IAAA,aACG,uBAAA;EAAA,KAEF,IAAA,aAAiB,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;EAE1D,qBAAA,EAAuB,CAAA;IACrB,qBAAA,GACE,EAAA,aACG,uBAAA;EAAA,KAEF,SAAA,aAAsB,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;AAAA;;;;;;;;;;AApGrE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6Pc,SAAA,KACV,MAAA,+BACQ,WAAA,GAAc,WAAA,CAAA,CAE1B,OAAA,EAAS,oBAAA,CAAqB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA,KAC5C,iBAAA,CAAkB,sBAAA,CAAuB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA;;;;;;;;;;;;;;;;;iBAkB3C,SAAA,KACV,MAAA,+BACQ,WAAA,GAAc,WAAA,CAAA,CAE1B,OAAA,EAAS,sBAAA,CAAuB,cAAA,CAAe,CAAA,GAAI,QAAA,CAAS,CAAA,EAAG,GAAA,KAC9D,iBAAA,CAAkB,sBAAA,CAAuB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA"}
|
package/dist/stream.d.ts
CHANGED
|
@@ -1,8 +1,52 @@
|
|
|
1
|
-
import { UseStreamCustomOptions
|
|
2
|
-
import {
|
|
3
|
-
import { BagTemplate } from "@langchain/langgraph-sdk";
|
|
1
|
+
import { UseStreamCustomOptions } from "./types.js";
|
|
2
|
+
import { AcceptBaseMessages, HistoryWithBaseMessages, InferBag, InferStateType, MessageMetadata, ResolveStreamInterface, ResolveStreamOptions, SubagentStreamInterface } from "@langchain/langgraph-sdk/ui";
|
|
3
|
+
import { BagTemplate, DefaultToolCall, ToolCallWithResult } from "@langchain/langgraph-sdk";
|
|
4
|
+
import { AIMessage, BaseMessage, ToolMessage } from "@langchain/core/messages";
|
|
4
5
|
|
|
5
6
|
//#region src/stream.d.ts
|
|
7
|
+
type ClassToolCallWithResult<T> = T extends ToolCallWithResult<infer TC, unknown, unknown> ? ToolCallWithResult<TC, ToolMessage, AIMessage> : T;
|
|
8
|
+
type ClassSubagentStreamInterface<StateType = Record<string, unknown>, ToolCall = DefaultToolCall, SubagentName extends string = string> = Omit<SubagentStreamInterface<StateType, ToolCall, SubagentName>, "messages"> & {
|
|
9
|
+
messages: BaseMessage[];
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Maps a stream interface to use @langchain/core BaseMessage class instances
|
|
13
|
+
* instead of plain Message objects for the `messages` property, and remaps
|
|
14
|
+
* tool call types to use @langchain/core message classes.
|
|
15
|
+
*/
|
|
16
|
+
type WithClassMessages<T> = Omit<T, "messages" | "history" | "getMessagesMetadata" | "toolCalls" | "getToolCalls" | "submit" | "subagents" | "activeSubagents" | "getSubagent" | "getSubagentsByType" | "getSubagentsByMessage"> & {
|
|
17
|
+
messages: BaseMessage[];
|
|
18
|
+
getMessagesMetadata: (message: BaseMessage, index?: number) => MessageMetadata<Record<string, unknown>> | undefined;
|
|
19
|
+
} & ("history" extends keyof T ? {
|
|
20
|
+
history: HistoryWithBaseMessages<T["history"]>;
|
|
21
|
+
} : unknown) & ("submit" extends keyof T ? {
|
|
22
|
+
submit: T extends {
|
|
23
|
+
submit: (values: infer V, options?: infer O) => infer Ret;
|
|
24
|
+
} ? (values: AcceptBaseMessages<Exclude<V, null | undefined>> | null | undefined, options?: O) => Ret : never;
|
|
25
|
+
} : unknown) & ("toolCalls" extends keyof T ? {
|
|
26
|
+
toolCalls: T extends {
|
|
27
|
+
toolCalls: (infer TC)[];
|
|
28
|
+
} ? ClassToolCallWithResult<TC>[] : never;
|
|
29
|
+
} : unknown) & ("getToolCalls" extends keyof T ? {
|
|
30
|
+
getToolCalls: T extends {
|
|
31
|
+
getToolCalls: (message: infer _M) => (infer TC)[];
|
|
32
|
+
} ? (message: AIMessage) => ClassToolCallWithResult<TC>[] : never;
|
|
33
|
+
} : unknown) & ("subagents" extends keyof T ? {
|
|
34
|
+
subagents: T extends {
|
|
35
|
+
subagents: Map<string, SubagentStreamInterface<infer S, infer TC, infer N>>;
|
|
36
|
+
} ? Map<string, ClassSubagentStreamInterface<S, TC, N>> : never;
|
|
37
|
+
activeSubagents: T extends {
|
|
38
|
+
activeSubagents: SubagentStreamInterface<infer S, infer TC, infer N>[];
|
|
39
|
+
} ? ClassSubagentStreamInterface<S, TC, N>[] : never;
|
|
40
|
+
getSubagent: T extends {
|
|
41
|
+
getSubagent: (id: string) => SubagentStreamInterface<infer S, infer TC, infer N> | undefined;
|
|
42
|
+
} ? (toolCallId: string) => ClassSubagentStreamInterface<S, TC, N> | undefined : never;
|
|
43
|
+
getSubagentsByType: T extends {
|
|
44
|
+
getSubagentsByType: (type: string) => SubagentStreamInterface<infer S, infer TC, infer N>[];
|
|
45
|
+
} ? (type: string) => ClassSubagentStreamInterface<S, TC, N>[] : never;
|
|
46
|
+
getSubagentsByMessage: T extends {
|
|
47
|
+
getSubagentsByMessage: (id: string) => SubagentStreamInterface<infer S, infer TC, infer N>[];
|
|
48
|
+
} ? (messageId: string) => ClassSubagentStreamInterface<S, TC, N>[] : never;
|
|
49
|
+
} : unknown);
|
|
6
50
|
/**
|
|
7
51
|
* A React hook that provides seamless integration with LangGraph streaming capabilities.
|
|
8
52
|
*
|
|
@@ -168,7 +212,7 @@ declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate
|
|
|
168
212
|
*
|
|
169
213
|
* @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}
|
|
170
214
|
*/
|
|
171
|
-
declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: UseStreamCustomOptions
|
|
215
|
+
declare function useStream<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: UseStreamCustomOptions<InferStateType<T>, InferBag<T, Bag>>): WithClassMessages<ResolveStreamInterface<T, InferBag<T, Bag>>>;
|
|
172
216
|
//#endregion
|
|
173
|
-
export {
|
|
217
|
+
export { ClassSubagentStreamInterface, useStream };
|
|
174
218
|
//# sourceMappingURL=stream.d.ts.map
|
package/dist/stream.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.ts","names":[],"sources":["../src/stream.tsx"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"stream.d.ts","names":[],"sources":["../src/stream.tsx"],"mappings":";;;;;;KAqCK,uBAAA,MACH,CAAA,SAAU,kBAAA,+BACN,kBAAA,CAAmB,EAAA,EAAI,WAAA,EAAiB,SAAA,IACxC,CAAA;AAAA,KAEM,4BAAA,aACE,MAAA,8BACD,eAAA,0CAET,IAAA,CACF,uBAAA,CAAwB,SAAA,EAAW,QAAA,EAAU,YAAA;EAG7C,QAAA,EAAU,WAAA;AAAA;;;;;;KAQP,iBAAA,MAAuB,IAAA,CAC1B,CAAA;EAaA,QAAA,EAAU,WAAA;EACV,mBAAA,GACE,OAAA,EAAS,WAAA,EACT,KAAA,cACG,eAAA,CAAgB,MAAA;AAAA,6BACM,CAAA;EACrB,OAAA,EAAS,uBAAA,CAAwB,CAAA;AAAA,uCAEf,CAAA;EAElB,MAAA,EAAQ,CAAA;IACN,MAAA,GAAS,MAAA,WAAiB,OAAA;EAAA,KAGtB,MAAA,EACI,kBAAA,CAAmB,OAAA,CAAQ,CAAA,yCAG/B,OAAA,GAAU,CAAA,KACP,GAAA;AAAA,0CAIY,CAAA;EAErB,SAAA,EAAW,CAAA;IAAY,SAAA;EAAA,IACnB,uBAAA,CAAwB,EAAA;AAAA,6CAIJ,CAAA;EAExB,YAAA,EAAc,CAAA;IACZ,YAAA,GAAe,OAAA;EAAA,KAEZ,OAAA,EAAS,SAAA,KAAkB,uBAAA,CAAwB,EAAA;AAAA,0CAInC,CAAA;EAErB,SAAA,EAAW,CAAA;IACT,SAAA,EAAW,GAAA,SAET,uBAAA;EAAA,IAGA,GAAA,SAAY,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;EAEpD,eAAA,EAAiB,CAAA;IACf,eAAA,EAAiB,uBAAA;EAAA,IAMf,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;EAExC,WAAA,EAAa,CAAA;IACX,WAAA,GACE,EAAA,aACG,uBAAA;EAAA,KAGD,UAAA,aACG,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;EAE7C,kBAAA,EAAoB,CAAA;IAClB,kBAAA,GACE,IAAA,aACG,uBAAA;EAAA,KAEF,IAAA,aAAiB,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;EAE1D,qBAAA,EAAuB,CAAA;IACrB,qBAAA,GACE,EAAA,aACG,uBAAA;EAAA,KAEF,SAAA,aAAsB,4BAAA,CAA6B,CAAA,EAAG,EAAA,EAAI,CAAA;AAAA;;;;;;;;;;AApGrE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6Pc,SAAA,KACV,MAAA,+BACQ,WAAA,GAAc,WAAA,CAAA,CAE1B,OAAA,EAAS,oBAAA,CAAqB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA,KAC5C,iBAAA,CAAkB,sBAAA,CAAuB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA;;;;;;;;;;;;;;;;;iBAkB3C,SAAA,KACV,MAAA,+BACQ,WAAA,GAAc,WAAA,CAAA,CAE1B,OAAA,EAAS,sBAAA,CAAuB,cAAA,CAAe,CAAA,GAAI,QAAA,CAAS,CAAA,EAAG,GAAA,KAC9D,iBAAA,CAAkB,sBAAA,CAAuB,CAAA,EAAG,QAAA,CAAS,CAAA,EAAG,GAAA"}
|
package/dist/stream.js
CHANGED
|
@@ -5,12 +5,10 @@ import { useState } from "react";
|
|
|
5
5
|
function isCustomOptions(options) {
|
|
6
6
|
return "transport" in options;
|
|
7
7
|
}
|
|
8
|
-
function selectStreamImplementation(options) {
|
|
9
|
-
return isCustomOptions(options) ? useStreamCustom : useStreamLGP;
|
|
10
|
-
}
|
|
11
8
|
function useStream(options) {
|
|
12
|
-
const [
|
|
13
|
-
return
|
|
9
|
+
const [isCustom] = useState(isCustomOptions(options));
|
|
10
|
+
if (isCustom) return useStreamCustom(options);
|
|
11
|
+
return useStreamLGP(options);
|
|
14
12
|
}
|
|
15
13
|
//#endregion
|
|
16
14
|
export { useStream };
|
package/dist/stream.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.js","names":[],"sources":["../src/stream.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport type { BagTemplate } from \"@langchain/langgraph-sdk\";\nimport type {\n UseStreamOptions,\n ResolveStreamInterface,\n ResolveStreamOptions,\n InferBag,\n InferStateType,\n WithClassMessages,\n} from \"@langchain/langgraph-sdk/ui\";\nimport { useStreamLGP } from \"./stream.lgp.js\";\nimport { useStreamCustom } from \"./stream.custom.js\";\nimport type { UseStreamCustomOptions } from \"./types.js\";\n\nfunction isCustomOptions<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options:\n | UseStreamOptions<StateType, Bag>\n | UseStreamCustomOptions<StateType, Bag>\n): options is UseStreamCustomOptions<StateType, Bag> {\n return \"transport\" in options;\n}\n\ntype UseStreamImplementation = typeof useStreamLGP | typeof useStreamCustom;\n\ntype AnyUseStreamOptions =\n | UseStreamOptions<Record<string, unknown>, BagTemplate>\n | UseStreamCustomOptions<Record<string, unknown>, BagTemplate>;\n\nfunction selectStreamImplementation(\n options: AnyUseStreamOptions\n): UseStreamImplementation {\n return isCustomOptions(options) ? useStreamCustom : useStreamLGP;\n}\n\nexport type {\n WithClassMessages,\n ClassSubagentStreamInterface,\n} from \"@langchain/langgraph-sdk/ui\";\n\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, subagent streams, and errors.\n *\n * ## Usage with ReactAgent (recommended for createAgent users)\n *\n * When using `createAgent` from `@langchain/langgraph`, you can pass `typeof agent` as the\n * type parameter to automatically infer tool call types:\n *\n * @example\n * ```typescript\n * // In your agent file (e.g., agent.ts)\n * import { createAgent, tool } from \"langchain\";\n * import { z } from \"zod\";\n *\n * const getWeather = tool(\n * async ({ location }) => `Weather in ${location}`,\n * { name: \"get_weather\", schema: z.object({ location: z.string() }) }\n * );\n *\n * export const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [getWeather],\n * });\n *\n * // In your React component\n * import { agent } from \"./agent\";\n *\n * function Chat() {\n * // Tool calls are automatically typed from the agent's tools!\n * const stream = useStream<typeof agent>({\n * assistantId: \"agent\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.toolCalls[0].call.name is typed as \"get_weather\"\n * // stream.toolCalls[0].call.args is typed as { location: string }\n * }\n * ```\n *\n * ## Usage with StateGraph (for custom LangGraph applications)\n *\n * When building custom graphs with `StateGraph`, embed your tool call types directly\n * in your state's messages property using `Message<MyToolCalls>`:\n *\n * @example\n * ```typescript\n * import { Message } from \"@langchain/langgraph-sdk\";\n *\n * // Define your tool call types as a discriminated union\n * type MyToolCalls =\n * | { name: \"search\"; args: { query: string }; id?: string }\n * | { name: \"calculate\"; args: { expression: string }; id?: string };\n *\n * // Embed tool call types in your state's messages\n * interface MyGraphState {\n * messages: Message<MyToolCalls>[];\n * context?: string;\n * }\n *\n * function Chat() {\n * const stream = useStream<MyGraphState>({\n * assistantId: \"my-graph\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.values is typed as MyGraphState\n * // stream.toolCalls[0].call.name is typed as \"search\" | \"calculate\"\n * }\n * ```\n *\n * @example\n * ```typescript\n * // With additional type configuration (interrupts, configurable)\n * interface MyGraphState {\n * messages: Message<MyToolCalls>[];\n * }\n *\n * function Chat() {\n * const stream = useStream<MyGraphState, {\n * InterruptType: { question: string };\n * ConfigurableType: { userId: string };\n * }>({\n * assistantId: \"my-graph\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.interrupt is typed as { question: string } | undefined\n * }\n * ```\n *\n * ## Usage with Deep Agents (subagent streaming, experimental)\n *\n * For agents that spawn subagents (nested graphs), use `filterSubagentMessages`\n * to keep the main message stream clean while tracking subagent activity separately:\n *\n * @example\n * ```typescript\n * import { useStream, SubagentStream } from \"@langchain/langgraph-sdk/react\";\n * import type { agent } from \"./agent\";\n *\n * function DeepAgentChat() {\n * const stream = useStream<typeof agent>({\n * assistantId: \"deepagent\",\n * apiUrl: \"http://localhost:2024\",\n * // Filter subagent messages from main stream\n * filterSubagentMessages: true,\n * });\n *\n * const handleSubmit = (content: string) => {\n * stream.submit(\n * { messages: [{ content, type: \"human\" }] },\n * { streamSubgraphs: true } // Enable subgraph streaming\n * );\n * };\n *\n * // Access subagent streams via stream.subagents (Map<string, SubagentStream>)\n * const subagentList = [...stream.subagents.values()];\n *\n * return (\n * <div>\n * {stream.messages.map((msg) => <Message key={msg.id} message={msg} />)}\n *\n * {subagentList.map((subagent) => (\n * <SubagentCard\n * key={subagent.id}\n * status={subagent.status} // \"pending\" | \"running\" | \"complete\" | \"error\"\n * messages={subagent.messages}\n * toolCalls={subagent.toolCalls}\n * />\n * ))}\n * </div>\n * );\n * }\n * ```\n *\n * @template T Either a ReactAgent type (with `~agentTypes`) or a state type (`Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport function useStream<\n T = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: ResolveStreamOptions<T, InferBag<T, Bag>>\n): WithClassMessages<ResolveStreamInterface<T, InferBag<T, Bag>>>;\n\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, and errors.\n *\n * @template T Either a ReactAgent type (with `~agentTypes`) or a state type (`Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport function useStream<\n T = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: UseStreamCustomOptions<InferStateType<T>, InferBag<T, Bag>>\n): WithClassMessages<ResolveStreamInterface<T, InferBag<T, Bag>>>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useStream(options: any): any {\n // Keep implementation stable for the lifetime of this hook instance.\n const [useSelectedStream] = useState(() =>\n selectStreamImplementation(options)\n );\n return useSelectedStream(options);\n}\n"],"mappings":";;;;AAcA,SAAS,gBAIP,SAGmD;AACnD,QAAO,eAAe;;AASxB,SAAS,2BACP,SACyB;AACzB,QAAO,gBAAgB,QAAQ,GAAG,kBAAkB;;AA2LtD,SAAgB,UAAU,SAAmB;CAE3C,MAAM,CAAC,qBAAqB,eAC1B,2BAA2B,QAAQ,CACpC;AACD,QAAO,kBAAkB,QAAQ"}
|
|
1
|
+
{"version":3,"file":"stream.js","names":[],"sources":["../src/stream.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport type {\n BaseMessage,\n ToolMessage as CoreToolMessage,\n AIMessage as CoreAIMessage,\n} from \"@langchain/core/messages\";\nimport type {\n BagTemplate,\n ToolCallWithResult,\n DefaultToolCall,\n} from \"@langchain/langgraph-sdk\";\nimport type {\n UseStreamOptions,\n AcceptBaseMessages,\n ResolveStreamInterface,\n ResolveStreamOptions,\n InferBag,\n InferStateType,\n MessageMetadata,\n SubagentStreamInterface,\n HistoryWithBaseMessages,\n} from \"@langchain/langgraph-sdk/ui\";\nimport { useStreamLGP } from \"./stream.lgp.js\";\nimport { useStreamCustom } from \"./stream.custom.js\";\nimport type { UseStreamCustomOptions } from \"./types.js\";\n\nfunction isCustomOptions<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options:\n | UseStreamOptions<StateType, Bag>\n | UseStreamCustomOptions<StateType, Bag>,\n): options is UseStreamCustomOptions<StateType, Bag> {\n return \"transport\" in options;\n}\n\ntype ClassToolCallWithResult<T> =\n T extends ToolCallWithResult<infer TC, unknown, unknown>\n ? ToolCallWithResult<TC, CoreToolMessage, CoreAIMessage>\n : T;\n\nexport type ClassSubagentStreamInterface<\n StateType = Record<string, unknown>,\n ToolCall = DefaultToolCall,\n SubagentName extends string = string,\n> = Omit<\n SubagentStreamInterface<StateType, ToolCall, SubagentName>,\n \"messages\"\n> & {\n messages: BaseMessage[];\n};\n\n/**\n * Maps a stream interface to use @langchain/core BaseMessage class instances\n * instead of plain Message objects for the `messages` property, and remaps\n * tool call types to use @langchain/core message classes.\n */\ntype WithClassMessages<T> = Omit<\n T,\n | \"messages\"\n | \"history\"\n | \"getMessagesMetadata\"\n | \"toolCalls\"\n | \"getToolCalls\"\n | \"submit\"\n | \"subagents\"\n | \"activeSubagents\"\n | \"getSubagent\"\n | \"getSubagentsByType\"\n | \"getSubagentsByMessage\"\n> & {\n messages: BaseMessage[];\n getMessagesMetadata: (\n message: BaseMessage,\n index?: number,\n ) => MessageMetadata<Record<string, unknown>> | undefined;\n} & (\"history\" extends keyof T\n ? { history: HistoryWithBaseMessages<T[\"history\"]> }\n : unknown) &\n (\"submit\" extends keyof T\n ? {\n submit: T extends {\n submit: (values: infer V, options?: infer O) => infer Ret;\n }\n ? (\n values:\n | AcceptBaseMessages<Exclude<V, null | undefined>>\n | null\n | undefined,\n options?: O,\n ) => Ret\n : never;\n }\n : unknown) &\n (\"toolCalls\" extends keyof T\n ? {\n toolCalls: T extends { toolCalls: (infer TC)[] }\n ? ClassToolCallWithResult<TC>[]\n : never;\n }\n : unknown) &\n (\"getToolCalls\" extends keyof T\n ? {\n getToolCalls: T extends {\n getToolCalls: (message: infer _M) => (infer TC)[];\n }\n ? (message: CoreAIMessage) => ClassToolCallWithResult<TC>[]\n : never;\n }\n : unknown) &\n (\"subagents\" extends keyof T\n ? {\n subagents: T extends {\n subagents: Map<\n string,\n SubagentStreamInterface<infer S, infer TC, infer N>\n >;\n }\n ? Map<string, ClassSubagentStreamInterface<S, TC, N>>\n : never;\n activeSubagents: T extends {\n activeSubagents: SubagentStreamInterface<\n infer S,\n infer TC,\n infer N\n >[];\n }\n ? ClassSubagentStreamInterface<S, TC, N>[]\n : never;\n getSubagent: T extends {\n getSubagent: (\n id: string,\n ) => SubagentStreamInterface<infer S, infer TC, infer N> | undefined;\n }\n ? (\n toolCallId: string,\n ) => ClassSubagentStreamInterface<S, TC, N> | undefined\n : never;\n getSubagentsByType: T extends {\n getSubagentsByType: (\n type: string,\n ) => SubagentStreamInterface<infer S, infer TC, infer N>[];\n }\n ? (type: string) => ClassSubagentStreamInterface<S, TC, N>[]\n : never;\n getSubagentsByMessage: T extends {\n getSubagentsByMessage: (\n id: string,\n ) => SubagentStreamInterface<infer S, infer TC, infer N>[];\n }\n ? (messageId: string) => ClassSubagentStreamInterface<S, TC, N>[]\n : never;\n }\n : unknown);\n\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, subagent streams, and errors.\n *\n * ## Usage with ReactAgent (recommended for createAgent users)\n *\n * When using `createAgent` from `@langchain/langgraph`, you can pass `typeof agent` as the\n * type parameter to automatically infer tool call types:\n *\n * @example\n * ```typescript\n * // In your agent file (e.g., agent.ts)\n * import { createAgent, tool } from \"langchain\";\n * import { z } from \"zod\";\n *\n * const getWeather = tool(\n * async ({ location }) => `Weather in ${location}`,\n * { name: \"get_weather\", schema: z.object({ location: z.string() }) }\n * );\n *\n * export const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [getWeather],\n * });\n *\n * // In your React component\n * import { agent } from \"./agent\";\n *\n * function Chat() {\n * // Tool calls are automatically typed from the agent's tools!\n * const stream = useStream<typeof agent>({\n * assistantId: \"agent\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.toolCalls[0].call.name is typed as \"get_weather\"\n * // stream.toolCalls[0].call.args is typed as { location: string }\n * }\n * ```\n *\n * ## Usage with StateGraph (for custom LangGraph applications)\n *\n * When building custom graphs with `StateGraph`, embed your tool call types directly\n * in your state's messages property using `Message<MyToolCalls>`:\n *\n * @example\n * ```typescript\n * import { Message } from \"@langchain/langgraph-sdk\";\n *\n * // Define your tool call types as a discriminated union\n * type MyToolCalls =\n * | { name: \"search\"; args: { query: string }; id?: string }\n * | { name: \"calculate\"; args: { expression: string }; id?: string };\n *\n * // Embed tool call types in your state's messages\n * interface MyGraphState {\n * messages: Message<MyToolCalls>[];\n * context?: string;\n * }\n *\n * function Chat() {\n * const stream = useStream<MyGraphState>({\n * assistantId: \"my-graph\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.values is typed as MyGraphState\n * // stream.toolCalls[0].call.name is typed as \"search\" | \"calculate\"\n * }\n * ```\n *\n * @example\n * ```typescript\n * // With additional type configuration (interrupts, configurable)\n * interface MyGraphState {\n * messages: Message<MyToolCalls>[];\n * }\n *\n * function Chat() {\n * const stream = useStream<MyGraphState, {\n * InterruptType: { question: string };\n * ConfigurableType: { userId: string };\n * }>({\n * assistantId: \"my-graph\",\n * apiUrl: \"http://localhost:2024\",\n * });\n *\n * // stream.interrupt is typed as { question: string } | undefined\n * }\n * ```\n *\n * ## Usage with Deep Agents (subagent streaming, experimental)\n *\n * For agents that spawn subagents (nested graphs), use `filterSubagentMessages`\n * to keep the main message stream clean while tracking subagent activity separately:\n *\n * @example\n * ```typescript\n * import { useStream, SubagentStream } from \"@langchain/langgraph-sdk/react\";\n * import type { agent } from \"./agent\";\n *\n * function DeepAgentChat() {\n * const stream = useStream<typeof agent>({\n * assistantId: \"deepagent\",\n * apiUrl: \"http://localhost:2024\",\n * // Filter subagent messages from main stream\n * filterSubagentMessages: true,\n * });\n *\n * const handleSubmit = (content: string) => {\n * stream.submit(\n * { messages: [{ content, type: \"human\" }] },\n * { streamSubgraphs: true } // Enable subgraph streaming\n * );\n * };\n *\n * // Access subagent streams via stream.subagents (Map<string, SubagentStream>)\n * const subagentList = [...stream.subagents.values()];\n *\n * return (\n * <div>\n * {stream.messages.map((msg) => <Message key={msg.id} message={msg} />)}\n *\n * {subagentList.map((subagent) => (\n * <SubagentCard\n * key={subagent.id}\n * status={subagent.status} // \"pending\" | \"running\" | \"complete\" | \"error\"\n * messages={subagent.messages}\n * toolCalls={subagent.toolCalls}\n * />\n * ))}\n * </div>\n * );\n * }\n * ```\n *\n * @template T Either a ReactAgent type (with `~agentTypes`) or a state type (`Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport function useStream<\n T = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: ResolveStreamOptions<T, InferBag<T, Bag>>,\n): WithClassMessages<ResolveStreamInterface<T, InferBag<T, Bag>>>;\n\n/**\n * A React hook that provides seamless integration with LangGraph streaming capabilities.\n *\n * The `useStream` hook handles all the complexities of streaming, state management, and branching logic,\n * letting you focus on building great chat experiences. It provides automatic state management for\n * messages, interrupts, loading states, and errors.\n *\n * @template T Either a ReactAgent type (with `~agentTypes`) or a state type (`Record<string, unknown>`)\n * @template Bag Type configuration bag containing:\n * - `ConfigurableType`: Type for the `config.configurable` property\n * - `InterruptType`: Type for interrupt values\n * - `CustomEventType`: Type for custom events\n * - `UpdateType`: Type for the submit function updates\n *\n * @see {@link https://docs.langchain.com/langgraph-platform/use-stream-react | LangGraph React Integration Guide}\n */\nexport function useStream<\n T = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: UseStreamCustomOptions<InferStateType<T>, InferBag<T, Bag>>,\n): WithClassMessages<ResolveStreamInterface<T, InferBag<T, Bag>>>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useStream(options: any): any {\n // Store this in useState to make sure we're not changing the implementation in re-renders\n const [isCustom] = useState(isCustomOptions(options));\n\n if (isCustom) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useStreamCustom(options);\n }\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useStreamLGP(options);\n}\n"],"mappings":";;;;AA0BA,SAAS,gBAIP,SAGmD;AACnD,QAAO,eAAe;;AA6SxB,SAAgB,UAAU,SAAmB;CAE3C,MAAM,CAAC,YAAY,SAAS,gBAAgB,QAAQ,CAAC;AAErD,KAAI,SAEF,QAAO,gBAAgB,QAAQ;AAIjC,QAAO,aAAa,QAAQ"}
|
package/dist/stream.lgp.cjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
require("./_virtual/_rolldown/runtime.cjs");
|
|
2
3
|
const require_thread = require("./thread.cjs");
|
|
3
4
|
let react = require("react");
|
|
4
5
|
let _langchain_langgraph_sdk_client = require("@langchain/langgraph-sdk/client");
|
|
@@ -249,18 +250,7 @@ function useStreamLGP(options) {
|
|
|
249
250
|
const historyMessages = getMessages(historyValues);
|
|
250
251
|
const shouldReconstructSubagents = options.filterSubagentMessages && !stream.isLoading && !history.isLoading && historyMessages.length > 0;
|
|
251
252
|
(0, react.useEffect)(() => {
|
|
252
|
-
if (shouldReconstructSubagents) {
|
|
253
|
-
stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });
|
|
254
|
-
if (historyLimit !== false && threadId) {
|
|
255
|
-
const controller = new AbortController();
|
|
256
|
-
stream.fetchSubagentHistory(client.threads, threadId, {
|
|
257
|
-
messagesKey: options.messagesKey ?? "messages",
|
|
258
|
-
historyLimit: typeof historyLimit === "number" ? historyLimit : void 0,
|
|
259
|
-
signal: controller.signal
|
|
260
|
-
});
|
|
261
|
-
return () => controller.abort();
|
|
262
|
-
}
|
|
263
|
-
}
|
|
253
|
+
if (shouldReconstructSubagents) stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });
|
|
264
254
|
}, [shouldReconstructSubagents, historyMessages.length]);
|
|
265
255
|
const historyError = (() => {
|
|
266
256
|
const error = branchContext.threadHead?.tasks?.at(-1)?.error;
|
|
@@ -291,7 +281,7 @@ function useStreamLGP(options) {
|
|
|
291
281
|
const checkpointId = submitOptions?.checkpoint?.checkpoint_id;
|
|
292
282
|
setBranch(checkpointId != null ? branchContext.branchByCheckpoint[checkpointId]?.branch ?? "" : "");
|
|
293
283
|
const includeImplicitBranch = historyLimit === true || typeof historyLimit === "number";
|
|
294
|
-
const shouldRefetch =
|
|
284
|
+
const shouldRefetch = options.onFinish != null || includeImplicitBranch;
|
|
295
285
|
let callbackMeta;
|
|
296
286
|
let rejoinKey;
|
|
297
287
|
let usableThreadId = threadId;
|
|
@@ -379,7 +369,7 @@ function useStreamLGP(options) {
|
|
|
379
369
|
options.onFinish?.(lastHead, callbackMeta);
|
|
380
370
|
return null;
|
|
381
371
|
}
|
|
382
|
-
}
|
|
372
|
+
}
|
|
383
373
|
},
|
|
384
374
|
onError(error) {
|
|
385
375
|
options.onError?.(error, callbackMeta);
|
|
@@ -451,7 +441,6 @@ function useStreamLGP(options) {
|
|
|
451
441
|
thread_id: threadId,
|
|
452
442
|
run_id: runId
|
|
453
443
|
};
|
|
454
|
-
const shouldRefetchJoin = historyLimit === true || typeof historyLimit === "number" || (0, _langchain_langgraph_sdk_ui.onFinishRequiresThreadState)(options.onFinish);
|
|
455
444
|
await stream.start(async (signal) => {
|
|
456
445
|
threadIdStreamingRef.current = threadId;
|
|
457
446
|
const stream = client.runs.joinStream(threadId, runId, {
|
|
@@ -473,10 +462,6 @@ function useStreamLGP(options) {
|
|
|
473
462
|
},
|
|
474
463
|
async onSuccess() {
|
|
475
464
|
runMetadataStorage?.removeItem(`lg:stream:${threadId}`);
|
|
476
|
-
if (!shouldRefetchJoin) {
|
|
477
|
-
if (options.onFinish != null && !(0, _langchain_langgraph_sdk_ui.onFinishRequiresThreadState)(options.onFinish)) options.onFinish(void 0, callbackMeta);
|
|
478
|
-
return;
|
|
479
|
-
}
|
|
480
465
|
const lastHead = (await history.mutate(threadId))?.at(0);
|
|
481
466
|
if (lastHead) options.onFinish?.(lastHead, callbackMeta);
|
|
482
467
|
},
|
|
@@ -539,27 +524,29 @@ function useStreamLGP(options) {
|
|
|
539
524
|
}, [reconnectKey]);
|
|
540
525
|
const error = stream.error ?? historyError ?? history.error;
|
|
541
526
|
const values = stream.values ?? historyValues;
|
|
542
|
-
const
|
|
527
|
+
const toolsRef = (0, react.useRef)(options.tools);
|
|
528
|
+
toolsRef.current = options.tools;
|
|
529
|
+
const onToolRef = (0, react.useRef)(options.onTool);
|
|
530
|
+
onToolRef.current = options.onTool;
|
|
531
|
+
const handledBrowserToolsRef = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
543
532
|
(0, react.useEffect)(() => {
|
|
544
|
-
|
|
533
|
+
handledBrowserToolsRef.current.clear();
|
|
545
534
|
}, [threadId]);
|
|
546
535
|
(0, react.useEffect)(() => {
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
values
|
|
562
|
-
]);
|
|
536
|
+
const tools = toolsRef.current;
|
|
537
|
+
if (!tools?.length) return;
|
|
538
|
+
const interrupts = values?.__interrupt__;
|
|
539
|
+
if (!Array.isArray(interrupts) || interrupts.length === 0) return;
|
|
540
|
+
for (const interrupt of interrupts) {
|
|
541
|
+
if (!(0, _langchain_langgraph_sdk.isHeadlessToolInterrupt)(interrupt.value)) continue;
|
|
542
|
+
const interruptId = interrupt.id ?? interrupt.value.toolCall.id ?? "";
|
|
543
|
+
if (handledBrowserToolsRef.current.has(interruptId)) continue;
|
|
544
|
+
handledBrowserToolsRef.current.add(interruptId);
|
|
545
|
+
(0, _langchain_langgraph_sdk.handleHeadlessToolInterrupt)(interrupt.value, tools, onToolRef.current).then((result) => {
|
|
546
|
+
submit(null, { command: { resume: result.toolCallId ? { [result.toolCallId]: result.value } : result.value } });
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
}, [values, submit]);
|
|
563
550
|
return {
|
|
564
551
|
get values() {
|
|
565
552
|
trackStreamMode("values");
|
|
@@ -585,10 +572,14 @@ function useStreamLGP(options) {
|
|
|
585
572
|
return branchContext.branchTree;
|
|
586
573
|
},
|
|
587
574
|
get interrupts() {
|
|
588
|
-
if (values != null && "__interrupt__" in values && Array.isArray(values.__interrupt__))
|
|
575
|
+
if (values != null && "__interrupt__" in values && Array.isArray(values.__interrupt__)) {
|
|
576
|
+
const valueInterrupts = values.__interrupt__;
|
|
577
|
+
if (valueInterrupts.length === 0) return [{ when: "breakpoint" }];
|
|
578
|
+
return valueInterrupts;
|
|
579
|
+
}
|
|
589
580
|
if (stream.isLoading) return [];
|
|
590
|
-
const
|
|
591
|
-
if (
|
|
581
|
+
const allInterrupts = (branchContext.threadHead?.tasks ?? []).flatMap((t) => t.interrupts ?? []);
|
|
582
|
+
if (allInterrupts.length > 0) return allInterrupts;
|
|
592
583
|
if (!(branchContext.threadHead?.next ?? []).length || error != null) return [];
|
|
593
584
|
return [{ when: "breakpoint" }];
|
|
594
585
|
},
|