langchain 1.0.3 → 1.0.5
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/CHANGELOG.md +21 -0
- package/dist/agents/ReactAgent.cjs +15 -17
- package/dist/agents/ReactAgent.cjs.map +1 -1
- package/dist/agents/ReactAgent.d.cts +3 -3
- package/dist/agents/ReactAgent.d.cts.map +1 -1
- package/dist/agents/ReactAgent.d.ts +3 -3
- package/dist/agents/ReactAgent.d.ts.map +1 -1
- package/dist/agents/ReactAgent.js +15 -17
- package/dist/agents/ReactAgent.js.map +1 -1
- package/dist/agents/annotation.cjs +6 -4
- package/dist/agents/annotation.cjs.map +1 -1
- package/dist/agents/annotation.js +7 -5
- package/dist/agents/annotation.js.map +1 -1
- package/dist/agents/middleware/contextEditing.cjs +302 -33
- package/dist/agents/middleware/contextEditing.cjs.map +1 -1
- package/dist/agents/middleware/contextEditing.d.cts +125 -41
- package/dist/agents/middleware/contextEditing.d.cts.map +1 -1
- package/dist/agents/middleware/contextEditing.d.ts +125 -41
- package/dist/agents/middleware/contextEditing.d.ts.map +1 -1
- package/dist/agents/middleware/contextEditing.js +302 -33
- package/dist/agents/middleware/contextEditing.js.map +1 -1
- package/dist/agents/middleware/dynamicSystemPrompt.d.cts.map +1 -1
- package/dist/agents/middleware/dynamicSystemPrompt.d.ts.map +1 -1
- package/dist/agents/middleware/hitl.d.cts.map +1 -1
- package/dist/agents/middleware/hitl.d.ts.map +1 -1
- package/dist/agents/middleware/index.cjs +2 -0
- package/dist/agents/middleware/index.js +2 -0
- package/dist/agents/middleware/modelCallLimit.cjs +6 -2
- package/dist/agents/middleware/modelCallLimit.cjs.map +1 -1
- package/dist/agents/middleware/modelCallLimit.d.cts +8 -8
- package/dist/agents/middleware/modelCallLimit.d.cts.map +1 -1
- package/dist/agents/middleware/modelCallLimit.d.ts +8 -8
- package/dist/agents/middleware/modelCallLimit.d.ts.map +1 -1
- package/dist/agents/middleware/modelCallLimit.js +6 -2
- package/dist/agents/middleware/modelCallLimit.js.map +1 -1
- package/dist/agents/middleware/modelFallback.cjs +2 -2
- package/dist/agents/middleware/modelFallback.cjs.map +1 -1
- package/dist/agents/middleware/modelFallback.d.cts +2 -2
- package/dist/agents/middleware/modelFallback.d.cts.map +1 -1
- package/dist/agents/middleware/modelFallback.d.ts +2 -2
- package/dist/agents/middleware/modelFallback.d.ts.map +1 -1
- package/dist/agents/middleware/modelFallback.js +2 -2
- package/dist/agents/middleware/modelFallback.js.map +1 -1
- package/dist/agents/middleware/pii.cjs +445 -0
- package/dist/agents/middleware/pii.cjs.map +1 -0
- package/dist/agents/middleware/pii.d.cts +216 -0
- package/dist/agents/middleware/pii.d.cts.map +1 -0
- package/dist/agents/middleware/pii.d.ts +216 -0
- package/dist/agents/middleware/pii.d.ts.map +1 -0
- package/dist/agents/middleware/pii.js +436 -0
- package/dist/agents/middleware/pii.js.map +1 -0
- package/dist/agents/middleware/piiRedaction.cjs +2 -1
- package/dist/agents/middleware/piiRedaction.cjs.map +1 -1
- package/dist/agents/middleware/piiRedaction.d.cts +4 -1
- package/dist/agents/middleware/piiRedaction.d.cts.map +1 -1
- package/dist/agents/middleware/piiRedaction.d.ts +4 -1
- package/dist/agents/middleware/piiRedaction.d.ts.map +1 -1
- package/dist/agents/middleware/piiRedaction.js +2 -1
- package/dist/agents/middleware/piiRedaction.js.map +1 -1
- package/dist/agents/middleware/promptCaching.d.cts.map +1 -1
- package/dist/agents/middleware/promptCaching.d.ts.map +1 -1
- package/dist/agents/middleware/summarization.cjs +263 -52
- package/dist/agents/middleware/summarization.cjs.map +1 -1
- package/dist/agents/middleware/summarization.d.cts +384 -26
- package/dist/agents/middleware/summarization.d.cts.map +1 -1
- package/dist/agents/middleware/summarization.d.ts +384 -26
- package/dist/agents/middleware/summarization.d.ts.map +1 -1
- package/dist/agents/middleware/summarization.js +263 -55
- package/dist/agents/middleware/summarization.js.map +1 -1
- package/dist/agents/middleware/todoListMiddleware.d.cts.map +1 -1
- package/dist/agents/middleware/toolCallLimit.cjs +36 -27
- package/dist/agents/middleware/toolCallLimit.cjs.map +1 -1
- package/dist/agents/middleware/toolCallLimit.d.cts +3 -1
- package/dist/agents/middleware/toolCallLimit.d.cts.map +1 -1
- package/dist/agents/middleware/toolCallLimit.d.ts +3 -1
- package/dist/agents/middleware/toolCallLimit.d.ts.map +1 -1
- package/dist/agents/middleware/toolCallLimit.js +36 -27
- package/dist/agents/middleware/toolCallLimit.js.map +1 -1
- package/dist/agents/middleware/toolEmulator.cjs +118 -0
- package/dist/agents/middleware/toolEmulator.cjs.map +1 -0
- package/dist/agents/middleware/toolEmulator.d.cts +76 -0
- package/dist/agents/middleware/toolEmulator.d.cts.map +1 -0
- package/dist/agents/middleware/toolEmulator.d.ts +76 -0
- package/dist/agents/middleware/toolEmulator.d.ts.map +1 -0
- package/dist/agents/middleware/toolEmulator.js +117 -0
- package/dist/agents/middleware/toolEmulator.js.map +1 -0
- package/dist/agents/middleware/utils.cjs +4 -0
- package/dist/agents/middleware/utils.cjs.map +1 -1
- package/dist/agents/middleware/utils.d.cts.map +1 -1
- package/dist/agents/middleware/utils.d.ts.map +1 -1
- package/dist/agents/middleware/utils.js +4 -0
- package/dist/agents/middleware/utils.js.map +1 -1
- package/dist/agents/nodes/AgentNode.cjs +1 -5
- package/dist/agents/nodes/AgentNode.cjs.map +1 -1
- package/dist/agents/nodes/AgentNode.js +2 -6
- package/dist/agents/nodes/AgentNode.js.map +1 -1
- package/dist/agents/responses.cjs +0 -1
- package/dist/agents/responses.js +1 -1
- package/dist/agents/runtime.d.cts +5 -5
- package/dist/agents/runtime.d.cts.map +1 -1
- package/dist/agents/runtime.d.ts +5 -5
- package/dist/agents/runtime.d.ts.map +1 -1
- package/dist/index.cjs +22 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/package.json +10 -9
- package/dist/agents/middleware/callLimit.cjs +0 -130
- package/dist/agents/middleware/callLimit.cjs.map +0 -1
- package/dist/agents/middleware/callLimit.d.cts +0 -119
- package/dist/agents/middleware/callLimit.d.cts.map +0 -1
- package/dist/agents/middleware/callLimit.d.ts +0 -119
- package/dist/agents/middleware/callLimit.d.ts.map +0 -1
- package/dist/agents/middleware/callLimit.js +0 -129
- package/dist/agents/middleware/callLimit.js.map +0 -1
- package/dist/agents/middleware/index.d.cts +0 -15
- package/dist/agents/middleware/index.d.ts +0 -14
- package/dist/agents/tools.d.cts +0 -9
- package/dist/agents/tools.d.cts.map +0 -1
- package/dist/agents/tools.d.ts +0 -9
- package/dist/agents/tools.d.ts.map +0 -1
- package/dist/embeddings/cache_backed.cjs +0 -140
- package/dist/embeddings/cache_backed.cjs.map +0 -1
- package/dist/embeddings/cache_backed.d.cts +0 -107
- package/dist/embeddings/cache_backed.d.cts.map +0 -1
- package/dist/embeddings/cache_backed.d.ts +0 -107
- package/dist/embeddings/cache_backed.d.ts.map +0 -1
- package/dist/embeddings/cache_backed.js +0 -134
- package/dist/embeddings/cache_backed.js.map +0 -1
- package/dist/embeddings/fake.cjs +0 -22
- package/dist/embeddings/fake.cjs.map +0 -1
- package/dist/embeddings/fake.d.cts +0 -1
- package/dist/embeddings/fake.d.ts +0 -1
- package/dist/embeddings/fake.js +0 -12
- package/dist/embeddings/fake.js.map +0 -1
- package/dist/node_modules/.pnpm/eventemitter3@4.0.7/node_modules/eventemitter3/index.cjs +0 -248
- package/dist/node_modules/.pnpm/eventemitter3@4.0.7/node_modules/eventemitter3/index.cjs.map +0 -1
- package/dist/node_modules/.pnpm/eventemitter3@4.0.7/node_modules/eventemitter3/index.js +0 -244
- package/dist/node_modules/.pnpm/eventemitter3@4.0.7/node_modules/eventemitter3/index.js.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/client.cjs +0 -3096
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/client.cjs.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/client.js +0 -3095
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/client.js.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/env.cjs +0 -12
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/env.cjs.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/env.js +0 -12
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/env.js.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/experimental/otel/constants.cjs +0 -71
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/experimental/otel/constants.cjs.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/experimental/otel/constants.js +0 -38
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/experimental/otel/constants.js.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/experimental/otel/translator.cjs +0 -221
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/experimental/otel/translator.cjs.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/experimental/otel/translator.js +0 -221
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/experimental/otel/translator.js.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/index.cjs +0 -11
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/index.cjs.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/index.js +0 -11
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/index.js.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/run_trees.cjs +0 -703
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/run_trees.cjs.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/run_trees.js +0 -702
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/run_trees.js.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/singletons/constants.cjs +0 -7
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/singletons/constants.cjs.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/singletons/constants.js +0 -6
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/singletons/constants.js.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/singletons/fetch.cjs +0 -29
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/singletons/fetch.cjs.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/singletons/fetch.js +0 -28
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/singletons/fetch.js.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/singletons/otel.cjs +0 -115
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/singletons/otel.cjs.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/singletons/otel.js +0 -113
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/singletons/otel.js.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/_uuid.cjs +0 -14
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/_uuid.cjs.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/_uuid.js +0 -13
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/_uuid.js.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/async_caller.cjs +0 -95
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/async_caller.cjs.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/async_caller.js +0 -95
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/async_caller.js.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/env.cjs +0 -136
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/env.cjs.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/env.js +0 -131
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/env.js.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/error.cjs +0 -102
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/error.cjs.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/error.js +0 -99
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/error.js.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/fast-safe-stringify/index.cjs +0 -140
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/fast-safe-stringify/index.cjs.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/fast-safe-stringify/index.js +0 -140
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/fast-safe-stringify/index.js.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/messages.cjs +0 -18
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/messages.cjs.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/messages.js +0 -16
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/messages.js.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/project.cjs +0 -10
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/project.cjs.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/project.js +0 -10
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/project.js.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/prompts.cjs +0 -30
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/prompts.cjs.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/prompts.js +0 -30
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/prompts.js.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/warn.cjs +0 -13
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/warn.cjs.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/warn.js +0 -12
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/dist/utils/warn.js.map +0 -1
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/index.cjs +0 -6
- package/dist/node_modules/.pnpm/langsmith@0.3.74_@opentelemetry_api@1.9.0_openai@5.12.2_ws@8.18.3_bufferutil@4.0.9_utf-8-validate@6.0.5__zod@3.25.76_/node_modules/langsmith/index.js +0 -6
- package/dist/node_modules/.pnpm/p-finally@1.0.0/node_modules/p-finally/index.cjs +0 -27
- package/dist/node_modules/.pnpm/p-finally@1.0.0/node_modules/p-finally/index.cjs.map +0 -1
- package/dist/node_modules/.pnpm/p-finally@1.0.0/node_modules/p-finally/index.js +0 -23
- package/dist/node_modules/.pnpm/p-finally@1.0.0/node_modules/p-finally/index.js.map +0 -1
- package/dist/node_modules/.pnpm/p-queue@6.6.2/node_modules/p-queue/dist/index.cjs +0 -267
- package/dist/node_modules/.pnpm/p-queue@6.6.2/node_modules/p-queue/dist/index.cjs.map +0 -1
- package/dist/node_modules/.pnpm/p-queue@6.6.2/node_modules/p-queue/dist/index.js +0 -263
- package/dist/node_modules/.pnpm/p-queue@6.6.2/node_modules/p-queue/dist/index.js.map +0 -1
- package/dist/node_modules/.pnpm/p-queue@6.6.2/node_modules/p-queue/dist/lower-bound.cjs +0 -32
- package/dist/node_modules/.pnpm/p-queue@6.6.2/node_modules/p-queue/dist/lower-bound.cjs.map +0 -1
- package/dist/node_modules/.pnpm/p-queue@6.6.2/node_modules/p-queue/dist/lower-bound.js +0 -28
- package/dist/node_modules/.pnpm/p-queue@6.6.2/node_modules/p-queue/dist/lower-bound.js.map +0 -1
- package/dist/node_modules/.pnpm/p-queue@6.6.2/node_modules/p-queue/dist/priority-queue.cjs +0 -49
- package/dist/node_modules/.pnpm/p-queue@6.6.2/node_modules/p-queue/dist/priority-queue.cjs.map +0 -1
- package/dist/node_modules/.pnpm/p-queue@6.6.2/node_modules/p-queue/dist/priority-queue.js +0 -45
- package/dist/node_modules/.pnpm/p-queue@6.6.2/node_modules/p-queue/dist/priority-queue.js.map +0 -1
- package/dist/node_modules/.pnpm/p-retry@4.6.2/node_modules/p-retry/index.cjs +0 -83
- package/dist/node_modules/.pnpm/p-retry@4.6.2/node_modules/p-retry/index.cjs.map +0 -1
- package/dist/node_modules/.pnpm/p-retry@4.6.2/node_modules/p-retry/index.js +0 -79
- package/dist/node_modules/.pnpm/p-retry@4.6.2/node_modules/p-retry/index.js.map +0 -1
- package/dist/node_modules/.pnpm/p-timeout@3.2.0/node_modules/p-timeout/index.cjs +0 -52
- package/dist/node_modules/.pnpm/p-timeout@3.2.0/node_modules/p-timeout/index.cjs.map +0 -1
- package/dist/node_modules/.pnpm/p-timeout@3.2.0/node_modules/p-timeout/index.js +0 -48
- package/dist/node_modules/.pnpm/p-timeout@3.2.0/node_modules/p-timeout/index.js.map +0 -1
- package/dist/node_modules/.pnpm/retry@0.13.1/node_modules/retry/index.cjs +0 -16
- package/dist/node_modules/.pnpm/retry@0.13.1/node_modules/retry/index.cjs.map +0 -1
- package/dist/node_modules/.pnpm/retry@0.13.1/node_modules/retry/index.js +0 -13
- package/dist/node_modules/.pnpm/retry@0.13.1/node_modules/retry/index.js.map +0 -1
- package/dist/node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry.cjs +0 -77
- package/dist/node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry.cjs.map +0 -1
- package/dist/node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry.js +0 -74
- package/dist/node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry.js.map +0 -1
- package/dist/node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry_operation.cjs +0 -115
- package/dist/node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry_operation.cjs.map +0 -1
- package/dist/node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry_operation.js +0 -112
- package/dist/node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry_operation.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/classes/comparator.cjs +0 -90
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/classes/comparator.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/classes/comparator.js +0 -86
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/classes/comparator.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/classes/range.cjs +0 -294
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/classes/range.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/classes/range.js +0 -290
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/classes/range.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/classes/semver.cjs +0 -191
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/classes/semver.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/classes/semver.js +0 -187
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/classes/semver.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/clean.cjs +0 -24
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/clean.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/clean.js +0 -20
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/clean.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/cmp.cjs +0 -51
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/cmp.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/cmp.js +0 -47
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/cmp.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/coerce.cjs +0 -48
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/coerce.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/coerce.js +0 -44
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/coerce.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/compare-build.cjs +0 -25
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/compare-build.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/compare-build.js +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/compare-build.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/compare-loose.cjs +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/compare-loose.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/compare-loose.js +0 -17
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/compare-loose.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/compare.cjs +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/compare.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/compare.js +0 -17
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/compare.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/diff.cjs +0 -43
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/diff.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/diff.js +0 -39
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/diff.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/eq.cjs +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/eq.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/eq.js +0 -17
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/eq.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/gt.cjs +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/gt.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/gt.js +0 -17
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/gt.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/gte.cjs +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/gte.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/gte.js +0 -17
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/gte.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/inc.cjs +0 -32
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/inc.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/inc.js +0 -28
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/inc.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/lt.cjs +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/lt.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/lt.js +0 -17
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/lt.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/lte.cjs +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/lte.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/lte.js +0 -17
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/lte.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/major.cjs +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/major.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/major.js +0 -17
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/major.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/minor.cjs +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/minor.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/minor.js +0 -17
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/minor.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/neq.cjs +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/neq.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/neq.js +0 -17
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/neq.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/parse.cjs +0 -29
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/parse.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/parse.js +0 -25
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/parse.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/patch.cjs +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/patch.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/patch.js +0 -17
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/patch.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/prerelease.cjs +0 -24
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/prerelease.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/prerelease.js +0 -20
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/prerelease.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/rcompare.cjs +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/rcompare.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/rcompare.js +0 -17
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/rcompare.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/rsort.cjs +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/rsort.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/rsort.js +0 -17
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/rsort.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/satisfies.cjs +0 -28
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/satisfies.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/satisfies.js +0 -24
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/satisfies.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/sort.cjs +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/sort.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/sort.js +0 -17
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/sort.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/valid.cjs +0 -24
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/valid.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/valid.js +0 -20
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/functions/valid.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/index.cjs +0 -146
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/index.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/index.js +0 -142
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/index.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/constants.cjs +0 -41
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/constants.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/constants.js +0 -37
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/constants.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/debug.cjs +0 -19
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/debug.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/debug.js +0 -15
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/debug.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/identifiers.cjs +0 -32
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/identifiers.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/identifiers.js +0 -28
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/identifiers.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/lrucache.cjs +0 -47
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/lrucache.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/lrucache.js +0 -43
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/lrucache.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/parse-options.cjs +0 -25
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/parse-options.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/parse-options.js +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/parse-options.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/re.cjs +0 -94
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/re.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/re.js +0 -90
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/internal/re.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/gtr.cjs +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/gtr.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/gtr.js +0 -17
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/gtr.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/intersects.cjs +0 -25
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/intersects.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/intersects.js +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/intersects.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/ltr.cjs +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/ltr.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/ltr.js +0 -17
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/ltr.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/max-satisfying.cjs +0 -41
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/max-satisfying.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/max-satisfying.js +0 -37
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/max-satisfying.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/min-satisfying.cjs +0 -41
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/min-satisfying.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/min-satisfying.js +0 -37
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/min-satisfying.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/min-version.cjs +0 -55
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/min-version.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/min-version.js +0 -51
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/min-version.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/outside.cjs +0 -74
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/outside.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/outside.js +0 -70
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/outside.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/simplify.cjs +0 -48
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/simplify.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/simplify.js +0 -44
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/simplify.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/subset.cjs +0 -112
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/subset.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/subset.js +0 -108
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/subset.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/to-comparators.cjs +0 -21
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/to-comparators.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/to-comparators.js +0 -17
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/to-comparators.js.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/valid.cjs +0 -27
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/valid.cjs.map +0 -1
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/valid.js +0 -23
- package/dist/node_modules/.pnpm/semver@7.7.2/node_modules/semver/ranges/valid.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolCallLimit.js","names":["toolName: string | undefined","threadCount: number","runCount: number","threadLimit: number | undefined","runLimit: number | undefined","exceededLimits: string[]","options: ToolCallLimitConfig","toolCall: { name?: string }","toolCalls: ToolCall[]","allowed: ToolCall[]","blocked: ToolCall[]","blocked","allowed","artificialMessages: Array<ToolMessage | AIMessage>","otherTools: ToolCall[]"],"sources":["../../../src/agents/middleware/toolCallLimit.ts"],"sourcesContent":["import { AIMessage, ToolMessage } from \"@langchain/core/messages\";\nimport { z } from \"zod/v3\";\nimport type { InferInteropZodInput } from \"@langchain/core/utils/types\";\nimport type { ToolCall } from \"@langchain/core/messages/tool\";\n\nimport { createMiddleware } from \"../middleware.js\";\n\n/**\n * Build the error message content for ToolMessage when limit is exceeded.\n *\n * This message is sent to the model, so it should not reference thread/run concepts\n * that the model has no notion of.\n *\n * @param toolName - Tool name being limited (if specific tool), or undefined for all tools.\n * @param threadCount - Current thread tool call count.\n * @param runCount - Current run tool call count.\n * @param threadLimit - Thread tool call limit (if set).\n * @param runLimit - Run tool call limit (if set).\n * @returns A concise message. If only run limit is exceeded (not thread limit),\n * returns a simple \"limit exceeded\" message without instructing model to stop.\n * If thread limit is exceeded, includes instruction not to call again.\n */\nfunction buildToolMessageContent(\n toolName: string | undefined,\n threadCount: number,\n runCount: number,\n threadLimit: number | undefined,\n runLimit: number | undefined\n): string {\n // Check if thread limit is exceeded\n const threadExceeded = threadLimit !== undefined && threadCount > threadLimit;\n // Check if only run limit is exceeded (not thread limit)\n const onlyRunExceeded =\n runLimit !== undefined && runCount > runLimit && !threadExceeded;\n\n if (onlyRunExceeded) {\n // Run limit exceeded but thread limit not exceeded - simpler message\n if (toolName) {\n return `Tool call limit exceeded for '${toolName}'.`;\n }\n return \"Tool call limit exceeded.\";\n }\n\n // Thread limit exceeded (or both) - include instruction not to call again\n if (toolName) {\n return `Tool call limit exceeded. Do not call '${toolName}' again.`;\n }\n return \"Tool call limit exceeded. Do not make additional tool calls.\";\n}\n\n/**\n * Build the final AI message content for 'end' behavior.\n *\n * This message is displayed to the user, so it should include detailed information\n * about which limits were exceeded.\n *\n * @param threadCount - Current thread tool call count.\n * @param runCount - Current run tool call count.\n * @param threadLimit - Thread tool call limit (if set).\n * @param runLimit - Run tool call limit (if set).\n * @param toolName - Tool name being limited (if specific tool), or undefined for all tools.\n * @returns A formatted message describing which limits were exceeded.\n */\nfunction buildFinalAIMessageContent(\n threadCount: number,\n runCount: number,\n threadLimit: number | undefined,\n runLimit: number | undefined,\n toolName: string | undefined\n): string {\n const toolDesc = toolName ? `'${toolName}' tool` : \"Tool\";\n const exceededLimits: string[] = [];\n\n if (threadLimit !== undefined && threadCount > threadLimit) {\n exceededLimits.push(\n `thread limit exceeded (${threadCount}/${threadLimit} calls)`\n );\n }\n if (runLimit !== undefined && runCount > runLimit) {\n exceededLimits.push(`run limit exceeded (${runCount}/${runLimit} calls)`);\n }\n\n const limitsText = exceededLimits.join(\" and \");\n return `${toolDesc} call limit reached: ${limitsText}.`;\n}\n\n/**\n * Exception raised when tool call limits are exceeded.\n *\n * This exception is raised when the configured exit behavior is 'error'\n * and either the thread or run tool call limit has been exceeded.\n */\nexport class ToolCallLimitExceededError extends Error {\n /**\n * Current thread tool call count.\n */\n threadCount: number;\n /**\n * Current run tool call count.\n */\n runCount: number;\n /**\n * Thread tool call limit (if set).\n */\n threadLimit: number | undefined;\n /**\n * Run tool call limit (if set).\n */\n runLimit: number | undefined;\n /**\n * Tool name being limited (if specific tool), or undefined for all tools.\n */\n toolName: string | undefined;\n\n constructor(\n threadCount: number,\n runCount: number,\n threadLimit: number | undefined,\n runLimit: number | undefined,\n toolName: string | undefined = undefined\n ) {\n const message = buildFinalAIMessageContent(\n threadCount,\n runCount,\n threadLimit,\n runLimit,\n toolName\n );\n super(message);\n\n this.name = \"ToolCallLimitExceededError\";\n this.threadCount = threadCount;\n this.runCount = runCount;\n this.threadLimit = threadLimit;\n this.runLimit = runLimit;\n this.toolName = toolName;\n }\n}\n\n/**\n * Options for configuring the Tool Call Limit middleware.\n */\nexport const ToolCallLimitOptionsSchema = z.object({\n /**\n * Name of the specific tool to limit. If undefined, limits apply to all tools.\n */\n toolName: z.string().optional(),\n /**\n * Maximum number of tool calls allowed per thread.\n * undefined means no limit.\n */\n threadLimit: z.number().optional(),\n /**\n * Maximum number of tool calls allowed per run.\n * undefined means no limit.\n */\n runLimit: z.number().optional(),\n /**\n * What to do when limits are exceeded.\n * - \"continue\": Block exceeded tools with error messages, let other tools continue (default)\n * - \"error\": Raise a ToolCallLimitExceededError exception\n * - \"end\": Stop execution immediately, injecting a ToolMessage and an AI message\n * for the single tool call that exceeded the limit. Raises NotImplementedError\n * if there are multiple tool calls.\n */\n exitBehavior: z.enum([\"continue\", \"error\", \"end\"]).default(\"continue\"),\n});\n\nexport type ToolCallLimitConfig = InferInteropZodInput<\n typeof ToolCallLimitOptionsSchema\n>;\n\n/**\n * Middleware state schema to track the number of model calls made at the thread and run level.\n */\nconst stateSchema = z.object({\n threadToolCallCount: z.record(z.string(), z.number()).default({}),\n runToolCallCount: z.record(z.string(), z.number()).default({}),\n});\n\nconst DEFAULT_TOOL_COUNT_KEY = \"__all__\";\n\n/**\n * Middleware that tracks tool call counts and enforces limits.\n *\n * This middleware monitors the number of tool calls made during agent execution\n * and can terminate the agent when specified limits are reached. It supports\n * both thread-level and run-level call counting with configurable exit behaviors.\n *\n * Thread-level: The middleware counts all tool calls in the entire message history\n * and persists this count across multiple runs (invocations) of the agent.\n *\n * Run-level: The middleware counts tool calls made after the last HumanMessage,\n * representing the current run (invocation) of the agent.\n *\n * @param options - Configuration options for the middleware\n * @param options.toolName - Name of the specific tool to limit. If undefined, limits apply to all tools.\n * @param options.threadLimit - Maximum number of tool calls allowed per thread. undefined means no limit.\n * @param options.runLimit - Maximum number of tool calls allowed per run. undefined means no limit.\n * @param options.exitBehavior - What to do when limits are exceeded.\n * - \"continue\": Block exceeded tools with error messages, let other tools continue. Model decides when to end. (default)\n * - \"error\": Raise a ToolCallLimitExceededError exception\n * - \"end\": Stop execution immediately with a ToolMessage + AI message for the single tool call that exceeded the limit. Raises NotImplementedError if there are multiple tool calls.\n *\n * @throws {Error} If both limits are undefined.\n * @throws {NotImplementedError} If exitBehavior is \"end\" and there are multiple tool calls.\n *\n * @example Continue execution with blocked tools (default)\n * ```ts\n * import { toolCallLimitMiddleware } from \"@langchain/langchain/agents/middleware\";\n * import { createAgent } from \"@langchain/langchain/agents\";\n *\n * // Block exceeded tools but let other tools and model continue\n * const limiter = toolCallLimitMiddleware({\n * threadLimit: 20,\n * runLimit: 10,\n * exitBehavior: \"continue\", // default\n * });\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * middleware: [limiter]\n * });\n * ```\n *\n * @example Stop immediately when limit exceeded\n * ```ts\n * // End execution immediately with an AI message\n * const limiter = toolCallLimitMiddleware({\n * runLimit: 5,\n * exitBehavior: \"end\"\n * });\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * middleware: [limiter]\n * });\n * ```\n *\n * @example Raise exception on limit\n * ```ts\n * // Strict limit with exception handling\n * const limiter = toolCallLimitMiddleware({\n * toolName: \"search\",\n * threadLimit: 5,\n * exitBehavior: \"error\"\n * });\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * middleware: [limiter]\n * });\n *\n * try {\n * const result = await agent.invoke({ messages: [new HumanMessage(\"Task\")] });\n * } catch (error) {\n * if (error instanceof ToolCallLimitExceededError) {\n * console.log(`Search limit exceeded: ${error}`);\n * }\n * }\n * ```\n */\nexport function toolCallLimitMiddleware(options: ToolCallLimitConfig) {\n /**\n * Validate that at least one limit is specified\n */\n if (options.threadLimit === undefined && options.runLimit === undefined) {\n throw new Error(\n \"At least one limit must be specified (threadLimit or runLimit)\"\n );\n }\n\n /**\n * Apply default for exitBehavior\n */\n const exitBehavior = options.exitBehavior ?? \"continue\";\n\n /**\n * Generate the middleware name based on the tool name\n */\n const middlewareName = options.toolName\n ? `ToolCallLimitMiddleware[${options.toolName}]`\n : \"ToolCallLimitMiddleware\";\n\n return createMiddleware({\n name: middlewareName,\n stateSchema,\n afterModel: {\n canJumpTo: [\"end\"],\n hook: (state) => {\n /**\n * Get the last AI message to check for tool calls\n */\n const lastAIMessage = [...state.messages]\n .reverse()\n .find(AIMessage.isInstance);\n\n if (!lastAIMessage || !lastAIMessage.tool_calls) {\n return undefined;\n }\n\n /**\n * Helper to check if limit would be exceeded by one more call\n */\n const wouldExceedLimit = (\n threadCount: number,\n runCount: number\n ): boolean => {\n return (\n (options.threadLimit !== undefined &&\n threadCount + 1 > options.threadLimit) ||\n (options.runLimit !== undefined && runCount + 1 > options.runLimit)\n );\n };\n\n /**\n * Helper to check if a tool call matches our filter\n */\n const matchesToolFilter = (toolCall: { name?: string }): boolean => {\n return (\n options.toolName === undefined || toolCall.name === options.toolName\n );\n };\n\n /**\n * Separate tool calls into allowed and blocked based on limits\n */\n const separateToolCalls = (\n toolCalls: ToolCall[],\n threadCount: number,\n runCount: number\n ): {\n allowed: ToolCall[];\n blocked: ToolCall[];\n finalThreadCount: number;\n finalRunCount: number;\n } => {\n const allowed: ToolCall[] = [];\n const blocked: ToolCall[] = [];\n let tempThreadCount = threadCount;\n let tempRunCount = runCount;\n\n for (const toolCall of toolCalls) {\n if (!matchesToolFilter(toolCall)) {\n // Tool call doesn't match our filter, skip it\n continue;\n }\n\n if (wouldExceedLimit(tempThreadCount, tempRunCount)) {\n blocked.push(toolCall);\n } else {\n allowed.push(toolCall);\n tempThreadCount += 1;\n tempRunCount += 1;\n }\n }\n\n return {\n allowed,\n blocked,\n finalThreadCount: tempThreadCount + blocked.length,\n finalRunCount: tempRunCount + blocked.length,\n };\n };\n\n /**\n * Get the count key for this middleware instance\n */\n const countKey = options.toolName ?? DEFAULT_TOOL_COUNT_KEY;\n\n /**\n * Get current counts\n */\n const threadCounts = { ...(state.threadToolCallCount ?? {}) };\n const runCounts = { ...(state.runToolCallCount ?? {}) };\n const currentThreadCount = threadCounts[countKey] ?? 0;\n const currentRunCount = runCounts[countKey] ?? 0;\n\n /**\n * Separate tool calls into allowed and blocked\n */\n const { allowed, blocked, finalThreadCount, finalRunCount } =\n separateToolCalls(\n lastAIMessage.tool_calls,\n currentThreadCount,\n currentRunCount\n );\n\n /**\n * Update counts to include ALL tool call attempts (both allowed and blocked)\n */\n threadCounts[countKey] = finalThreadCount;\n runCounts[countKey] = finalRunCount;\n\n /**\n * If no tool calls are blocked, just update counts\n */\n if (blocked.length === 0) {\n if (allowed.length > 0) {\n return {\n threadToolCallCount: threadCounts,\n runToolCallCount: runCounts,\n };\n }\n return undefined;\n }\n\n /**\n * Handle different exit behaviors\n */\n if (exitBehavior === \"error\") {\n throw new ToolCallLimitExceededError(\n finalThreadCount,\n finalRunCount,\n options.threadLimit,\n options.runLimit,\n options.toolName\n );\n }\n\n /**\n * Build tool message content (sent to model - no thread/run details)\n */\n const toolMsgContent = buildToolMessageContent(\n options.toolName,\n finalThreadCount,\n finalRunCount,\n options.threadLimit,\n options.runLimit\n );\n\n /**\n * Inject artificial error ToolMessages for blocked tool calls\n */\n const artificialMessages: Array<ToolMessage | AIMessage> = blocked.map(\n (toolCall) =>\n new ToolMessage({\n content: toolMsgContent,\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n status: \"error\",\n })\n );\n\n if (exitBehavior === \"end\") {\n /**\n * Check if there are tool calls to other tools that would continue executing\n * For tool-specific limiters: check for calls to other tools\n * For global limiters: check if there are multiple different tool types\n */\n let otherTools: ToolCall[] = [];\n if (options.toolName !== undefined) {\n /**\n * Tool-specific limiter: check for calls to other tools\n */\n otherTools = lastAIMessage.tool_calls.filter(\n (tc) => tc.name !== options.toolName\n );\n } else {\n /**\n * Global limiter: check if there are multiple different tool types\n * If there are allowed calls, those would execute\n * But even if all are blocked, we can't handle multiple tool types with \"end\"\n */\n const uniqueToolNames = new Set(\n lastAIMessage.tool_calls.map((tc) => tc.name).filter(Boolean)\n );\n if (uniqueToolNames.size > 1) {\n /**\n * Multiple different tool types - use allowed calls to show which ones\n */\n otherTools =\n allowed.length > 0 ? allowed : lastAIMessage.tool_calls;\n }\n }\n\n if (otherTools.length > 0) {\n const toolNames = Array.from(\n new Set(otherTools.map((tc) => tc.name).filter(Boolean))\n ).join(\", \");\n throw new Error(\n `Cannot end execution with other tool calls pending. Found calls to: ${toolNames}. Use 'continue' or 'error' behavior instead.`\n );\n }\n\n /**\n * Build final AI message content (displayed to user - includes thread/run details)\n */\n const finalMsgContent = buildFinalAIMessageContent(\n finalThreadCount,\n finalRunCount,\n options.threadLimit,\n options.runLimit,\n options.toolName\n );\n artificialMessages.push(new AIMessage(finalMsgContent));\n\n return {\n threadToolCallCount: threadCounts,\n runToolCallCount: runCounts,\n jumpTo: \"end\" as const,\n messages: artificialMessages,\n };\n }\n\n /**\n * For exit_behavior=\"continue\", return error messages to block exceeded tools\n */\n return {\n threadToolCallCount: threadCounts,\n runToolCallCount: runCounts,\n messages: artificialMessages,\n };\n },\n },\n /**\n * reset the run tool call count after the agent execution completes\n */\n afterAgent: () => ({\n runToolCallCount: {},\n }),\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"toolCallLimit.js","names":["toolName: string | undefined","threadCount: number","runCount: number","threadLimit: number | undefined","runLimit: number | undefined","exceededLimits: string[]","options: ToolCallLimitConfig","z4","toolCall: { name?: string }","toolCalls: ToolCall[]","allowed: ToolCall[]","blocked: ToolCall[]","blocked","allowed","artificialMessages: Array<ToolMessage | AIMessage>","otherTools: ToolCall[]"],"sources":["../../../src/agents/middleware/toolCallLimit.ts"],"sourcesContent":["import { AIMessage, ToolMessage } from \"@langchain/core/messages\";\nimport { z as z4 } from \"zod/v4\";\nimport { z } from \"zod/v3\";\nimport type { InferInteropZodInput } from \"@langchain/core/utils/types\";\nimport type { ToolCall } from \"@langchain/core/messages/tool\";\n\nimport { createMiddleware } from \"../middleware.js\";\n\n/**\n * Build the error message content for ToolMessage when limit is exceeded.\n *\n * This message is sent to the model, so it should not reference thread/run concepts\n * that the model has no notion of.\n *\n * @param toolName - Tool name being limited (if specific tool), or undefined for all tools.\n * @returns A concise message instructing the model not to call the tool again.\n */\nfunction buildToolMessageContent(toolName: string | undefined): string {\n // Always instruct the model not to call again, regardless of which limit was hit\n if (toolName) {\n return `Tool call limit exceeded. Do not call '${toolName}' again.`;\n }\n return \"Tool call limit exceeded. Do not make additional tool calls.\";\n}\n\nconst VALID_EXIT_BEHAVIORS = [\"continue\", \"error\", \"end\"] as const;\nconst DEFAULT_EXIT_BEHAVIOR = \"continue\";\n\n/**\n * Build the final AI message content for 'end' behavior.\n *\n * This message is displayed to the user, so it should include detailed information\n * about which limits were exceeded.\n *\n * @param threadCount - Current thread tool call count.\n * @param runCount - Current run tool call count.\n * @param threadLimit - Thread tool call limit (if set).\n * @param runLimit - Run tool call limit (if set).\n * @param toolName - Tool name being limited (if specific tool), or undefined for all tools.\n * @returns A formatted message describing which limits were exceeded.\n */\nfunction buildFinalAIMessageContent(\n threadCount: number,\n runCount: number,\n threadLimit: number | undefined,\n runLimit: number | undefined,\n toolName: string | undefined\n): string {\n const toolDesc = toolName ? `'${toolName}' tool` : \"Tool\";\n const exceededLimits: string[] = [];\n\n if (threadLimit !== undefined && threadCount > threadLimit) {\n exceededLimits.push(\n `thread limit exceeded (${threadCount}/${threadLimit} calls)`\n );\n }\n if (runLimit !== undefined && runCount > runLimit) {\n exceededLimits.push(`run limit exceeded (${runCount}/${runLimit} calls)`);\n }\n\n const limitsText = exceededLimits.join(\" and \");\n return `${toolDesc} call limit reached: ${limitsText}.`;\n}\n\n/**\n * Schema for the exit behavior.\n */\nconst exitBehaviorSchema = z\n .enum(VALID_EXIT_BEHAVIORS)\n .default(DEFAULT_EXIT_BEHAVIOR);\n\n/**\n * Exception raised when tool call limits are exceeded.\n *\n * This exception is raised when the configured exit behavior is 'error'\n * and either the thread or run tool call limit has been exceeded.\n */\nexport class ToolCallLimitExceededError extends Error {\n /**\n * Current thread tool call count.\n */\n threadCount: number;\n /**\n * Current run tool call count.\n */\n runCount: number;\n /**\n * Thread tool call limit (if set).\n */\n threadLimit: number | undefined;\n /**\n * Run tool call limit (if set).\n */\n runLimit: number | undefined;\n /**\n * Tool name being limited (if specific tool), or undefined for all tools.\n */\n toolName: string | undefined;\n\n constructor(\n threadCount: number,\n runCount: number,\n threadLimit: number | undefined,\n runLimit: number | undefined,\n toolName: string | undefined = undefined\n ) {\n const message = buildFinalAIMessageContent(\n threadCount,\n runCount,\n threadLimit,\n runLimit,\n toolName\n );\n super(message);\n\n this.name = \"ToolCallLimitExceededError\";\n this.threadCount = threadCount;\n this.runCount = runCount;\n this.threadLimit = threadLimit;\n this.runLimit = runLimit;\n this.toolName = toolName;\n }\n}\n\n/**\n * Options for configuring the Tool Call Limit middleware.\n */\nexport const ToolCallLimitOptionsSchema = z.object({\n /**\n * Name of the specific tool to limit. If undefined, limits apply to all tools.\n */\n toolName: z.string().optional(),\n /**\n * Maximum number of tool calls allowed per thread.\n * undefined means no limit.\n */\n threadLimit: z.number().optional(),\n /**\n * Maximum number of tool calls allowed per run.\n * undefined means no limit.\n */\n runLimit: z.number().optional(),\n /**\n * What to do when limits are exceeded.\n * - \"continue\": Block exceeded tools with error messages, let other tools continue (default)\n * - \"error\": Raise a ToolCallLimitExceededError exception\n * - \"end\": Stop execution immediately, injecting a ToolMessage and an AI message\n * for the single tool call that exceeded the limit. Raises NotImplementedError\n * if there are multiple tool calls.\n *\n * @default \"continue\"\n */\n exitBehavior: exitBehaviorSchema,\n});\n\nexport type ToolCallLimitConfig = InferInteropZodInput<\n typeof ToolCallLimitOptionsSchema\n>;\n\n/**\n * Middleware state schema to track the number of model calls made at the thread and run level.\n */\nconst stateSchema = z.object({\n threadToolCallCount: z.record(z.string(), z.number()).default({}),\n runToolCallCount: z.record(z.string(), z.number()).default({}),\n});\n\nconst DEFAULT_TOOL_COUNT_KEY = \"__all__\";\n\n/**\n * Middleware that tracks tool call counts and enforces limits.\n *\n * This middleware monitors the number of tool calls made during agent execution\n * and can terminate the agent when specified limits are reached. It supports\n * both thread-level and run-level call counting with configurable exit behaviors.\n *\n * Thread-level: The middleware counts all tool calls in the entire message history\n * and persists this count across multiple runs (invocations) of the agent.\n *\n * Run-level: The middleware counts tool calls made after the last HumanMessage,\n * representing the current run (invocation) of the agent.\n *\n * @param options - Configuration options for the middleware\n * @param options.toolName - Name of the specific tool to limit. If undefined, limits apply to all tools.\n * @param options.threadLimit - Maximum number of tool calls allowed per thread. undefined means no limit.\n * @param options.runLimit - Maximum number of tool calls allowed per run. undefined means no limit.\n * @param options.exitBehavior - What to do when limits are exceeded.\n * - \"continue\": Block exceeded tools with error messages, let other tools continue. Model decides when to end. (default)\n * - \"error\": Raise a ToolCallLimitExceededError exception\n * - \"end\": Stop execution immediately with a ToolMessage + AI message for the single tool call that exceeded the limit. Raises NotImplementedError if there are multiple tool calls.\n *\n * @throws {Error} If both limits are undefined, if exitBehavior is invalid, or if runLimit exceeds threadLimit.\n * @throws {NotImplementedError} If exitBehavior is \"end\" and there are multiple tool calls.\n *\n * @example Continue execution with blocked tools (default)\n * ```ts\n * import { toolCallLimitMiddleware } from \"@langchain/langchain/agents/middleware\";\n * import { createAgent } from \"@langchain/langchain/agents\";\n *\n * // Block exceeded tools but let other tools and model continue\n * const limiter = toolCallLimitMiddleware({\n * threadLimit: 20,\n * runLimit: 10,\n * exitBehavior: \"continue\", // default\n * });\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * middleware: [limiter]\n * });\n * ```\n *\n * @example Stop immediately when limit exceeded\n * ```ts\n * // End execution immediately with an AI message\n * const limiter = toolCallLimitMiddleware({\n * runLimit: 5,\n * exitBehavior: \"end\"\n * });\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * middleware: [limiter]\n * });\n * ```\n *\n * @example Raise exception on limit\n * ```ts\n * // Strict limit with exception handling\n * const limiter = toolCallLimitMiddleware({\n * toolName: \"search\",\n * threadLimit: 5,\n * exitBehavior: \"error\"\n * });\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * middleware: [limiter]\n * });\n *\n * try {\n * const result = await agent.invoke({ messages: [new HumanMessage(\"Task\")] });\n * } catch (error) {\n * if (error instanceof ToolCallLimitExceededError) {\n * console.log(`Search limit exceeded: ${error}`);\n * }\n * }\n * ```\n */\nexport function toolCallLimitMiddleware(options: ToolCallLimitConfig) {\n /**\n * Validate that at least one limit is specified\n */\n if (options.threadLimit === undefined && options.runLimit === undefined) {\n throw new Error(\n \"At least one limit must be specified (threadLimit or runLimit)\"\n );\n }\n\n /**\n * Validate exitBehavior (Zod schema already validates, but provide helpful error)\n */\n const exitBehavior = options.exitBehavior ?? DEFAULT_EXIT_BEHAVIOR;\n const parseResult = exitBehaviorSchema.safeParse(exitBehavior);\n if (!parseResult.success) {\n throw new Error(z4.prettifyError(parseResult.error).slice(2));\n }\n\n /**\n * Validate that runLimit does not exceed threadLimit\n */\n if (\n options.threadLimit !== undefined &&\n options.runLimit !== undefined &&\n options.runLimit > options.threadLimit\n ) {\n throw new Error(\n `runLimit (${options.runLimit}) cannot exceed threadLimit (${options.threadLimit}). ` +\n \"The run limit should be less than or equal to the thread limit.\"\n );\n }\n\n /**\n * Generate the middleware name based on the tool name\n */\n const middlewareName = options.toolName\n ? `ToolCallLimitMiddleware[${options.toolName}]`\n : \"ToolCallLimitMiddleware\";\n\n return createMiddleware({\n name: middlewareName,\n stateSchema,\n afterModel: {\n canJumpTo: [\"end\"],\n hook: (state) => {\n /**\n * Get the last AI message to check for tool calls\n */\n const lastAIMessage = [...state.messages]\n .reverse()\n .find(AIMessage.isInstance);\n\n if (!lastAIMessage || !lastAIMessage.tool_calls) {\n return undefined;\n }\n\n /**\n * Helper to check if limit would be exceeded by one more call\n */\n const wouldExceedLimit = (\n threadCount: number,\n runCount: number\n ): boolean => {\n return (\n (options.threadLimit !== undefined &&\n threadCount + 1 > options.threadLimit) ||\n (options.runLimit !== undefined && runCount + 1 > options.runLimit)\n );\n };\n\n /**\n * Helper to check if a tool call matches our filter\n */\n const matchesToolFilter = (toolCall: { name?: string }): boolean => {\n return (\n options.toolName === undefined || toolCall.name === options.toolName\n );\n };\n\n /**\n * Separate tool calls into allowed and blocked based on limits\n */\n const separateToolCalls = (\n toolCalls: ToolCall[],\n threadCount: number,\n runCount: number\n ): {\n allowed: ToolCall[];\n blocked: ToolCall[];\n finalThreadCount: number;\n finalRunCount: number;\n } => {\n const allowed: ToolCall[] = [];\n const blocked: ToolCall[] = [];\n let tempThreadCount = threadCount;\n let tempRunCount = runCount;\n\n for (const toolCall of toolCalls) {\n if (!matchesToolFilter(toolCall)) {\n // Tool call doesn't match our filter, skip it\n continue;\n }\n\n if (wouldExceedLimit(tempThreadCount, tempRunCount)) {\n blocked.push(toolCall);\n } else {\n allowed.push(toolCall);\n tempThreadCount += 1;\n tempRunCount += 1;\n }\n }\n\n return {\n allowed,\n blocked,\n finalThreadCount: tempThreadCount,\n finalRunCount: tempRunCount + blocked.length,\n };\n };\n\n /**\n * Get the count key for this middleware instance\n */\n const countKey = options.toolName ?? DEFAULT_TOOL_COUNT_KEY;\n\n /**\n * Get current counts\n */\n const threadCounts = { ...(state.threadToolCallCount ?? {}) };\n const runCounts = { ...(state.runToolCallCount ?? {}) };\n const currentThreadCount = threadCounts[countKey] ?? 0;\n const currentRunCount = runCounts[countKey] ?? 0;\n\n /**\n * Separate tool calls into allowed and blocked\n */\n const { allowed, blocked, finalThreadCount, finalRunCount } =\n separateToolCalls(\n lastAIMessage.tool_calls,\n currentThreadCount,\n currentRunCount\n );\n\n /**\n * Update counts:\n * - Thread count includes only allowed calls (blocked calls don't count towards thread-level tracking)\n * - Run count includes blocked calls since they were attempted in this run\n */\n threadCounts[countKey] = finalThreadCount;\n runCounts[countKey] = finalRunCount;\n\n /**\n * If no tool calls are blocked, just update counts\n */\n if (blocked.length === 0) {\n if (allowed.length > 0) {\n return {\n threadToolCallCount: threadCounts,\n runToolCallCount: runCounts,\n };\n }\n return undefined;\n }\n\n /**\n * Handle different exit behaviors\n */\n if (exitBehavior === \"error\") {\n // Use hypothetical thread count to show which limit was exceeded\n const hypotheticalThreadCount = finalThreadCount + blocked.length;\n throw new ToolCallLimitExceededError(\n hypotheticalThreadCount,\n finalRunCount,\n options.threadLimit,\n options.runLimit,\n options.toolName\n );\n }\n\n /**\n * Build tool message content (sent to model - no thread/run details)\n */\n const toolMsgContent = buildToolMessageContent(options.toolName);\n\n /**\n * Inject artificial error ToolMessages for blocked tool calls\n */\n const artificialMessages: Array<ToolMessage | AIMessage> = blocked.map(\n (toolCall) =>\n new ToolMessage({\n content: toolMsgContent,\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n status: \"error\",\n })\n );\n\n if (exitBehavior === \"end\") {\n /**\n * Check if there are tool calls to other tools that would continue executing\n * For tool-specific limiters: check for calls to other tools\n * For global limiters: check if there are multiple different tool types\n */\n let otherTools: ToolCall[] = [];\n if (options.toolName !== undefined) {\n /**\n * Tool-specific limiter: check for calls to other tools\n */\n otherTools = lastAIMessage.tool_calls.filter(\n (tc) => tc.name !== options.toolName\n );\n } else {\n /**\n * Global limiter: check if there are multiple different tool types\n * If there are allowed calls, those would execute\n * But even if all are blocked, we can't handle multiple tool types with \"end\"\n */\n const uniqueToolNames = new Set(\n lastAIMessage.tool_calls.map((tc) => tc.name).filter(Boolean)\n );\n if (uniqueToolNames.size > 1) {\n /**\n * Multiple different tool types - use allowed calls to show which ones\n */\n otherTools =\n allowed.length > 0 ? allowed : lastAIMessage.tool_calls;\n }\n }\n\n if (otherTools.length > 0) {\n const toolNames = Array.from(\n new Set(otherTools.map((tc) => tc.name).filter(Boolean))\n ).join(\", \");\n throw new Error(\n `Cannot end execution with other tool calls pending. Found calls to: ${toolNames}. Use 'continue' or 'error' behavior instead.`\n );\n }\n\n /**\n * Build final AI message content (displayed to user - includes thread/run details)\n * Use hypothetical thread count (what it would have been if call wasn't blocked)\n * to show which limit was actually exceeded\n */\n const hypotheticalThreadCount = finalThreadCount + blocked.length;\n const finalMsgContent = buildFinalAIMessageContent(\n hypotheticalThreadCount,\n finalRunCount,\n options.threadLimit,\n options.runLimit,\n options.toolName\n );\n artificialMessages.push(new AIMessage(finalMsgContent));\n\n return {\n threadToolCallCount: threadCounts,\n runToolCallCount: runCounts,\n jumpTo: \"end\" as const,\n messages: artificialMessages,\n };\n }\n\n /**\n * For exit_behavior=\"continue\", return error messages to block exceeded tools\n */\n return {\n threadToolCallCount: threadCounts,\n runToolCallCount: runCounts,\n messages: artificialMessages,\n };\n },\n },\n /**\n * reset the run tool call count after the agent execution completes\n */\n afterAgent: () => ({\n runToolCallCount: {},\n }),\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_chat_models_universal = require('../../chat_models/universal.cjs');
|
|
3
|
+
const require_middleware = require('../middleware.cjs');
|
|
4
|
+
const __langchain_core_messages = require_rolldown_runtime.__toESM(require("@langchain/core/messages"));
|
|
5
|
+
|
|
6
|
+
//#region src/agents/middleware/toolEmulator.ts
|
|
7
|
+
/**
|
|
8
|
+
* Middleware that emulates specified tools using an LLM instead of executing them.
|
|
9
|
+
*
|
|
10
|
+
* This middleware allows selective emulation of tools for testing purposes.
|
|
11
|
+
* By default (when `tools` is undefined), all tools are emulated. You can specify
|
|
12
|
+
* which tools to emulate by passing a list of tool names or tool instances.
|
|
13
|
+
*
|
|
14
|
+
* @param options - Configuration options for the middleware
|
|
15
|
+
* @param options.tools - List of tool names or tool instances to emulate. If undefined, all tools are emulated.
|
|
16
|
+
* @param options.model - Model to use for emulation. Defaults to "anthropic:claude-sonnet-4-5-20250929".
|
|
17
|
+
*
|
|
18
|
+
* @example Emulate all tools (default behavior)
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { toolEmulatorMiddleware } from "@langchain/langchain/agents/middleware";
|
|
21
|
+
* import { createAgent } from "@langchain/langchain/agents";
|
|
22
|
+
*
|
|
23
|
+
* const middleware = toolEmulatorMiddleware();
|
|
24
|
+
*
|
|
25
|
+
* const agent = createAgent({
|
|
26
|
+
* model: "openai:gpt-4o",
|
|
27
|
+
* tools: [getWeather, getUserLocation, calculator],
|
|
28
|
+
* middleware: [middleware],
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @example Emulate specific tools by name
|
|
33
|
+
* ```ts
|
|
34
|
+
* const middleware = toolEmulatorMiddleware({
|
|
35
|
+
* tools: ["get_weather", "get_user_location"]
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @example Use a custom model for emulation
|
|
40
|
+
* ```ts
|
|
41
|
+
* const middleware = toolEmulatorMiddleware({
|
|
42
|
+
* tools: ["get_weather"],
|
|
43
|
+
* model: "anthropic:claude-sonnet-4-5-20250929"
|
|
44
|
+
* });
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @example Emulate specific tools by passing tool instances
|
|
48
|
+
* ```ts
|
|
49
|
+
* const middleware = toolEmulatorMiddleware({
|
|
50
|
+
* tools: [getWeather, getUserLocation]
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
function toolEmulatorMiddleware(options = {}) {
|
|
55
|
+
let agentModel;
|
|
56
|
+
const { tools, model } = options;
|
|
57
|
+
/**
|
|
58
|
+
* Extract tool names from tools
|
|
59
|
+
*/
|
|
60
|
+
const emulateAll = !tools || tools.length === 0;
|
|
61
|
+
const toolsToEmulate = /* @__PURE__ */ new Set();
|
|
62
|
+
if (!emulateAll && tools) for (const tool of tools) if (typeof tool === "string") toolsToEmulate.add(tool);
|
|
63
|
+
else {
|
|
64
|
+
const toolName = typeof tool.name === "string" ? tool.name : String(tool.name);
|
|
65
|
+
toolsToEmulate.add(toolName);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Initialize emulator model
|
|
69
|
+
* We'll initialize it lazily in wrapToolCall to handle async initChatModel
|
|
70
|
+
*/
|
|
71
|
+
let emulatorModel;
|
|
72
|
+
const getEmulatorModel = async () => {
|
|
73
|
+
if (typeof model === "object") return model;
|
|
74
|
+
if (typeof model === "string") {
|
|
75
|
+
emulatorModel = emulatorModel ?? await require_chat_models_universal.initChatModel(model, { temperature: 1 }).catch((err) => {
|
|
76
|
+
console.error("Error initializing emulator model, using agent model:", err);
|
|
77
|
+
return agentModel;
|
|
78
|
+
});
|
|
79
|
+
return emulatorModel;
|
|
80
|
+
}
|
|
81
|
+
return agentModel;
|
|
82
|
+
};
|
|
83
|
+
return require_middleware.createMiddleware({
|
|
84
|
+
name: "ToolEmulatorMiddleware",
|
|
85
|
+
wrapModelCall: async (request, handler) => {
|
|
86
|
+
agentModel = request.model;
|
|
87
|
+
return handler(request);
|
|
88
|
+
},
|
|
89
|
+
wrapToolCall: async (request, handler) => {
|
|
90
|
+
const toolName = request.toolCall.name;
|
|
91
|
+
const shouldEmulate = emulateAll || toolsToEmulate.has(toolName);
|
|
92
|
+
if (!shouldEmulate) return handler(request);
|
|
93
|
+
const toolArgs = request.toolCall.args;
|
|
94
|
+
const toolDescription = request.tool.description || "No description available";
|
|
95
|
+
const toolArgsString = typeof toolArgs === "string" ? toolArgs : JSON.stringify(toolArgs);
|
|
96
|
+
const prompt = `You are emulating a tool call for testing purposes.
|
|
97
|
+
|
|
98
|
+
Tool: ${toolName}
|
|
99
|
+
Description: ${toolDescription}
|
|
100
|
+
Arguments: ${toolArgsString}
|
|
101
|
+
|
|
102
|
+
Generate a realistic response that this tool would return given these arguments.
|
|
103
|
+
Return ONLY the tool's output, no explanation or preamble. Introduce variation into your responses.`;
|
|
104
|
+
const emulator = await getEmulatorModel();
|
|
105
|
+
const response = await emulator.invoke([new __langchain_core_messages.HumanMessage(prompt)]);
|
|
106
|
+
const content = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
|
|
107
|
+
return new __langchain_core_messages.ToolMessage({
|
|
108
|
+
content,
|
|
109
|
+
tool_call_id: request.toolCall.id ?? "",
|
|
110
|
+
name: toolName
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
//#endregion
|
|
117
|
+
exports.toolEmulatorMiddleware = toolEmulatorMiddleware;
|
|
118
|
+
//# sourceMappingURL=toolEmulator.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolEmulator.cjs","names":["options: ToolEmulatorOptions","agentModel: BaseChatModel | undefined","emulatorModel: BaseChatModel | undefined","initChatModel","createMiddleware","HumanMessage","ToolMessage"],"sources":["../../../src/agents/middleware/toolEmulator.ts"],"sourcesContent":["import { HumanMessage, ToolMessage } from \"@langchain/core/messages\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { initChatModel } from \"../../chat_models/universal.js\";\nimport { createMiddleware } from \"../middleware.js\";\n\n/**\n * Options for configuring the Tool Emulator middleware.\n */\nexport interface ToolEmulatorOptions {\n /**\n * List of tool names (string) or tool instances to emulate.\n * - If `undefined` (default), ALL tools will be emulated.\n * - If empty array, no tools will be emulated.\n * - If array with tool names/instances, only those tools will be emulated.\n */\n tools?: (string | ClientTool | ServerTool)[];\n\n /**\n * Model to use for emulation.\n * - Can be a model identifier string (e.g., \"anthropic:claude-sonnet-4-5-20250929\")\n * - Can be a BaseChatModel instance\n * - Defaults to agent model\n */\n model?: string | BaseChatModel;\n}\n\n/**\n * Middleware that emulates specified tools using an LLM instead of executing them.\n *\n * This middleware allows selective emulation of tools for testing purposes.\n * By default (when `tools` is undefined), all tools are emulated. You can specify\n * which tools to emulate by passing a list of tool names or tool instances.\n *\n * @param options - Configuration options for the middleware\n * @param options.tools - List of tool names or tool instances to emulate. If undefined, all tools are emulated.\n * @param options.model - Model to use for emulation. Defaults to \"anthropic:claude-sonnet-4-5-20250929\".\n *\n * @example Emulate all tools (default behavior)\n * ```ts\n * import { toolEmulatorMiddleware } from \"@langchain/langchain/agents/middleware\";\n * import { createAgent } from \"@langchain/langchain/agents\";\n *\n * const middleware = toolEmulatorMiddleware();\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [getWeather, getUserLocation, calculator],\n * middleware: [middleware],\n * });\n * ```\n *\n * @example Emulate specific tools by name\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [\"get_weather\", \"get_user_location\"]\n * });\n * ```\n *\n * @example Use a custom model for emulation\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [\"get_weather\"],\n * model: \"anthropic:claude-sonnet-4-5-20250929\"\n * });\n * ```\n *\n * @example Emulate specific tools by passing tool instances\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [getWeather, getUserLocation]\n * });\n * ```\n */\nexport function toolEmulatorMiddleware(\n options: ToolEmulatorOptions = {}\n): ReturnType<typeof createMiddleware> {\n let agentModel: BaseChatModel | undefined;\n const { tools, model } = options;\n\n /**\n * Extract tool names from tools\n */\n const emulateAll = !tools || tools.length === 0;\n const toolsToEmulate = new Set<string>();\n\n if (!emulateAll && tools) {\n for (const tool of tools) {\n if (typeof tool === \"string\") {\n toolsToEmulate.add(tool);\n } else {\n // Assume tool instance with .name property\n const toolName =\n typeof tool.name === \"string\" ? tool.name : String(tool.name);\n toolsToEmulate.add(toolName);\n }\n }\n }\n\n /**\n * Initialize emulator model\n * We'll initialize it lazily in wrapToolCall to handle async initChatModel\n */\n let emulatorModel: BaseChatModel | undefined;\n const getEmulatorModel = async (): Promise<BaseChatModel> => {\n if (typeof model === \"object\") {\n return model;\n }\n if (typeof model === \"string\") {\n emulatorModel =\n emulatorModel ??\n (await initChatModel(model, { temperature: 1 }).catch((err) => {\n console.error(\n \"Error initializing emulator model, using agent model:\",\n err\n );\n return agentModel as BaseChatModel;\n }));\n return emulatorModel;\n }\n return agentModel as BaseChatModel;\n };\n\n return createMiddleware({\n name: \"ToolEmulatorMiddleware\",\n wrapModelCall: async (request, handler) => {\n agentModel = request.model as BaseChatModel;\n return handler(request);\n },\n wrapToolCall: async (request, handler) => {\n const toolName = request.toolCall.name;\n\n // Check if this tool should be emulated\n const shouldEmulate = emulateAll || toolsToEmulate.has(toolName);\n\n if (!shouldEmulate) {\n // Let it execute normally by calling the handler\n return handler(request);\n }\n\n // Extract tool information for emulation\n const toolArgs = request.toolCall.args;\n const toolDescription =\n request.tool.description || \"No description available\";\n\n // Build prompt for emulator LLM\n const toolArgsString =\n typeof toolArgs === \"string\" ? toolArgs : JSON.stringify(toolArgs);\n const prompt = `You are emulating a tool call for testing purposes.\n\nTool: ${toolName}\nDescription: ${toolDescription}\nArguments: ${toolArgsString}\n\nGenerate a realistic response that this tool would return given these arguments.\nReturn ONLY the tool's output, no explanation or preamble. Introduce variation into your responses.`;\n\n // Get emulated response from LLM\n const emulator = await getEmulatorModel();\n const response = await emulator.invoke([new HumanMessage(prompt)]);\n\n // Extract content from response\n const content =\n typeof response.content === \"string\"\n ? response.content\n : JSON.stringify(response.content);\n\n // Short-circuit: return emulated result without executing real tool\n return new ToolMessage({\n content,\n tool_call_id: request.toolCall.id ?? \"\",\n name: toolName,\n });\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0EA,SAAgB,uBACdA,UAA+B,CAAE,GACI;CACrC,IAAIC;CACJ,MAAM,EAAE,OAAO,OAAO,GAAG;;;;CAKzB,MAAM,aAAa,CAAC,SAAS,MAAM,WAAW;CAC9C,MAAM,iCAAiB,IAAI;AAE3B,KAAI,CAAC,cAAc,MACjB,MAAK,MAAM,QAAQ,MACjB,KAAI,OAAO,SAAS,UAClB,eAAe,IAAI,KAAK;MACnB;EAEL,MAAM,WACJ,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,OAAO,KAAK,KAAK;EAC/D,eAAe,IAAI,SAAS;CAC7B;;;;;CAQL,IAAIC;CACJ,MAAM,mBAAmB,YAAoC;AAC3D,MAAI,OAAO,UAAU,SACnB,QAAO;AAET,MAAI,OAAO,UAAU,UAAU;GAC7B,gBACE,iBACC,MAAMC,4CAAc,OAAO,EAAE,aAAa,EAAG,EAAC,CAAC,MAAM,CAAC,QAAQ;IAC7D,QAAQ,MACN,yDACA,IACD;AACD,WAAO;GACR,EAAC;AACJ,UAAO;EACR;AACD,SAAO;CACR;AAED,QAAOC,oCAAiB;EACtB,MAAM;EACN,eAAe,OAAO,SAAS,YAAY;GACzC,aAAa,QAAQ;AACrB,UAAO,QAAQ,QAAQ;EACxB;EACD,cAAc,OAAO,SAAS,YAAY;GACxC,MAAM,WAAW,QAAQ,SAAS;GAGlC,MAAM,gBAAgB,cAAc,eAAe,IAAI,SAAS;AAEhE,OAAI,CAAC,cAEH,QAAO,QAAQ,QAAQ;GAIzB,MAAM,WAAW,QAAQ,SAAS;GAClC,MAAM,kBACJ,QAAQ,KAAK,eAAe;GAG9B,MAAM,iBACJ,OAAO,aAAa,WAAW,WAAW,KAAK,UAAU,SAAS;GACpE,MAAM,SAAS,CAAC;;MAEhB,EAAE,SAAS;aACJ,EAAE,gBAAgB;WACpB,EAAE,eAAe;;;mGAGuE,CAAC;GAG9F,MAAM,WAAW,MAAM,kBAAkB;GACzC,MAAM,WAAW,MAAM,SAAS,OAAO,CAAC,IAAIC,uCAAa,OAAQ,EAAC;GAGlE,MAAM,UACJ,OAAO,SAAS,YAAY,WACxB,SAAS,UACT,KAAK,UAAU,SAAS,QAAQ;AAGtC,UAAO,IAAIC,sCAAY;IACrB;IACA,cAAc,QAAQ,SAAS,MAAM;IACrC,MAAM;GACP;EACF;CACF,EAAC;AACH"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { createMiddleware } from "../middleware.cjs";
|
|
2
|
+
import { BaseChatModel } from "@langchain/core/language_models/chat_models";
|
|
3
|
+
import { ClientTool, ServerTool } from "@langchain/core/tools";
|
|
4
|
+
|
|
5
|
+
//#region src/agents/middleware/toolEmulator.d.ts
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Options for configuring the Tool Emulator middleware.
|
|
9
|
+
*/
|
|
10
|
+
interface ToolEmulatorOptions {
|
|
11
|
+
/**
|
|
12
|
+
* List of tool names (string) or tool instances to emulate.
|
|
13
|
+
* - If `undefined` (default), ALL tools will be emulated.
|
|
14
|
+
* - If empty array, no tools will be emulated.
|
|
15
|
+
* - If array with tool names/instances, only those tools will be emulated.
|
|
16
|
+
*/
|
|
17
|
+
tools?: (string | ClientTool | ServerTool)[];
|
|
18
|
+
/**
|
|
19
|
+
* Model to use for emulation.
|
|
20
|
+
* - Can be a model identifier string (e.g., "anthropic:claude-sonnet-4-5-20250929")
|
|
21
|
+
* - Can be a BaseChatModel instance
|
|
22
|
+
* - Defaults to agent model
|
|
23
|
+
*/
|
|
24
|
+
model?: string | BaseChatModel;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Middleware that emulates specified tools using an LLM instead of executing them.
|
|
28
|
+
*
|
|
29
|
+
* This middleware allows selective emulation of tools for testing purposes.
|
|
30
|
+
* By default (when `tools` is undefined), all tools are emulated. You can specify
|
|
31
|
+
* which tools to emulate by passing a list of tool names or tool instances.
|
|
32
|
+
*
|
|
33
|
+
* @param options - Configuration options for the middleware
|
|
34
|
+
* @param options.tools - List of tool names or tool instances to emulate. If undefined, all tools are emulated.
|
|
35
|
+
* @param options.model - Model to use for emulation. Defaults to "anthropic:claude-sonnet-4-5-20250929".
|
|
36
|
+
*
|
|
37
|
+
* @example Emulate all tools (default behavior)
|
|
38
|
+
* ```ts
|
|
39
|
+
* import { toolEmulatorMiddleware } from "@langchain/langchain/agents/middleware";
|
|
40
|
+
* import { createAgent } from "@langchain/langchain/agents";
|
|
41
|
+
*
|
|
42
|
+
* const middleware = toolEmulatorMiddleware();
|
|
43
|
+
*
|
|
44
|
+
* const agent = createAgent({
|
|
45
|
+
* model: "openai:gpt-4o",
|
|
46
|
+
* tools: [getWeather, getUserLocation, calculator],
|
|
47
|
+
* middleware: [middleware],
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* @example Emulate specific tools by name
|
|
52
|
+
* ```ts
|
|
53
|
+
* const middleware = toolEmulatorMiddleware({
|
|
54
|
+
* tools: ["get_weather", "get_user_location"]
|
|
55
|
+
* });
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* @example Use a custom model for emulation
|
|
59
|
+
* ```ts
|
|
60
|
+
* const middleware = toolEmulatorMiddleware({
|
|
61
|
+
* tools: ["get_weather"],
|
|
62
|
+
* model: "anthropic:claude-sonnet-4-5-20250929"
|
|
63
|
+
* });
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* @example Emulate specific tools by passing tool instances
|
|
67
|
+
* ```ts
|
|
68
|
+
* const middleware = toolEmulatorMiddleware({
|
|
69
|
+
* tools: [getWeather, getUserLocation]
|
|
70
|
+
* });
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
declare function toolEmulatorMiddleware(options?: ToolEmulatorOptions): ReturnType<typeof createMiddleware>;
|
|
74
|
+
//#endregion
|
|
75
|
+
export { ToolEmulatorOptions, toolEmulatorMiddleware };
|
|
76
|
+
//# sourceMappingURL=toolEmulator.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolEmulator.d.cts","names":["BaseChatModel","ClientTool","ServerTool","createMiddleware","ToolEmulatorOptions","toolEmulatorMiddleware","ReturnType"],"sources":["../../../src/agents/middleware/toolEmulator.d.ts"],"sourcesContent":["import type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { createMiddleware } from \"../middleware.js\";\n/**\n * Options for configuring the Tool Emulator middleware.\n */\nexport interface ToolEmulatorOptions {\n /**\n * List of tool names (string) or tool instances to emulate.\n * - If `undefined` (default), ALL tools will be emulated.\n * - If empty array, no tools will be emulated.\n * - If array with tool names/instances, only those tools will be emulated.\n */\n tools?: (string | ClientTool | ServerTool)[];\n /**\n * Model to use for emulation.\n * - Can be a model identifier string (e.g., \"anthropic:claude-sonnet-4-5-20250929\")\n * - Can be a BaseChatModel instance\n * - Defaults to agent model\n */\n model?: string | BaseChatModel;\n}\n/**\n * Middleware that emulates specified tools using an LLM instead of executing them.\n *\n * This middleware allows selective emulation of tools for testing purposes.\n * By default (when `tools` is undefined), all tools are emulated. You can specify\n * which tools to emulate by passing a list of tool names or tool instances.\n *\n * @param options - Configuration options for the middleware\n * @param options.tools - List of tool names or tool instances to emulate. If undefined, all tools are emulated.\n * @param options.model - Model to use for emulation. Defaults to \"anthropic:claude-sonnet-4-5-20250929\".\n *\n * @example Emulate all tools (default behavior)\n * ```ts\n * import { toolEmulatorMiddleware } from \"@langchain/langchain/agents/middleware\";\n * import { createAgent } from \"@langchain/langchain/agents\";\n *\n * const middleware = toolEmulatorMiddleware();\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [getWeather, getUserLocation, calculator],\n * middleware: [middleware],\n * });\n * ```\n *\n * @example Emulate specific tools by name\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [\"get_weather\", \"get_user_location\"]\n * });\n * ```\n *\n * @example Use a custom model for emulation\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [\"get_weather\"],\n * model: \"anthropic:claude-sonnet-4-5-20250929\"\n * });\n * ```\n *\n * @example Emulate specific tools by passing tool instances\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [getWeather, getUserLocation]\n * });\n * ```\n */\nexport declare function toolEmulatorMiddleware(options?: ToolEmulatorOptions): ReturnType<typeof createMiddleware>;\n"],"mappings":";;;;;;;;AAMA;AAAoC,UAAnBI,mBAAAA,CAAmB;EAAA;;;AAcF;AAiDlC;;EAA8C,KAAWA,CAAAA,EAAAA,CAAAA,MAAAA,GAxDnCH,UAwDmCG,GAxDtBF,UAwDsBE,CAAAA,EAAAA;EAAmB;;AAAa;;;;mBAjDpEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiDGK,sBAAAA,WAAiCD,sBAAsBE,kBAAkBH"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { createMiddleware } from "../middleware.js";
|
|
2
|
+
import { BaseChatModel } from "@langchain/core/language_models/chat_models";
|
|
3
|
+
import { ClientTool, ServerTool } from "@langchain/core/tools";
|
|
4
|
+
|
|
5
|
+
//#region src/agents/middleware/toolEmulator.d.ts
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Options for configuring the Tool Emulator middleware.
|
|
9
|
+
*/
|
|
10
|
+
interface ToolEmulatorOptions {
|
|
11
|
+
/**
|
|
12
|
+
* List of tool names (string) or tool instances to emulate.
|
|
13
|
+
* - If `undefined` (default), ALL tools will be emulated.
|
|
14
|
+
* - If empty array, no tools will be emulated.
|
|
15
|
+
* - If array with tool names/instances, only those tools will be emulated.
|
|
16
|
+
*/
|
|
17
|
+
tools?: (string | ClientTool | ServerTool)[];
|
|
18
|
+
/**
|
|
19
|
+
* Model to use for emulation.
|
|
20
|
+
* - Can be a model identifier string (e.g., "anthropic:claude-sonnet-4-5-20250929")
|
|
21
|
+
* - Can be a BaseChatModel instance
|
|
22
|
+
* - Defaults to agent model
|
|
23
|
+
*/
|
|
24
|
+
model?: string | BaseChatModel;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Middleware that emulates specified tools using an LLM instead of executing them.
|
|
28
|
+
*
|
|
29
|
+
* This middleware allows selective emulation of tools for testing purposes.
|
|
30
|
+
* By default (when `tools` is undefined), all tools are emulated. You can specify
|
|
31
|
+
* which tools to emulate by passing a list of tool names or tool instances.
|
|
32
|
+
*
|
|
33
|
+
* @param options - Configuration options for the middleware
|
|
34
|
+
* @param options.tools - List of tool names or tool instances to emulate. If undefined, all tools are emulated.
|
|
35
|
+
* @param options.model - Model to use for emulation. Defaults to "anthropic:claude-sonnet-4-5-20250929".
|
|
36
|
+
*
|
|
37
|
+
* @example Emulate all tools (default behavior)
|
|
38
|
+
* ```ts
|
|
39
|
+
* import { toolEmulatorMiddleware } from "@langchain/langchain/agents/middleware";
|
|
40
|
+
* import { createAgent } from "@langchain/langchain/agents";
|
|
41
|
+
*
|
|
42
|
+
* const middleware = toolEmulatorMiddleware();
|
|
43
|
+
*
|
|
44
|
+
* const agent = createAgent({
|
|
45
|
+
* model: "openai:gpt-4o",
|
|
46
|
+
* tools: [getWeather, getUserLocation, calculator],
|
|
47
|
+
* middleware: [middleware],
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* @example Emulate specific tools by name
|
|
52
|
+
* ```ts
|
|
53
|
+
* const middleware = toolEmulatorMiddleware({
|
|
54
|
+
* tools: ["get_weather", "get_user_location"]
|
|
55
|
+
* });
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* @example Use a custom model for emulation
|
|
59
|
+
* ```ts
|
|
60
|
+
* const middleware = toolEmulatorMiddleware({
|
|
61
|
+
* tools: ["get_weather"],
|
|
62
|
+
* model: "anthropic:claude-sonnet-4-5-20250929"
|
|
63
|
+
* });
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* @example Emulate specific tools by passing tool instances
|
|
67
|
+
* ```ts
|
|
68
|
+
* const middleware = toolEmulatorMiddleware({
|
|
69
|
+
* tools: [getWeather, getUserLocation]
|
|
70
|
+
* });
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
declare function toolEmulatorMiddleware(options?: ToolEmulatorOptions): ReturnType<typeof createMiddleware>;
|
|
74
|
+
//#endregion
|
|
75
|
+
export { ToolEmulatorOptions, toolEmulatorMiddleware };
|
|
76
|
+
//# sourceMappingURL=toolEmulator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolEmulator.d.ts","names":["BaseChatModel","ClientTool","ServerTool","createMiddleware","ToolEmulatorOptions","toolEmulatorMiddleware","ReturnType"],"sources":["../../../src/agents/middleware/toolEmulator.d.ts"],"sourcesContent":["import type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { createMiddleware } from \"../middleware.js\";\n/**\n * Options for configuring the Tool Emulator middleware.\n */\nexport interface ToolEmulatorOptions {\n /**\n * List of tool names (string) or tool instances to emulate.\n * - If `undefined` (default), ALL tools will be emulated.\n * - If empty array, no tools will be emulated.\n * - If array with tool names/instances, only those tools will be emulated.\n */\n tools?: (string | ClientTool | ServerTool)[];\n /**\n * Model to use for emulation.\n * - Can be a model identifier string (e.g., \"anthropic:claude-sonnet-4-5-20250929\")\n * - Can be a BaseChatModel instance\n * - Defaults to agent model\n */\n model?: string | BaseChatModel;\n}\n/**\n * Middleware that emulates specified tools using an LLM instead of executing them.\n *\n * This middleware allows selective emulation of tools for testing purposes.\n * By default (when `tools` is undefined), all tools are emulated. You can specify\n * which tools to emulate by passing a list of tool names or tool instances.\n *\n * @param options - Configuration options for the middleware\n * @param options.tools - List of tool names or tool instances to emulate. If undefined, all tools are emulated.\n * @param options.model - Model to use for emulation. Defaults to \"anthropic:claude-sonnet-4-5-20250929\".\n *\n * @example Emulate all tools (default behavior)\n * ```ts\n * import { toolEmulatorMiddleware } from \"@langchain/langchain/agents/middleware\";\n * import { createAgent } from \"@langchain/langchain/agents\";\n *\n * const middleware = toolEmulatorMiddleware();\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [getWeather, getUserLocation, calculator],\n * middleware: [middleware],\n * });\n * ```\n *\n * @example Emulate specific tools by name\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [\"get_weather\", \"get_user_location\"]\n * });\n * ```\n *\n * @example Use a custom model for emulation\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [\"get_weather\"],\n * model: \"anthropic:claude-sonnet-4-5-20250929\"\n * });\n * ```\n *\n * @example Emulate specific tools by passing tool instances\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [getWeather, getUserLocation]\n * });\n * ```\n */\nexport declare function toolEmulatorMiddleware(options?: ToolEmulatorOptions): ReturnType<typeof createMiddleware>;\n"],"mappings":";;;;;;;;AAMA;AAAoC,UAAnBI,mBAAAA,CAAmB;EAAA;;;AAcF;AAiDlC;;EAA8C,KAAWA,CAAAA,EAAAA,CAAAA,MAAAA,GAxDnCH,UAwDmCG,GAxDtBF,UAwDsBE,CAAAA,EAAAA;EAAmB;;AAAa;;;;mBAjDpEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiDGK,sBAAAA,WAAiCD,sBAAsBE,kBAAkBH"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { initChatModel } from "../../chat_models/universal.js";
|
|
2
|
+
import { createMiddleware } from "../middleware.js";
|
|
3
|
+
import { HumanMessage, ToolMessage } from "@langchain/core/messages";
|
|
4
|
+
|
|
5
|
+
//#region src/agents/middleware/toolEmulator.ts
|
|
6
|
+
/**
|
|
7
|
+
* Middleware that emulates specified tools using an LLM instead of executing them.
|
|
8
|
+
*
|
|
9
|
+
* This middleware allows selective emulation of tools for testing purposes.
|
|
10
|
+
* By default (when `tools` is undefined), all tools are emulated. You can specify
|
|
11
|
+
* which tools to emulate by passing a list of tool names or tool instances.
|
|
12
|
+
*
|
|
13
|
+
* @param options - Configuration options for the middleware
|
|
14
|
+
* @param options.tools - List of tool names or tool instances to emulate. If undefined, all tools are emulated.
|
|
15
|
+
* @param options.model - Model to use for emulation. Defaults to "anthropic:claude-sonnet-4-5-20250929".
|
|
16
|
+
*
|
|
17
|
+
* @example Emulate all tools (default behavior)
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { toolEmulatorMiddleware } from "@langchain/langchain/agents/middleware";
|
|
20
|
+
* import { createAgent } from "@langchain/langchain/agents";
|
|
21
|
+
*
|
|
22
|
+
* const middleware = toolEmulatorMiddleware();
|
|
23
|
+
*
|
|
24
|
+
* const agent = createAgent({
|
|
25
|
+
* model: "openai:gpt-4o",
|
|
26
|
+
* tools: [getWeather, getUserLocation, calculator],
|
|
27
|
+
* middleware: [middleware],
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @example Emulate specific tools by name
|
|
32
|
+
* ```ts
|
|
33
|
+
* const middleware = toolEmulatorMiddleware({
|
|
34
|
+
* tools: ["get_weather", "get_user_location"]
|
|
35
|
+
* });
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @example Use a custom model for emulation
|
|
39
|
+
* ```ts
|
|
40
|
+
* const middleware = toolEmulatorMiddleware({
|
|
41
|
+
* tools: ["get_weather"],
|
|
42
|
+
* model: "anthropic:claude-sonnet-4-5-20250929"
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @example Emulate specific tools by passing tool instances
|
|
47
|
+
* ```ts
|
|
48
|
+
* const middleware = toolEmulatorMiddleware({
|
|
49
|
+
* tools: [getWeather, getUserLocation]
|
|
50
|
+
* });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
function toolEmulatorMiddleware(options = {}) {
|
|
54
|
+
let agentModel;
|
|
55
|
+
const { tools, model } = options;
|
|
56
|
+
/**
|
|
57
|
+
* Extract tool names from tools
|
|
58
|
+
*/
|
|
59
|
+
const emulateAll = !tools || tools.length === 0;
|
|
60
|
+
const toolsToEmulate = /* @__PURE__ */ new Set();
|
|
61
|
+
if (!emulateAll && tools) for (const tool of tools) if (typeof tool === "string") toolsToEmulate.add(tool);
|
|
62
|
+
else {
|
|
63
|
+
const toolName = typeof tool.name === "string" ? tool.name : String(tool.name);
|
|
64
|
+
toolsToEmulate.add(toolName);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Initialize emulator model
|
|
68
|
+
* We'll initialize it lazily in wrapToolCall to handle async initChatModel
|
|
69
|
+
*/
|
|
70
|
+
let emulatorModel;
|
|
71
|
+
const getEmulatorModel = async () => {
|
|
72
|
+
if (typeof model === "object") return model;
|
|
73
|
+
if (typeof model === "string") {
|
|
74
|
+
emulatorModel = emulatorModel ?? await initChatModel(model, { temperature: 1 }).catch((err) => {
|
|
75
|
+
console.error("Error initializing emulator model, using agent model:", err);
|
|
76
|
+
return agentModel;
|
|
77
|
+
});
|
|
78
|
+
return emulatorModel;
|
|
79
|
+
}
|
|
80
|
+
return agentModel;
|
|
81
|
+
};
|
|
82
|
+
return createMiddleware({
|
|
83
|
+
name: "ToolEmulatorMiddleware",
|
|
84
|
+
wrapModelCall: async (request, handler) => {
|
|
85
|
+
agentModel = request.model;
|
|
86
|
+
return handler(request);
|
|
87
|
+
},
|
|
88
|
+
wrapToolCall: async (request, handler) => {
|
|
89
|
+
const toolName = request.toolCall.name;
|
|
90
|
+
const shouldEmulate = emulateAll || toolsToEmulate.has(toolName);
|
|
91
|
+
if (!shouldEmulate) return handler(request);
|
|
92
|
+
const toolArgs = request.toolCall.args;
|
|
93
|
+
const toolDescription = request.tool.description || "No description available";
|
|
94
|
+
const toolArgsString = typeof toolArgs === "string" ? toolArgs : JSON.stringify(toolArgs);
|
|
95
|
+
const prompt = `You are emulating a tool call for testing purposes.
|
|
96
|
+
|
|
97
|
+
Tool: ${toolName}
|
|
98
|
+
Description: ${toolDescription}
|
|
99
|
+
Arguments: ${toolArgsString}
|
|
100
|
+
|
|
101
|
+
Generate a realistic response that this tool would return given these arguments.
|
|
102
|
+
Return ONLY the tool's output, no explanation or preamble. Introduce variation into your responses.`;
|
|
103
|
+
const emulator = await getEmulatorModel();
|
|
104
|
+
const response = await emulator.invoke([new HumanMessage(prompt)]);
|
|
105
|
+
const content = typeof response.content === "string" ? response.content : JSON.stringify(response.content);
|
|
106
|
+
return new ToolMessage({
|
|
107
|
+
content,
|
|
108
|
+
tool_call_id: request.toolCall.id ?? "",
|
|
109
|
+
name: toolName
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
//#endregion
|
|
116
|
+
export { toolEmulatorMiddleware };
|
|
117
|
+
//# sourceMappingURL=toolEmulator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolEmulator.js","names":["options: ToolEmulatorOptions","agentModel: BaseChatModel | undefined","emulatorModel: BaseChatModel | undefined"],"sources":["../../../src/agents/middleware/toolEmulator.ts"],"sourcesContent":["import { HumanMessage, ToolMessage } from \"@langchain/core/messages\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { initChatModel } from \"../../chat_models/universal.js\";\nimport { createMiddleware } from \"../middleware.js\";\n\n/**\n * Options for configuring the Tool Emulator middleware.\n */\nexport interface ToolEmulatorOptions {\n /**\n * List of tool names (string) or tool instances to emulate.\n * - If `undefined` (default), ALL tools will be emulated.\n * - If empty array, no tools will be emulated.\n * - If array with tool names/instances, only those tools will be emulated.\n */\n tools?: (string | ClientTool | ServerTool)[];\n\n /**\n * Model to use for emulation.\n * - Can be a model identifier string (e.g., \"anthropic:claude-sonnet-4-5-20250929\")\n * - Can be a BaseChatModel instance\n * - Defaults to agent model\n */\n model?: string | BaseChatModel;\n}\n\n/**\n * Middleware that emulates specified tools using an LLM instead of executing them.\n *\n * This middleware allows selective emulation of tools for testing purposes.\n * By default (when `tools` is undefined), all tools are emulated. You can specify\n * which tools to emulate by passing a list of tool names or tool instances.\n *\n * @param options - Configuration options for the middleware\n * @param options.tools - List of tool names or tool instances to emulate. If undefined, all tools are emulated.\n * @param options.model - Model to use for emulation. Defaults to \"anthropic:claude-sonnet-4-5-20250929\".\n *\n * @example Emulate all tools (default behavior)\n * ```ts\n * import { toolEmulatorMiddleware } from \"@langchain/langchain/agents/middleware\";\n * import { createAgent } from \"@langchain/langchain/agents\";\n *\n * const middleware = toolEmulatorMiddleware();\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [getWeather, getUserLocation, calculator],\n * middleware: [middleware],\n * });\n * ```\n *\n * @example Emulate specific tools by name\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [\"get_weather\", \"get_user_location\"]\n * });\n * ```\n *\n * @example Use a custom model for emulation\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [\"get_weather\"],\n * model: \"anthropic:claude-sonnet-4-5-20250929\"\n * });\n * ```\n *\n * @example Emulate specific tools by passing tool instances\n * ```ts\n * const middleware = toolEmulatorMiddleware({\n * tools: [getWeather, getUserLocation]\n * });\n * ```\n */\nexport function toolEmulatorMiddleware(\n options: ToolEmulatorOptions = {}\n): ReturnType<typeof createMiddleware> {\n let agentModel: BaseChatModel | undefined;\n const { tools, model } = options;\n\n /**\n * Extract tool names from tools\n */\n const emulateAll = !tools || tools.length === 0;\n const toolsToEmulate = new Set<string>();\n\n if (!emulateAll && tools) {\n for (const tool of tools) {\n if (typeof tool === \"string\") {\n toolsToEmulate.add(tool);\n } else {\n // Assume tool instance with .name property\n const toolName =\n typeof tool.name === \"string\" ? tool.name : String(tool.name);\n toolsToEmulate.add(toolName);\n }\n }\n }\n\n /**\n * Initialize emulator model\n * We'll initialize it lazily in wrapToolCall to handle async initChatModel\n */\n let emulatorModel: BaseChatModel | undefined;\n const getEmulatorModel = async (): Promise<BaseChatModel> => {\n if (typeof model === \"object\") {\n return model;\n }\n if (typeof model === \"string\") {\n emulatorModel =\n emulatorModel ??\n (await initChatModel(model, { temperature: 1 }).catch((err) => {\n console.error(\n \"Error initializing emulator model, using agent model:\",\n err\n );\n return agentModel as BaseChatModel;\n }));\n return emulatorModel;\n }\n return agentModel as BaseChatModel;\n };\n\n return createMiddleware({\n name: \"ToolEmulatorMiddleware\",\n wrapModelCall: async (request, handler) => {\n agentModel = request.model as BaseChatModel;\n return handler(request);\n },\n wrapToolCall: async (request, handler) => {\n const toolName = request.toolCall.name;\n\n // Check if this tool should be emulated\n const shouldEmulate = emulateAll || toolsToEmulate.has(toolName);\n\n if (!shouldEmulate) {\n // Let it execute normally by calling the handler\n return handler(request);\n }\n\n // Extract tool information for emulation\n const toolArgs = request.toolCall.args;\n const toolDescription =\n request.tool.description || \"No description available\";\n\n // Build prompt for emulator LLM\n const toolArgsString =\n typeof toolArgs === \"string\" ? toolArgs : JSON.stringify(toolArgs);\n const prompt = `You are emulating a tool call for testing purposes.\n\nTool: ${toolName}\nDescription: ${toolDescription}\nArguments: ${toolArgsString}\n\nGenerate a realistic response that this tool would return given these arguments.\nReturn ONLY the tool's output, no explanation or preamble. Introduce variation into your responses.`;\n\n // Get emulated response from LLM\n const emulator = await getEmulatorModel();\n const response = await emulator.invoke([new HumanMessage(prompt)]);\n\n // Extract content from response\n const content =\n typeof response.content === \"string\"\n ? response.content\n : JSON.stringify(response.content);\n\n // Short-circuit: return emulated result without executing real tool\n return new ToolMessage({\n content,\n tool_call_id: request.toolCall.id ?? \"\",\n name: toolName,\n });\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0EA,SAAgB,uBACdA,UAA+B,CAAE,GACI;CACrC,IAAIC;CACJ,MAAM,EAAE,OAAO,OAAO,GAAG;;;;CAKzB,MAAM,aAAa,CAAC,SAAS,MAAM,WAAW;CAC9C,MAAM,iCAAiB,IAAI;AAE3B,KAAI,CAAC,cAAc,MACjB,MAAK,MAAM,QAAQ,MACjB,KAAI,OAAO,SAAS,UAClB,eAAe,IAAI,KAAK;MACnB;EAEL,MAAM,WACJ,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,OAAO,KAAK,KAAK;EAC/D,eAAe,IAAI,SAAS;CAC7B;;;;;CAQL,IAAIC;CACJ,MAAM,mBAAmB,YAAoC;AAC3D,MAAI,OAAO,UAAU,SACnB,QAAO;AAET,MAAI,OAAO,UAAU,UAAU;GAC7B,gBACE,iBACC,MAAM,cAAc,OAAO,EAAE,aAAa,EAAG,EAAC,CAAC,MAAM,CAAC,QAAQ;IAC7D,QAAQ,MACN,yDACA,IACD;AACD,WAAO;GACR,EAAC;AACJ,UAAO;EACR;AACD,SAAO;CACR;AAED,QAAO,iBAAiB;EACtB,MAAM;EACN,eAAe,OAAO,SAAS,YAAY;GACzC,aAAa,QAAQ;AACrB,UAAO,QAAQ,QAAQ;EACxB;EACD,cAAc,OAAO,SAAS,YAAY;GACxC,MAAM,WAAW,QAAQ,SAAS;GAGlC,MAAM,gBAAgB,cAAc,eAAe,IAAI,SAAS;AAEhE,OAAI,CAAC,cAEH,QAAO,QAAQ,QAAQ;GAIzB,MAAM,WAAW,QAAQ,SAAS;GAClC,MAAM,kBACJ,QAAQ,KAAK,eAAe;GAG9B,MAAM,iBACJ,OAAO,aAAa,WAAW,WAAW,KAAK,UAAU,SAAS;GACpE,MAAM,SAAS,CAAC;;MAEhB,EAAE,SAAS;aACJ,EAAE,gBAAgB;WACpB,EAAE,eAAe;;;mGAGuE,CAAC;GAG9F,MAAM,WAAW,MAAM,kBAAkB;GACzC,MAAM,WAAW,MAAM,SAAS,OAAO,CAAC,IAAI,aAAa,OAAQ,EAAC;GAGlE,MAAM,UACJ,OAAO,SAAS,YAAY,WACxB,SAAS,UACT,KAAK,UAAU,SAAS,QAAQ;AAGtC,UAAO,IAAI,YAAY;IACrB;IACA,cAAc,QAAQ,SAAS,MAAM;IACrC,MAAM;GACP;EACF;CACF,EAAC;AACH"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const __langchain_core_messages = require_rolldown_runtime.__toESM(require("@langchain/core/messages"));
|
|
1
3
|
|
|
2
4
|
//#region src/agents/middleware/utils.ts
|
|
3
5
|
/**
|
|
@@ -16,6 +18,8 @@ function countTokensApproximately(messages) {
|
|
|
16
18
|
return "";
|
|
17
19
|
}).join("");
|
|
18
20
|
else textContent = "";
|
|
21
|
+
if (__langchain_core_messages.AIMessage.isInstance(msg) && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0) textContent += JSON.stringify(msg.tool_calls);
|
|
22
|
+
if (__langchain_core_messages.ToolMessage.isInstance(msg)) textContent += msg.tool_call_id ?? "";
|
|
19
23
|
totalChars += textContent.length;
|
|
20
24
|
}
|
|
21
25
|
return Math.ceil(totalChars / 4);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.cjs","names":["messages: BaseMessage[]","textContent: string","hook:\n | BeforeAgentHook\n | BeforeModelHook\n | AfterAgentHook\n | AfterModelHook\n | undefined","arg: BeforeAgentHook | BeforeModelHook | AfterAgentHook | AfterModelHook","ms: number"],"sources":["../../../src/agents/middleware/utils.ts"],"sourcesContent":["import type
|
|
1
|
+
{"version":3,"file":"utils.cjs","names":["messages: BaseMessage[]","textContent: string","AIMessage","ToolMessage","hook:\n | BeforeAgentHook\n | BeforeModelHook\n | AfterAgentHook\n | AfterModelHook\n | undefined","arg: BeforeAgentHook | BeforeModelHook | AfterAgentHook | AfterModelHook","ms: number"],"sources":["../../../src/agents/middleware/utils.ts"],"sourcesContent":["import {\n AIMessage,\n ToolMessage,\n type BaseMessage,\n} from \"@langchain/core/messages\";\nimport {\n AfterModelHook,\n AfterAgentHook,\n BeforeAgentHook,\n BeforeModelHook,\n} from \"./types.js\";\nimport { JumpToTarget } from \"../constants.js\";\n\n/**\n * Default token counter that approximates based on character count\n * @param messages Messages to count tokens for\n * @returns Approximate token count\n */\nexport function countTokensApproximately(messages: BaseMessage[]): number {\n let totalChars = 0;\n for (const msg of messages) {\n let textContent: string;\n if (typeof msg.content === \"string\") {\n textContent = msg.content;\n } else if (Array.isArray(msg.content)) {\n textContent = msg.content\n .map((item) => {\n if (typeof item === \"string\") return item;\n if (item.type === \"text\" && \"text\" in item) return item.text;\n return \"\";\n })\n .join(\"\");\n } else {\n textContent = \"\";\n }\n\n if (\n AIMessage.isInstance(msg) &&\n Array.isArray(msg.tool_calls) &&\n msg.tool_calls.length > 0\n ) {\n textContent += JSON.stringify(msg.tool_calls);\n }\n\n if (ToolMessage.isInstance(msg)) {\n textContent += msg.tool_call_id ?? \"\";\n }\n\n totalChars += textContent.length;\n }\n // Approximate 1 token = 4 characters\n return Math.ceil(totalChars / 4);\n}\n\nexport function getHookConstraint(\n hook:\n | BeforeAgentHook\n | BeforeModelHook\n | AfterAgentHook\n | AfterModelHook\n | undefined\n): JumpToTarget[] | undefined {\n if (!hook || typeof hook === \"function\") {\n return undefined;\n }\n return hook.canJumpTo;\n}\n\nexport function getHookFunction(\n arg: BeforeAgentHook | BeforeModelHook | AfterAgentHook | AfterModelHook\n) {\n if (typeof arg === \"function\") {\n return arg;\n }\n return arg.hook;\n}\n\n/**\n * Sleep for the specified number of milliseconds.\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"],"mappings":";;;;;;;;;AAkBA,SAAgB,yBAAyBA,UAAiC;CACxE,IAAI,aAAa;AACjB,MAAK,MAAM,OAAO,UAAU;EAC1B,IAAIC;AACJ,MAAI,OAAO,IAAI,YAAY,UACzB,cAAc,IAAI;WACT,MAAM,QAAQ,IAAI,QAAQ,EACnC,cAAc,IAAI,QACf,IAAI,CAAC,SAAS;AACb,OAAI,OAAO,SAAS,SAAU,QAAO;AACrC,OAAI,KAAK,SAAS,UAAU,UAAU,KAAM,QAAO,KAAK;AACxD,UAAO;EACR,EAAC,CACD,KAAK,GAAG;OAEX,cAAc;AAGhB,MACEC,oCAAU,WAAW,IAAI,IACzB,MAAM,QAAQ,IAAI,WAAW,IAC7B,IAAI,WAAW,SAAS,GAExB,eAAe,KAAK,UAAU,IAAI,WAAW;AAG/C,MAAIC,sCAAY,WAAW,IAAI,EAC7B,eAAe,IAAI,gBAAgB;EAGrC,cAAc,YAAY;CAC3B;AAED,QAAO,KAAK,KAAK,aAAa,EAAE;AACjC;AAED,SAAgB,kBACdC,MAM4B;AAC5B,KAAI,CAAC,QAAQ,OAAO,SAAS,WAC3B,QAAO;AAET,QAAO,KAAK;AACb;AAED,SAAgB,gBACdC,KACA;AACA,KAAI,OAAO,QAAQ,WACjB,QAAO;AAET,QAAO,IAAI;AACZ;;;;AAKD,SAAgB,MAAMC,IAA2B;AAC/C,QAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAG;AACxD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.cts","names":["
|
|
1
|
+
{"version":3,"file":"utils.d.cts","names":["__types_js0","BaseMessage","AfterModelHook","AfterAgentHook","BeforeAgentHook","BeforeModelHook","JumpToTarget","countTokensApproximately","getHookConstraint","getHookFunction","___runtime_js0","AgentBuiltInState","Runtime","Partial","MiddlewareResult","Promise","sleep"],"sources":["../../../src/agents/middleware/utils.d.ts"],"sourcesContent":["import { type BaseMessage } from \"@langchain/core/messages\";\nimport { AfterModelHook, AfterAgentHook, BeforeAgentHook, BeforeModelHook } from \"./types.js\";\nimport { JumpToTarget } from \"../constants.js\";\n/**\n * Default token counter that approximates based on character count\n * @param messages Messages to count tokens for\n * @returns Approximate token count\n */\nexport declare function countTokensApproximately(messages: BaseMessage[]): number;\nexport declare function getHookConstraint(hook: BeforeAgentHook | BeforeModelHook | AfterAgentHook | AfterModelHook | undefined): JumpToTarget[] | undefined;\nexport declare function getHookFunction(arg: BeforeAgentHook | BeforeModelHook | AfterAgentHook | AfterModelHook): ((state: import(\"../runtime.js\").AgentBuiltInState, runtime: import(\"../runtime.js\").Runtime<unknown>) => Promise<import(\"./types.js\").MiddlewareResult<Partial<import(\"../runtime.js\").AgentBuiltInState>>> | import(\"./types.js\").MiddlewareResult<Partial<import(\"../runtime.js\").AgentBuiltInState>>) | ((state: import(\"../runtime.js\").AgentBuiltInState, runtime: import(\"../runtime.js\").Runtime<unknown>) => Promise<import(\"./types.js\").MiddlewareResult<Partial<import(\"../runtime.js\").AgentBuiltInState>>> | import(\"./types.js\").MiddlewareResult<Partial<import(\"../runtime.js\").AgentBuiltInState>>) | ((state: import(\"../runtime.js\").AgentBuiltInState, runtime: import(\"../runtime.js\").Runtime<unknown>) => Promise<import(\"./types.js\").MiddlewareResult<Partial<import(\"../runtime.js\").AgentBuiltInState>>> | import(\"./types.js\").MiddlewareResult<Partial<import(\"../runtime.js\").AgentBuiltInState>>) | ((state: import(\"../runtime.js\").AgentBuiltInState, runtime: import(\"../runtime.js\").Runtime<unknown>) => Promise<import(\"./types.js\").MiddlewareResult<Partial<import(\"../runtime.js\").AgentBuiltInState>>> | import(\"./types.js\").MiddlewareResult<Partial<import(\"../runtime.js\").AgentBuiltInState>>);\n/**\n * Sleep for the specified number of milliseconds.\n */\nexport declare function sleep(ms: number): Promise<void>;\n"],"mappings":";;;;AAQA;;;;;iBAAwBO,wBAAAA,WAAmCN"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","names":["
|
|
1
|
+
{"version":3,"file":"utils.d.ts","names":["__types_js7","BaseMessage","AfterModelHook","AfterAgentHook","BeforeAgentHook","BeforeModelHook","JumpToTarget","countTokensApproximately","getHookConstraint","getHookFunction","___runtime_js0","AgentBuiltInState","Runtime","Partial","MiddlewareResult","Promise","sleep"],"sources":["../../../src/agents/middleware/utils.d.ts"],"sourcesContent":["import { type BaseMessage } from \"@langchain/core/messages\";\nimport { AfterModelHook, AfterAgentHook, BeforeAgentHook, BeforeModelHook } from \"./types.js\";\nimport { JumpToTarget } from \"../constants.js\";\n/**\n * Default token counter that approximates based on character count\n * @param messages Messages to count tokens for\n * @returns Approximate token count\n */\nexport declare function countTokensApproximately(messages: BaseMessage[]): number;\nexport declare function getHookConstraint(hook: BeforeAgentHook | BeforeModelHook | AfterAgentHook | AfterModelHook | undefined): JumpToTarget[] | undefined;\nexport declare function getHookFunction(arg: BeforeAgentHook | BeforeModelHook | AfterAgentHook | AfterModelHook): ((state: import(\"../runtime.js\").AgentBuiltInState, runtime: import(\"../runtime.js\").Runtime<unknown>) => Promise<import(\"./types.js\").MiddlewareResult<Partial<import(\"../runtime.js\").AgentBuiltInState>>> | import(\"./types.js\").MiddlewareResult<Partial<import(\"../runtime.js\").AgentBuiltInState>>) | ((state: import(\"../runtime.js\").AgentBuiltInState, runtime: import(\"../runtime.js\").Runtime<unknown>) => Promise<import(\"./types.js\").MiddlewareResult<Partial<import(\"../runtime.js\").AgentBuiltInState>>> | import(\"./types.js\").MiddlewareResult<Partial<import(\"../runtime.js\").AgentBuiltInState>>) | ((state: import(\"../runtime.js\").AgentBuiltInState, runtime: import(\"../runtime.js\").Runtime<unknown>) => Promise<import(\"./types.js\").MiddlewareResult<Partial<import(\"../runtime.js\").AgentBuiltInState>>> | import(\"./types.js\").MiddlewareResult<Partial<import(\"../runtime.js\").AgentBuiltInState>>) | ((state: import(\"../runtime.js\").AgentBuiltInState, runtime: import(\"../runtime.js\").Runtime<unknown>) => Promise<import(\"./types.js\").MiddlewareResult<Partial<import(\"../runtime.js\").AgentBuiltInState>>> | import(\"./types.js\").MiddlewareResult<Partial<import(\"../runtime.js\").AgentBuiltInState>>);\n/**\n * Sleep for the specified number of milliseconds.\n */\nexport declare function sleep(ms: number): Promise<void>;\n"],"mappings":";;;;AAQA;;;;;iBAAwBO,wBAAAA,WAAmCN"}
|