@librechat/agents 3.3.12 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/dist/cjs/graphs/Graph.cjs +10 -0
  2. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  3. package/dist/cjs/instrumentation.cjs +1 -0
  4. package/dist/cjs/instrumentation.cjs.map +1 -1
  5. package/dist/cjs/langfuseSpanRegistry.cjs +6 -3
  6. package/dist/cjs/langfuseSpanRegistry.cjs.map +1 -1
  7. package/dist/cjs/llm/anthropic/index.cjs +35 -206
  8. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  9. package/dist/cjs/llm/bedrock/index.cjs +121 -241
  10. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  11. package/dist/cjs/llm/google/index.cjs +19 -12
  12. package/dist/cjs/llm/google/index.cjs.map +1 -1
  13. package/dist/cjs/llm/mistral/index.cjs +26 -0
  14. package/dist/cjs/llm/mistral/index.cjs.map +1 -0
  15. package/dist/cjs/llm/openai/index.cjs +82 -80
  16. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  17. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  18. package/dist/cjs/llm/providers.cjs +19 -19
  19. package/dist/cjs/llm/providers.cjs.map +1 -1
  20. package/dist/cjs/llm/stream/chunkAdapters.cjs +198 -0
  21. package/dist/cjs/llm/stream/chunkAdapters.cjs.map +1 -0
  22. package/dist/cjs/llm/stream/smoother.cjs +369 -0
  23. package/dist/cjs/llm/stream/smoother.cjs.map +1 -0
  24. package/dist/cjs/llm/vertexai/index.cjs +13 -1
  25. package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
  26. package/dist/cjs/main.cjs +18 -10
  27. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +34 -2
  28. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  29. package/dist/cjs/utils/tokens.cjs +76 -29
  30. package/dist/cjs/utils/tokens.cjs.map +1 -1
  31. package/dist/esm/graphs/Graph.mjs +10 -0
  32. package/dist/esm/graphs/Graph.mjs.map +1 -1
  33. package/dist/esm/instrumentation.mjs +1 -0
  34. package/dist/esm/instrumentation.mjs.map +1 -1
  35. package/dist/esm/langfuseSpanRegistry.mjs +6 -3
  36. package/dist/esm/langfuseSpanRegistry.mjs.map +1 -1
  37. package/dist/esm/llm/anthropic/index.mjs +34 -205
  38. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  39. package/dist/esm/llm/bedrock/index.mjs +120 -240
  40. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  41. package/dist/esm/llm/google/index.mjs +19 -12
  42. package/dist/esm/llm/google/index.mjs.map +1 -1
  43. package/dist/esm/llm/mistral/index.mjs +26 -0
  44. package/dist/esm/llm/mistral/index.mjs.map +1 -0
  45. package/dist/esm/llm/openai/index.mjs +82 -80
  46. package/dist/esm/llm/openai/index.mjs.map +1 -1
  47. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  48. package/dist/esm/llm/providers.mjs +3 -3
  49. package/dist/esm/llm/providers.mjs.map +1 -1
  50. package/dist/esm/llm/stream/chunkAdapters.mjs +195 -0
  51. package/dist/esm/llm/stream/chunkAdapters.mjs.map +1 -0
  52. package/dist/esm/llm/stream/smoother.mjs +365 -0
  53. package/dist/esm/llm/stream/smoother.mjs.map +1 -0
  54. package/dist/esm/llm/vertexai/index.mjs +13 -1
  55. package/dist/esm/llm/vertexai/index.mjs.map +1 -1
  56. package/dist/esm/main.mjs +4 -2
  57. package/dist/esm/tools/subagent/SubagentExecutor.mjs +34 -2
  58. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  59. package/dist/esm/utils/tokens.mjs +76 -30
  60. package/dist/esm/utils/tokens.mjs.map +1 -1
  61. package/dist/types/graphs/Graph.d.ts +3 -0
  62. package/dist/types/index.d.ts +3 -0
  63. package/dist/types/llm/google/index.d.ts +2 -0
  64. package/dist/types/llm/mistral/index.d.ts +11 -0
  65. package/dist/types/llm/openai/index.d.ts +20 -4
  66. package/dist/types/llm/openrouter/index.d.ts +4 -1
  67. package/dist/types/llm/stream/chunkAdapters.d.ts +48 -0
  68. package/dist/types/llm/stream/smoother.d.ts +95 -0
  69. package/dist/types/llm/vertexai/index.d.ts +2 -0
  70. package/dist/types/tools/subagent/SubagentExecutor.d.ts +3 -0
  71. package/dist/types/types/graph.d.ts +5 -0
  72. package/dist/types/types/llm.d.ts +21 -14
  73. package/dist/types/utils/tokens.d.ts +10 -0
  74. package/package.json +2 -2
  75. package/src/graphs/Graph.ts +11 -0
  76. package/src/index.ts +8 -0
  77. package/src/instrumentation.ts +1 -0
  78. package/src/langfuseSpanRegistry.ts +9 -0
  79. package/src/llm/anthropic/index.ts +85 -354
  80. package/src/llm/bedrock/index.ts +174 -390
  81. package/src/llm/bedrock/llm.spec.ts +2 -0
  82. package/src/llm/bedrock/streamSealDispatch.test.ts +76 -0
  83. package/src/llm/custom-chat-models.smoke.test.ts +16 -1
  84. package/src/llm/google/index.ts +17 -18
  85. package/src/llm/google/streamSmoothing.test.ts +121 -0
  86. package/src/llm/mistral/index.ts +33 -0
  87. package/src/llm/mistral/streamSmoothing.test.ts +97 -0
  88. package/src/llm/openai/deepseek.test.ts +56 -0
  89. package/src/llm/openai/index.ts +119 -126
  90. package/src/llm/openrouter/index.ts +4 -1
  91. package/src/llm/providers.ts +3 -3
  92. package/src/llm/stream/chunkAdapters.test.ts +202 -0
  93. package/src/llm/stream/chunkAdapters.ts +317 -0
  94. package/src/llm/stream/reassembly.test.ts +241 -0
  95. package/src/llm/stream/smoother.bench.test.ts +155 -0
  96. package/src/llm/stream/smoother.test.ts +519 -0
  97. package/src/llm/stream/smoother.ts +574 -0
  98. package/src/llm/vertexai/index.ts +17 -1
  99. package/src/llm/vertexai/streamSmoothing.test.ts +109 -0
  100. package/src/specs/langfuse-instrumentation.test.ts +26 -0
  101. package/src/specs/langfuse-span-registry.test.ts +17 -0
  102. package/src/specs/subagent.test.ts +44 -0
  103. package/src/specs/summarization.test.ts +5 -2
  104. package/src/specs/tokens.test.ts +159 -14
  105. package/src/tools/__tests__/SubagentExecutor.test.ts +48 -1
  106. package/src/tools/subagent/SubagentExecutor.ts +69 -5
  107. package/src/types/graph.ts +5 -0
  108. package/src/types/llm.ts +53 -36
  109. package/src/utils/tokens.ts +115 -30
@@ -48,6 +48,7 @@ function ensureOpenTelemetryContextManager() {
48
48
  function getLangfuseProcessorCacheKey(destinationKey, langfuse) {
49
49
  return JSON.stringify({
50
50
  destinationKey,
51
+ mediaUploadEnabled: langfuse?.mediaUploadEnabled,
51
52
  toolOutputTracing: langfuse?.toolOutputTracing
52
53
  });
53
54
  }
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentation.mjs","names":[],"sources":["../../src/instrumentation.ts"],"sourcesContent":["import { randomBytes } from 'node:crypto';\nimport { setLangfuseTracerProvider } from '@langfuse/tracing';\nimport { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';\nimport { context, ROOT_CONTEXT, createContextKey } from '@opentelemetry/api';\nimport { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks';\nimport type {\n IdGenerator,\n ReadableSpan,\n Span,\n SpanProcessor,\n} from '@opentelemetry/sdk-trace-base';\nimport type { LangfuseSpanProcessorParams } from '@langfuse/otel';\nimport type { Context } from '@opentelemetry/api';\nimport type * as t from '@/types';\nimport {\n getLangfuseDestinationKey,\n getLangfuseSpanProcessorParams,\n registerLangfuseManagedSpan,\n} from '@/langfuseSpanRegistry';\nimport {\n resolveLangfuseConfigForSpan,\n resolveTraceIdSeedForSpan,\n} from '@/langfuseRuntimeScope';\nimport { createLangfuseSpanProcessor } from '@/langfuseToolOutputTracing';\nimport { createLibreChatTraceAttributes } from '@/langfuse';\nimport { traceIdFromSeed } from '@/langfuseRuntimeContext';\nimport { isPresent } from '@/utils/misc';\n\n/**\n * Per-run seed for deterministic Langfuse trace ids. When a run opts in\n * (`LangfuseConfig.deterministicTraceId`), it executes its stream inside\n * `runWithTraceIdSeed(runId, ...)` from `./langfuseRuntimeContext`, and the\n * IdGenerator below derives the root trace id from that seed instead of a\n * random one. This lets external systems (e.g. a host app recording user\n * feedback after the fact) attach scores or observations to the trace by\n * regenerating the same id from the run/message id; no trace lookup required.\n * With no active seed it falls back to random ids, so default behavior is\n * unchanged.\n */\nclass SeededTraceIdGenerator implements IdGenerator {\n generateTraceId(): string {\n const seed = resolveTraceIdSeedForSpan(context.active());\n return isPresent(seed)\n ? traceIdFromSeed(seed)\n : randomBytes(16).toString('hex');\n }\n\n generateSpanId(): string {\n return randomBytes(8).toString('hex');\n }\n}\n\nlet langfuseTracerProvider: BasicTracerProvider | undefined;\nlet langfuseRoutingSpanProcessor: RoutingLangfuseSpanProcessor | undefined;\nconst contextManagerProbeKey = createContextKey(\n 'langfuse-context-manager-probe'\n);\n\nfunction hasActiveContextManager(): boolean {\n return context.with(\n ROOT_CONTEXT.setValue(contextManagerProbeKey, true),\n () => context.active().getValue(contextManagerProbeKey) === true\n );\n}\n\nexport function ensureOpenTelemetryContextManager(): void {\n if (hasActiveContextManager()) {\n return;\n }\n\n const contextManager = new AsyncLocalStorageContextManager();\n contextManager.enable();\n if (!context.setGlobalContextManager(contextManager)) {\n contextManager.disable();\n }\n}\n\n/** Cache key for processor instances: the destination plus processor-level\n * policy (`toolOutputTracing` is baked into each processor's redaction\n * behavior), unlike the pure destination identity used for span parenting. */\nfunction getLangfuseProcessorCacheKey(\n destinationKey: string,\n langfuse?: t.LangfuseConfig\n): string {\n return JSON.stringify({\n destinationKey,\n toolOutputTracing: langfuse?.toolOutputTracing,\n });\n}\n\nclass RoutingLangfuseSpanProcessor implements SpanProcessor {\n // Processors live for the process lifetime. LibreChat tenant Langfuse\n // destinations are expected to be a bounded admin-managed set, and shutdown\n // drains every cached processor when the provider is disposed.\n private readonly processors = new Map<string, SpanProcessor>();\n private readonly spanProcessors = new WeakMap<object, SpanProcessor>();\n\n ensureProcessor(langfuse?: t.LangfuseConfig): SpanProcessor | undefined {\n const params = getLangfuseSpanProcessorParams(langfuse);\n if (params == null) {\n return undefined;\n }\n return this.ensureProcessorForKey(\n getLangfuseProcessorCacheKey(getLangfuseDestinationKey(params), langfuse),\n params,\n langfuse\n );\n }\n\n private ensureProcessorForKey(\n processorCacheKey: string,\n params: LangfuseSpanProcessorParams,\n langfuse?: t.LangfuseConfig\n ): SpanProcessor {\n const existing = this.processors.get(processorCacheKey);\n if (existing != null) {\n return existing;\n }\n\n const processor = createLangfuseSpanProcessor(params, langfuse);\n this.processors.set(processorCacheKey, processor);\n return processor;\n }\n\n onStart(span: Span, parentContext: Context): void {\n const langfuse = resolveLangfuseConfigForSpan(parentContext);\n const params = getLangfuseSpanProcessorParams(langfuse);\n if (params == null) {\n return;\n }\n\n const destinationKey = getLangfuseDestinationKey(params);\n const processor = this.ensureProcessorForKey(\n getLangfuseProcessorCacheKey(destinationKey, langfuse),\n params,\n langfuse\n );\n registerLangfuseManagedSpan(span, destinationKey);\n\n const librechatTraceAttributes = createLibreChatTraceAttributes(\n langfuse?.librechatTraceAttributes ?? {}\n );\n if (Object.keys(librechatTraceAttributes).length > 0) {\n span.setAttributes(librechatTraceAttributes);\n }\n\n this.spanProcessors.set(span, processor);\n processor.onStart(span, parentContext);\n }\n\n onEnd(span: ReadableSpan): void {\n this.spanProcessors.get(span)?.onEnd(span);\n }\n\n async forceFlush(): Promise<void> {\n await Promise.all(\n Array.from(this.processors.values(), (processor) =>\n processor.forceFlush()\n )\n );\n }\n\n async shutdown(): Promise<void> {\n await Promise.all(\n Array.from(this.processors.values(), (processor) => processor.shutdown())\n );\n }\n}\n\nexport function initializeLangfuseTracing(\n langfuse?: t.LangfuseConfig\n): BasicTracerProvider | undefined {\n const params = getLangfuseSpanProcessorParams(langfuse);\n if (params == null) {\n return undefined;\n }\n\n if (langfuseTracerProvider != null) {\n langfuseRoutingSpanProcessor?.ensureProcessor(langfuse);\n return langfuseTracerProvider;\n }\n\n ensureOpenTelemetryContextManager();\n langfuseRoutingSpanProcessor = new RoutingLangfuseSpanProcessor();\n langfuseRoutingSpanProcessor.ensureProcessor(langfuse);\n langfuseTracerProvider = new BasicTracerProvider({\n spanProcessors: [langfuseRoutingSpanProcessor],\n idGenerator: new SeededTraceIdGenerator(),\n });\n\n setLangfuseTracerProvider(langfuseTracerProvider);\n return langfuseTracerProvider;\n}\n\nexport function initializeLangfuseTracingFromEnv():\n | BasicTracerProvider\n | undefined {\n return initializeLangfuseTracing();\n}\n\ninitializeLangfuseTracingFromEnv();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuCA,IAAM,yBAAN,MAAoD;CAClD,kBAA0B;EACxB,MAAM,OAAO,0BAA0B,QAAQ,OAAO,CAAC;EACvD,OAAO,UAAU,IAAI,IACjB,gBAAgB,IAAI,IACpB,YAAY,EAAE,CAAC,CAAC,SAAS,KAAK;CACpC;CAEA,iBAAyB;EACvB,OAAO,YAAY,CAAC,CAAC,CAAC,SAAS,KAAK;CACtC;AACF;AAEA,IAAI;AACJ,IAAI;AACJ,MAAM,yBAAyB,iBAC7B,gCACF;AAEA,SAAS,0BAAmC;CAC1C,OAAO,QAAQ,KACb,aAAa,SAAS,wBAAwB,IAAI,SAC5C,QAAQ,OAAO,CAAC,CAAC,SAAS,sBAAsB,MAAM,IAC9D;AACF;AAEA,SAAgB,oCAA0C;CACxD,IAAI,wBAAwB,GAC1B;CAGF,MAAM,iBAAiB,IAAI,gCAAgC;CAC3D,eAAe,OAAO;CACtB,IAAI,CAAC,QAAQ,wBAAwB,cAAc,GACjD,eAAe,QAAQ;AAE3B;;;;AAKA,SAAS,6BACP,gBACA,UACQ;CACR,OAAO,KAAK,UAAU;EACpB;EACA,mBAAmB,UAAU;CAC/B,CAAC;AACH;AAEA,IAAM,+BAAN,MAA4D;CAI1D,6BAA8B,IAAI,IAA2B;CAC7D,iCAAkC,IAAI,QAA+B;CAErE,gBAAgB,UAAwD;EACtE,MAAM,SAAS,+BAA+B,QAAQ;EACtD,IAAI,UAAU,MACZ;EAEF,OAAO,KAAK,sBACV,6BAA6B,0BAA0B,MAAM,GAAG,QAAQ,GACxE,QACA,QACF;CACF;CAEA,sBACE,mBACA,QACA,UACe;EACf,MAAM,WAAW,KAAK,WAAW,IAAI,iBAAiB;EACtD,IAAI,YAAY,MACd,OAAO;EAGT,MAAM,YAAY,4BAA4B,QAAQ,QAAQ;EAC9D,KAAK,WAAW,IAAI,mBAAmB,SAAS;EAChD,OAAO;CACT;CAEA,QAAQ,MAAY,eAA8B;EAChD,MAAM,WAAW,6BAA6B,aAAa;EAC3D,MAAM,SAAS,+BAA+B,QAAQ;EACtD,IAAI,UAAU,MACZ;EAGF,MAAM,iBAAiB,0BAA0B,MAAM;EACvD,MAAM,YAAY,KAAK,sBACrB,6BAA6B,gBAAgB,QAAQ,GACrD,QACA,QACF;EACA,4BAA4B,MAAM,cAAc;EAEhD,MAAM,2BAA2B,+BAC/B,UAAU,4BAA4B,CAAC,CACzC;EACA,IAAI,OAAO,KAAK,wBAAwB,CAAC,CAAC,SAAS,GACjD,KAAK,cAAc,wBAAwB;EAG7C,KAAK,eAAe,IAAI,MAAM,SAAS;EACvC,UAAU,QAAQ,MAAM,aAAa;CACvC;CAEA,MAAM,MAA0B;EAC9B,KAAK,eAAe,IAAI,IAAI,CAAC,EAAE,MAAM,IAAI;CAC3C;CAEA,MAAM,aAA4B;EAChC,MAAM,QAAQ,IACZ,MAAM,KAAK,KAAK,WAAW,OAAO,IAAI,cACpC,UAAU,WAAW,CACvB,CACF;CACF;CAEA,MAAM,WAA0B;EAC9B,MAAM,QAAQ,IACZ,MAAM,KAAK,KAAK,WAAW,OAAO,IAAI,cAAc,UAAU,SAAS,CAAC,CAC1E;CACF;AACF;AAEA,SAAgB,0BACd,UACiC;CAEjC,IADe,+BAA+B,QACrC,KAAK,MACZ;CAGF,IAAI,0BAA0B,MAAM;EAClC,8BAA8B,gBAAgB,QAAQ;EACtD,OAAO;CACT;CAEA,kCAAkC;CAClC,+BAA+B,IAAI,6BAA6B;CAChE,6BAA6B,gBAAgB,QAAQ;CACrD,yBAAyB,IAAI,oBAAoB;EAC/C,gBAAgB,CAAC,4BAA4B;EAC7C,aAAa,IAAI,uBAAuB;CAC1C,CAAC;CAED,0BAA0B,sBAAsB;CAChD,OAAO;AACT;AAEA,SAAgB,mCAEF;CACZ,OAAO,0BAA0B;AACnC;AAEA,iCAAiC"}
1
+ {"version":3,"file":"instrumentation.mjs","names":[],"sources":["../../src/instrumentation.ts"],"sourcesContent":["import { randomBytes } from 'node:crypto';\nimport { setLangfuseTracerProvider } from '@langfuse/tracing';\nimport { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';\nimport { context, ROOT_CONTEXT, createContextKey } from '@opentelemetry/api';\nimport { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks';\nimport type {\n IdGenerator,\n ReadableSpan,\n Span,\n SpanProcessor,\n} from '@opentelemetry/sdk-trace-base';\nimport type { LangfuseSpanProcessorParams } from '@langfuse/otel';\nimport type { Context } from '@opentelemetry/api';\nimport type * as t from '@/types';\nimport {\n getLangfuseDestinationKey,\n getLangfuseSpanProcessorParams,\n registerLangfuseManagedSpan,\n} from '@/langfuseSpanRegistry';\nimport {\n resolveLangfuseConfigForSpan,\n resolveTraceIdSeedForSpan,\n} from '@/langfuseRuntimeScope';\nimport { createLangfuseSpanProcessor } from '@/langfuseToolOutputTracing';\nimport { createLibreChatTraceAttributes } from '@/langfuse';\nimport { traceIdFromSeed } from '@/langfuseRuntimeContext';\nimport { isPresent } from '@/utils/misc';\n\n/**\n * Per-run seed for deterministic Langfuse trace ids. When a run opts in\n * (`LangfuseConfig.deterministicTraceId`), it executes its stream inside\n * `runWithTraceIdSeed(runId, ...)` from `./langfuseRuntimeContext`, and the\n * IdGenerator below derives the root trace id from that seed instead of a\n * random one. This lets external systems (e.g. a host app recording user\n * feedback after the fact) attach scores or observations to the trace by\n * regenerating the same id from the run/message id; no trace lookup required.\n * With no active seed it falls back to random ids, so default behavior is\n * unchanged.\n */\nclass SeededTraceIdGenerator implements IdGenerator {\n generateTraceId(): string {\n const seed = resolveTraceIdSeedForSpan(context.active());\n return isPresent(seed)\n ? traceIdFromSeed(seed)\n : randomBytes(16).toString('hex');\n }\n\n generateSpanId(): string {\n return randomBytes(8).toString('hex');\n }\n}\n\nlet langfuseTracerProvider: BasicTracerProvider | undefined;\nlet langfuseRoutingSpanProcessor: RoutingLangfuseSpanProcessor | undefined;\nconst contextManagerProbeKey = createContextKey(\n 'langfuse-context-manager-probe'\n);\n\nfunction hasActiveContextManager(): boolean {\n return context.with(\n ROOT_CONTEXT.setValue(contextManagerProbeKey, true),\n () => context.active().getValue(contextManagerProbeKey) === true\n );\n}\n\nexport function ensureOpenTelemetryContextManager(): void {\n if (hasActiveContextManager()) {\n return;\n }\n\n const contextManager = new AsyncLocalStorageContextManager();\n contextManager.enable();\n if (!context.setGlobalContextManager(contextManager)) {\n contextManager.disable();\n }\n}\n\n/** Cache key for processor instances: the destination plus processor-level\n * policy (`toolOutputTracing` is baked into each processor's redaction\n * behavior), unlike the pure destination identity used for span parenting. */\nfunction getLangfuseProcessorCacheKey(\n destinationKey: string,\n langfuse?: t.LangfuseConfig\n): string {\n return JSON.stringify({\n destinationKey,\n mediaUploadEnabled: langfuse?.mediaUploadEnabled,\n toolOutputTracing: langfuse?.toolOutputTracing,\n });\n}\n\nclass RoutingLangfuseSpanProcessor implements SpanProcessor {\n // Processors live for the process lifetime. LibreChat tenant Langfuse\n // destinations are expected to be a bounded admin-managed set, and shutdown\n // drains every cached processor when the provider is disposed.\n private readonly processors = new Map<string, SpanProcessor>();\n private readonly spanProcessors = new WeakMap<object, SpanProcessor>();\n\n ensureProcessor(langfuse?: t.LangfuseConfig): SpanProcessor | undefined {\n const params = getLangfuseSpanProcessorParams(langfuse);\n if (params == null) {\n return undefined;\n }\n return this.ensureProcessorForKey(\n getLangfuseProcessorCacheKey(getLangfuseDestinationKey(params), langfuse),\n params,\n langfuse\n );\n }\n\n private ensureProcessorForKey(\n processorCacheKey: string,\n params: LangfuseSpanProcessorParams,\n langfuse?: t.LangfuseConfig\n ): SpanProcessor {\n const existing = this.processors.get(processorCacheKey);\n if (existing != null) {\n return existing;\n }\n\n const processor = createLangfuseSpanProcessor(params, langfuse);\n this.processors.set(processorCacheKey, processor);\n return processor;\n }\n\n onStart(span: Span, parentContext: Context): void {\n const langfuse = resolveLangfuseConfigForSpan(parentContext);\n const params = getLangfuseSpanProcessorParams(langfuse);\n if (params == null) {\n return;\n }\n\n const destinationKey = getLangfuseDestinationKey(params);\n const processor = this.ensureProcessorForKey(\n getLangfuseProcessorCacheKey(destinationKey, langfuse),\n params,\n langfuse\n );\n registerLangfuseManagedSpan(span, destinationKey);\n\n const librechatTraceAttributes = createLibreChatTraceAttributes(\n langfuse?.librechatTraceAttributes ?? {}\n );\n if (Object.keys(librechatTraceAttributes).length > 0) {\n span.setAttributes(librechatTraceAttributes);\n }\n\n this.spanProcessors.set(span, processor);\n processor.onStart(span, parentContext);\n }\n\n onEnd(span: ReadableSpan): void {\n this.spanProcessors.get(span)?.onEnd(span);\n }\n\n async forceFlush(): Promise<void> {\n await Promise.all(\n Array.from(this.processors.values(), (processor) =>\n processor.forceFlush()\n )\n );\n }\n\n async shutdown(): Promise<void> {\n await Promise.all(\n Array.from(this.processors.values(), (processor) => processor.shutdown())\n );\n }\n}\n\nexport function initializeLangfuseTracing(\n langfuse?: t.LangfuseConfig\n): BasicTracerProvider | undefined {\n const params = getLangfuseSpanProcessorParams(langfuse);\n if (params == null) {\n return undefined;\n }\n\n if (langfuseTracerProvider != null) {\n langfuseRoutingSpanProcessor?.ensureProcessor(langfuse);\n return langfuseTracerProvider;\n }\n\n ensureOpenTelemetryContextManager();\n langfuseRoutingSpanProcessor = new RoutingLangfuseSpanProcessor();\n langfuseRoutingSpanProcessor.ensureProcessor(langfuse);\n langfuseTracerProvider = new BasicTracerProvider({\n spanProcessors: [langfuseRoutingSpanProcessor],\n idGenerator: new SeededTraceIdGenerator(),\n });\n\n setLangfuseTracerProvider(langfuseTracerProvider);\n return langfuseTracerProvider;\n}\n\nexport function initializeLangfuseTracingFromEnv():\n | BasicTracerProvider\n | undefined {\n return initializeLangfuseTracing();\n}\n\ninitializeLangfuseTracingFromEnv();\n"],"mappings":"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"}
@@ -43,7 +43,8 @@ function getLangfuseSpanProcessorParams(langfuse) {
43
43
  publicKey: langfuse.publicKey,
44
44
  secretKey: langfuse.secretKey,
45
45
  ...isPresent(langfuse.baseUrl) ? { baseUrl: langfuse.baseUrl } : {},
46
- ...isPresent(environment) ? { environment } : {}
46
+ ...isPresent(environment) ? { environment } : {},
47
+ ...langfuse.mediaUploadEnabled != null ? { mediaUploadEnabled: langfuse.mediaUploadEnabled } : {}
47
48
  };
48
49
  if (hasLangfuseEnvConfig()) {
49
50
  const baseUrl = langfuse?.baseUrl ?? process.env.LANGFUSE_BASE_URL ?? process.env.LANGFUSE_BASEURL;
@@ -51,14 +52,16 @@ function getLangfuseSpanProcessorParams(langfuse) {
51
52
  publicKey: process.env.LANGFUSE_PUBLIC_KEY,
52
53
  secretKey: process.env.LANGFUSE_SECRET_KEY,
53
54
  ...isPresent(baseUrl) ? { baseUrl } : {},
54
- ...isPresent(environment) ? { environment } : {}
55
+ ...isPresent(environment) ? { environment } : {},
56
+ ...langfuse?.mediaUploadEnabled != null ? { mediaUploadEnabled: langfuse.mediaUploadEnabled } : {}
55
57
  };
56
58
  }
57
59
  if (isPresent(langfuse?.baseUrl) && hasLangfuseEnvCredentials()) return {
58
60
  publicKey: process.env.LANGFUSE_PUBLIC_KEY,
59
61
  secretKey: process.env.LANGFUSE_SECRET_KEY,
60
62
  baseUrl: langfuse.baseUrl,
61
- ...isPresent(environment) ? { environment } : {}
63
+ ...isPresent(environment) ? { environment } : {},
64
+ ...langfuse.mediaUploadEnabled != null ? { mediaUploadEnabled: langfuse.mediaUploadEnabled } : {}
62
65
  };
63
66
  }
64
67
  function hashCacheKeyValue(value) {
@@ -1 +1 @@
1
- {"version":3,"file":"langfuseSpanRegistry.mjs","names":[],"sources":["../../src/langfuseSpanRegistry.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport type { LangfuseSpanProcessorParams } from '@langfuse/otel';\nimport type { Span } from '@opentelemetry/api';\nimport type * as t from '@/types';\nimport {\n hasLangfuseConfigCredentials,\n hasLangfuseEnvCredentials,\n hasLangfuseEnvConfig,\n} from '@/langfuseConfig';\nimport { isPresent } from '@/utils/misc';\n\n/**\n * Spans created through the Langfuse tracer provider, keyed by the export\n * destination they were routed to. Callback handlers use this to distinguish\n * safe ambient parents from spans a root observation must not inherit:\n *\n * - Foreign spans (a host's own OpenTelemetry instrumentation, e.g. HTTP\n * server spans on the global provider) are never exported to Langfuse —\n * inheriting one orphans the trace root (its root/trace input-output\n * shaping is skipped), collapses concurrent runs inside one request\n * context into a single merged trace, and bypasses the seeded\n * deterministic trace id generator.\n * - Langfuse-managed spans bound to a *different* destination (another\n * tenant's project) would leave the new trace dangling in its own\n * destination while inheriting the other tenant's trace id.\n *\n * Only a managed span whose destination matches the starting run's resolved\n * destination is a safe parent — that is the sanctioned way for hosts to\n * group runs under their own Langfuse observations.\n */\nconst managedSpanDestinations = new WeakMap<Span, string>();\n\nexport function registerLangfuseManagedSpan(\n span: Span,\n destinationKey: string\n): void {\n managedSpanDestinations.set(span, destinationKey);\n}\n\nexport function getLangfuseManagedSpanDestination(\n span: Span\n): string | undefined {\n return managedSpanDestinations.get(span);\n}\n\nfunction resolveLangfuseEnvironment(\n langfuse?: t.LangfuseConfig\n): string | undefined {\n const candidates = [\n langfuse?.environment,\n process.env.LANGFUSE_TRACING_ENVIRONMENT,\n process.env.NODE_ENV,\n ];\n for (const candidate of candidates) {\n if (candidate != null && candidate.trim() !== '') {\n return candidate.trim();\n }\n }\n return undefined;\n}\n\nexport function getLangfuseSpanProcessorParams(\n langfuse?: t.LangfuseConfig\n): LangfuseSpanProcessorParams | undefined {\n if (langfuse?.enabled === false) {\n return undefined;\n }\n const environment = resolveLangfuseEnvironment(langfuse);\n if (hasLangfuseConfigCredentials(langfuse)) {\n return {\n publicKey: langfuse.publicKey,\n secretKey: langfuse.secretKey,\n ...(isPresent(langfuse.baseUrl) ? { baseUrl: langfuse.baseUrl } : {}),\n ...(isPresent(environment) ? { environment } : {}),\n };\n }\n if (hasLangfuseEnvConfig()) {\n const baseUrl =\n langfuse?.baseUrl ??\n process.env.LANGFUSE_BASE_URL ??\n process.env.LANGFUSE_BASEURL;\n return {\n publicKey: process.env.LANGFUSE_PUBLIC_KEY as string,\n secretKey: process.env.LANGFUSE_SECRET_KEY as string,\n ...(isPresent(baseUrl) ? { baseUrl } : {}),\n ...(isPresent(environment) ? { environment } : {}),\n };\n }\n if (isPresent(langfuse?.baseUrl) && hasLangfuseEnvCredentials()) {\n return {\n publicKey: process.env.LANGFUSE_PUBLIC_KEY as string,\n secretKey: process.env.LANGFUSE_SECRET_KEY as string,\n baseUrl: langfuse.baseUrl,\n ...(isPresent(environment) ? { environment } : {}),\n };\n }\n return undefined;\n}\n\nfunction hashCacheKeyValue(value: string | undefined): string | undefined {\n return isPresent(value)\n ? createHash('sha256').update(value, 'utf8').digest('hex')\n : undefined;\n}\n\n/**\n * Identity of an export destination (project credentials + endpoint +\n * environment) only. Processor-level policies like `toolOutputTracing` are\n * deliberately excluded: two spans exporting to the same project under\n * different redaction settings still share a destination and may parent one\n * another.\n */\nexport function getLangfuseDestinationKey(\n params: LangfuseSpanProcessorParams\n): string {\n return JSON.stringify({\n publicKey: params.publicKey,\n secretKeyHash: hashCacheKeyValue(params.secretKey),\n baseUrl: params.baseUrl,\n environment: params.environment,\n });\n}\n\n/** The export destination a run with this config resolves to, or `undefined`\n * when no Langfuse destination is configured. */\nexport function resolveLangfuseDestinationKey(\n langfuse?: t.LangfuseConfig\n): string | undefined {\n const params = getLangfuseSpanProcessorParams(langfuse);\n return params == null ? undefined : getLangfuseDestinationKey(params);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA8BA,MAAM,0CAA0B,IAAI,QAAsB;AAE1D,SAAgB,4BACd,MACA,gBACM;CACN,wBAAwB,IAAI,MAAM,cAAc;AAClD;AAEA,SAAgB,kCACd,MACoB;CACpB,OAAO,wBAAwB,IAAI,IAAI;AACzC;AAEA,SAAS,2BACP,UACoB;CACpB,MAAM,aAAa;EACjB,UAAU;EACV,QAAQ,IAAI;EACZ,QAAQ,IAAI;CACd;CACA,KAAK,MAAM,aAAa,YACtB,IAAI,aAAa,QAAQ,UAAU,KAAK,MAAM,IAC5C,OAAO,UAAU,KAAK;AAI5B;AAEA,SAAgB,+BACd,UACyC;CACzC,IAAI,UAAU,YAAY,OACxB;CAEF,MAAM,cAAc,2BAA2B,QAAQ;CACvD,IAAI,6BAA6B,QAAQ,GACvC,OAAO;EACL,WAAW,SAAS;EACpB,WAAW,SAAS;EACpB,GAAI,UAAU,SAAS,OAAO,IAAI,EAAE,SAAS,SAAS,QAAQ,IAAI,CAAC;EACnE,GAAI,UAAU,WAAW,IAAI,EAAE,YAAY,IAAI,CAAC;CAClD;CAEF,IAAI,qBAAqB,GAAG;EAC1B,MAAM,UACJ,UAAU,WACV,QAAQ,IAAI,qBACZ,QAAQ,IAAI;EACd,OAAO;GACL,WAAW,QAAQ,IAAI;GACvB,WAAW,QAAQ,IAAI;GACvB,GAAI,UAAU,OAAO,IAAI,EAAE,QAAQ,IAAI,CAAC;GACxC,GAAI,UAAU,WAAW,IAAI,EAAE,YAAY,IAAI,CAAC;EAClD;CACF;CACA,IAAI,UAAU,UAAU,OAAO,KAAK,0BAA0B,GAC5D,OAAO;EACL,WAAW,QAAQ,IAAI;EACvB,WAAW,QAAQ,IAAI;EACvB,SAAS,SAAS;EAClB,GAAI,UAAU,WAAW,IAAI,EAAE,YAAY,IAAI,CAAC;CAClD;AAGJ;AAEA,SAAS,kBAAkB,OAA+C;CACxE,OAAO,UAAU,KAAK,IAClB,WAAW,QAAQ,CAAC,CAAC,OAAO,OAAO,MAAM,CAAC,CAAC,OAAO,KAAK,IACvD,KAAA;AACN;;;;;;;;AASA,SAAgB,0BACd,QACQ;CACR,OAAO,KAAK,UAAU;EACpB,WAAW,OAAO;EAClB,eAAe,kBAAkB,OAAO,SAAS;EACjD,SAAS,OAAO;EAChB,aAAa,OAAO;CACtB,CAAC;AACH;;;AAIA,SAAgB,8BACd,UACoB;CACpB,MAAM,SAAS,+BAA+B,QAAQ;CACtD,OAAO,UAAU,OAAO,KAAA,IAAY,0BAA0B,MAAM;AACtE"}
1
+ {"version":3,"file":"langfuseSpanRegistry.mjs","names":[],"sources":["../../src/langfuseSpanRegistry.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport type { LangfuseSpanProcessorParams } from '@langfuse/otel';\nimport type { Span } from '@opentelemetry/api';\nimport type * as t from '@/types';\nimport {\n hasLangfuseConfigCredentials,\n hasLangfuseEnvCredentials,\n hasLangfuseEnvConfig,\n} from '@/langfuseConfig';\nimport { isPresent } from '@/utils/misc';\n\n/**\n * Spans created through the Langfuse tracer provider, keyed by the export\n * destination they were routed to. Callback handlers use this to distinguish\n * safe ambient parents from spans a root observation must not inherit:\n *\n * - Foreign spans (a host's own OpenTelemetry instrumentation, e.g. HTTP\n * server spans on the global provider) are never exported to Langfuse —\n * inheriting one orphans the trace root (its root/trace input-output\n * shaping is skipped), collapses concurrent runs inside one request\n * context into a single merged trace, and bypasses the seeded\n * deterministic trace id generator.\n * - Langfuse-managed spans bound to a *different* destination (another\n * tenant's project) would leave the new trace dangling in its own\n * destination while inheriting the other tenant's trace id.\n *\n * Only a managed span whose destination matches the starting run's resolved\n * destination is a safe parent — that is the sanctioned way for hosts to\n * group runs under their own Langfuse observations.\n */\nconst managedSpanDestinations = new WeakMap<Span, string>();\n\nexport function registerLangfuseManagedSpan(\n span: Span,\n destinationKey: string\n): void {\n managedSpanDestinations.set(span, destinationKey);\n}\n\nexport function getLangfuseManagedSpanDestination(\n span: Span\n): string | undefined {\n return managedSpanDestinations.get(span);\n}\n\nfunction resolveLangfuseEnvironment(\n langfuse?: t.LangfuseConfig\n): string | undefined {\n const candidates = [\n langfuse?.environment,\n process.env.LANGFUSE_TRACING_ENVIRONMENT,\n process.env.NODE_ENV,\n ];\n for (const candidate of candidates) {\n if (candidate != null && candidate.trim() !== '') {\n return candidate.trim();\n }\n }\n return undefined;\n}\n\nexport function getLangfuseSpanProcessorParams(\n langfuse?: t.LangfuseConfig\n): LangfuseSpanProcessorParams | undefined {\n if (langfuse?.enabled === false) {\n return undefined;\n }\n const environment = resolveLangfuseEnvironment(langfuse);\n if (hasLangfuseConfigCredentials(langfuse)) {\n return {\n publicKey: langfuse.publicKey,\n secretKey: langfuse.secretKey,\n ...(isPresent(langfuse.baseUrl) ? { baseUrl: langfuse.baseUrl } : {}),\n ...(isPresent(environment) ? { environment } : {}),\n ...(langfuse.mediaUploadEnabled != null\n ? { mediaUploadEnabled: langfuse.mediaUploadEnabled }\n : {}),\n };\n }\n if (hasLangfuseEnvConfig()) {\n const baseUrl =\n langfuse?.baseUrl ??\n process.env.LANGFUSE_BASE_URL ??\n process.env.LANGFUSE_BASEURL;\n return {\n publicKey: process.env.LANGFUSE_PUBLIC_KEY as string,\n secretKey: process.env.LANGFUSE_SECRET_KEY as string,\n ...(isPresent(baseUrl) ? { baseUrl } : {}),\n ...(isPresent(environment) ? { environment } : {}),\n ...(langfuse?.mediaUploadEnabled != null\n ? { mediaUploadEnabled: langfuse.mediaUploadEnabled }\n : {}),\n };\n }\n if (isPresent(langfuse?.baseUrl) && hasLangfuseEnvCredentials()) {\n return {\n publicKey: process.env.LANGFUSE_PUBLIC_KEY as string,\n secretKey: process.env.LANGFUSE_SECRET_KEY as string,\n baseUrl: langfuse.baseUrl,\n ...(isPresent(environment) ? { environment } : {}),\n ...(langfuse.mediaUploadEnabled != null\n ? { mediaUploadEnabled: langfuse.mediaUploadEnabled }\n : {}),\n };\n }\n return undefined;\n}\n\nfunction hashCacheKeyValue(value: string | undefined): string | undefined {\n return isPresent(value)\n ? createHash('sha256').update(value, 'utf8').digest('hex')\n : undefined;\n}\n\n/**\n * Identity of an export destination (project credentials + endpoint +\n * environment) only. Processor-level policies like `toolOutputTracing` are\n * deliberately excluded: two spans exporting to the same project under\n * different redaction settings still share a destination and may parent one\n * another.\n */\nexport function getLangfuseDestinationKey(\n params: LangfuseSpanProcessorParams\n): string {\n return JSON.stringify({\n publicKey: params.publicKey,\n secretKeyHash: hashCacheKeyValue(params.secretKey),\n baseUrl: params.baseUrl,\n environment: params.environment,\n });\n}\n\n/** The export destination a run with this config resolves to, or `undefined`\n * when no Langfuse destination is configured. */\nexport function resolveLangfuseDestinationKey(\n langfuse?: t.LangfuseConfig\n): string | undefined {\n const params = getLangfuseSpanProcessorParams(langfuse);\n return params == null ? undefined : getLangfuseDestinationKey(params);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA8BA,MAAM,0CAA0B,IAAI,QAAsB;AAE1D,SAAgB,4BACd,MACA,gBACM;CACN,wBAAwB,IAAI,MAAM,cAAc;AAClD;AAEA,SAAgB,kCACd,MACoB;CACpB,OAAO,wBAAwB,IAAI,IAAI;AACzC;AAEA,SAAS,2BACP,UACoB;CACpB,MAAM,aAAa;EACjB,UAAU;EACV,QAAQ,IAAI;EACZ,QAAQ,IAAI;CACd;CACA,KAAK,MAAM,aAAa,YACtB,IAAI,aAAa,QAAQ,UAAU,KAAK,MAAM,IAC5C,OAAO,UAAU,KAAK;AAI5B;AAEA,SAAgB,+BACd,UACyC;CACzC,IAAI,UAAU,YAAY,OACxB;CAEF,MAAM,cAAc,2BAA2B,QAAQ;CACvD,IAAI,6BAA6B,QAAQ,GACvC,OAAO;EACL,WAAW,SAAS;EACpB,WAAW,SAAS;EACpB,GAAI,UAAU,SAAS,OAAO,IAAI,EAAE,SAAS,SAAS,QAAQ,IAAI,CAAC;EACnE,GAAI,UAAU,WAAW,IAAI,EAAE,YAAY,IAAI,CAAC;EAChD,GAAI,SAAS,sBAAsB,OAC/B,EAAE,oBAAoB,SAAS,mBAAmB,IAClD,CAAC;CACP;CAEF,IAAI,qBAAqB,GAAG;EAC1B,MAAM,UACJ,UAAU,WACV,QAAQ,IAAI,qBACZ,QAAQ,IAAI;EACd,OAAO;GACL,WAAW,QAAQ,IAAI;GACvB,WAAW,QAAQ,IAAI;GACvB,GAAI,UAAU,OAAO,IAAI,EAAE,QAAQ,IAAI,CAAC;GACxC,GAAI,UAAU,WAAW,IAAI,EAAE,YAAY,IAAI,CAAC;GAChD,GAAI,UAAU,sBAAsB,OAChC,EAAE,oBAAoB,SAAS,mBAAmB,IAClD,CAAC;EACP;CACF;CACA,IAAI,UAAU,UAAU,OAAO,KAAK,0BAA0B,GAC5D,OAAO;EACL,WAAW,QAAQ,IAAI;EACvB,WAAW,QAAQ,IAAI;EACvB,SAAS,SAAS;EAClB,GAAI,UAAU,WAAW,IAAI,EAAE,YAAY,IAAI,CAAC;EAChD,GAAI,SAAS,sBAAsB,OAC/B,EAAE,oBAAoB,SAAS,mBAAmB,IAClD,CAAC;CACP;AAGJ;AAEA,SAAS,kBAAkB,OAA+C;CACxE,OAAO,UAAU,KAAK,IAClB,WAAW,QAAQ,CAAC,CAAC,OAAO,OAAO,MAAM,CAAC,CAAC,OAAO,KAAK,IACvD,KAAA;AACN;;;;;;;;AASA,SAAgB,0BACd,QACQ;CACR,OAAO,KAAK,UAAU;EACpB,WAAW,OAAO;EAClB,eAAe,kBAAkB,OAAO,SAAS;EACjD,SAAS,OAAO;EAChB,aAAa,OAAO;CACtB,CAAC;AACH;;;AAIA,SAAgB,8BACd,UACoB;CACpB,MAAM,SAAS,+BAA+B,QAAQ;CACtD,OAAO,UAAU,OAAO,KAAA,IAAY,0BAA0B,MAAM;AACtE"}
@@ -1,4 +1,5 @@
1
1
  import { _convertMessagesToAnthropicPayload, stripUnsupportedAssistantPrefill } from "./utils/message_inputs.mjs";
2
+ import { isSignalAborted, resolveStreamDelay, smoothStream } from "../stream/smoother.mjs";
2
3
  import { _makeMessageChunkFromAnthropicEvent } from "./utils/message_outputs.mjs";
3
4
  import { convertAnthropicStream } from "./utils/stream_events.mjs";
4
5
  import { handleToolChoice } from "./utils/tools.mjs";
@@ -6,19 +7,6 @@ import { AIMessageChunk } from "@langchain/core/messages";
6
7
  import { ChatGenerationChunk } from "@langchain/core/outputs";
7
8
  import { ChatAnthropicMessages } from "@langchain/anthropic";
8
9
  //#region src/llm/anthropic/index.ts
9
- const DEFAULT_STREAM_DELAY = 25;
10
- const MAX_STREAM_QUEUE_CHUNKS = 256;
11
- const MAX_STREAM_QUEUE_TEXT_CHARS = 8192;
12
- const STREAM_CHUNK_MIN_SIZE = 4;
13
- const STREAM_BOUNDARIES = new Set([
14
- " ",
15
- ".",
16
- ",",
17
- "!",
18
- "?",
19
- ";",
20
- ":"
21
- ]);
22
10
  const ANTHROPIC_TOOL_BETAS = {
23
11
  tool_search_tool_regex_20251119: "advanced-tool-use-2025-11-20",
24
12
  tool_search_tool_bm25_20251119: "advanced-tool-use-2025-11-20",
@@ -102,45 +90,6 @@ function getSamplingParams({ model, thinking, topK, topP, temperature }) {
102
90
  ...isSetSamplingValue(topP) ? { top_p: topP } : {}
103
91
  };
104
92
  }
105
- function findStreamChunkBoundary(text, minSize) {
106
- if (minSize >= text.length) return text.length;
107
- for (let position = minSize; position < text.length; position++) if (STREAM_BOUNDARIES.has(text[position])) return position + 1;
108
- return text.length;
109
- }
110
- function splitStreamToken(text) {
111
- const chunks = [];
112
- let currentIndex = 0;
113
- while (currentIndex < text.length) {
114
- const chunkSize = findStreamChunkBoundary(text.slice(currentIndex), STREAM_CHUNK_MIN_SIZE);
115
- chunks.push(text.slice(currentIndex, currentIndex + chunkSize));
116
- currentIndex += chunkSize;
117
- }
118
- return chunks;
119
- }
120
- function getCadencedStreamDelay({ targetDelay, lastVisibleTextAt, now }) {
121
- if (targetDelay <= 0 || lastVisibleTextAt == null) return 0;
122
- return Math.max(0, targetDelay - (now - lastVisibleTextAt));
123
- }
124
- async function waitForStreamDelay(delay, signal) {
125
- if (delay <= 0 || isSignalAborted(signal)) return;
126
- await new Promise((resolve) => {
127
- const timeoutRef = {};
128
- const onAbort = () => {
129
- if (timeoutRef.current) clearTimeout(timeoutRef.current);
130
- signal?.removeEventListener("abort", onAbort);
131
- resolve();
132
- };
133
- timeoutRef.current = setTimeout(() => {
134
- signal?.removeEventListener("abort", onAbort);
135
- resolve();
136
- }, delay);
137
- signal?.addEventListener("abort", onAbort, { once: true });
138
- if (isSignalAborted(signal)) onAbort();
139
- });
140
- }
141
- function isSignalAborted(signal) {
142
- return signal?.aborted === true;
143
- }
144
93
  async function* abortableAnthropicStream(source, signal) {
145
94
  for await (const data of source) {
146
95
  if (isSignalAborted(signal)) {
@@ -225,7 +174,7 @@ var CustomAnthropic = class extends ChatAnthropicMessages {
225
174
  super(fields);
226
175
  this.resetTokenEvents();
227
176
  this.setDirectFields(fields);
228
- this._lc_stream_delay = Math.max(0, fields?._lc_stream_delay ?? DEFAULT_STREAM_DELAY);
177
+ this._lc_stream_delay = resolveStreamDelay(fields?._lc_stream_delay);
229
178
  this.outputConfig = fields?.outputConfig;
230
179
  this.inferenceGeo = fields?.inferenceGeo;
231
180
  this.contextManagement = fields?.contextManagement;
@@ -354,110 +303,17 @@ var CustomAnthropic = class extends ChatAnthropicMessages {
354
303
  cacheReadInputTokens: 0,
355
304
  outputTokens: 0
356
305
  };
357
- const queuedChunks = [];
358
- const producerState = { done: false };
359
- let queuedChunkIndex = 0;
360
- let bufferedTextLength = 0;
361
- let consumerClosed = false;
362
- let notifyConsumer;
363
- let notifyProducer;
364
- const notifyConsumerForChunk = () => {
365
- notifyConsumer?.();
366
- notifyConsumer = void 0;
367
- };
368
- const notifyProducerForSpace = () => {
369
- notifyProducer?.();
370
- notifyProducer = void 0;
371
- };
372
- const hasQueuedChunks = () => queuedChunkIndex < queuedChunks.length;
373
- const getQueuedChunkCount = () => queuedChunks.length - queuedChunkIndex;
374
- const isQueueAtCapacity = () => getQueuedChunkCount() >= MAX_STREAM_QUEUE_CHUNKS || bufferedTextLength >= MAX_STREAM_QUEUE_TEXT_CHARS;
375
- const waitForNextChunk = async () => {
376
- if (hasQueuedChunks() || producerState.done || producerState.error != null) return;
377
- await new Promise((resolve) => {
378
- notifyConsumer = resolve;
379
- });
380
- };
381
- const waitForQueueSpace = async () => {
382
- while (isQueueAtCapacity() && !consumerClosed && !isSignalAborted(options.signal)) await new Promise((resolve) => {
383
- const signal = options.signal;
384
- const onAbort = () => {
385
- signal?.removeEventListener("abort", onAbort);
386
- resolve();
387
- };
388
- const onSpace = () => {
389
- signal?.removeEventListener("abort", onAbort);
390
- resolve();
391
- };
392
- notifyProducer = onSpace;
393
- signal?.addEventListener("abort", onAbort, { once: true });
394
- if (isSignalAborted(signal)) onAbort();
395
- });
396
- };
397
- const dequeue = () => {
398
- if (!hasQueuedChunks()) return;
399
- const queuedChunk = queuedChunks[queuedChunkIndex];
400
- queuedChunkIndex++;
401
- if (queuedChunkIndex > 128 && queuedChunkIndex * 2 >= queuedChunks.length) {
402
- queuedChunks.splice(0, queuedChunkIndex);
403
- queuedChunkIndex = 0;
404
- }
405
- return queuedChunk;
406
- };
407
- const enqueue = async (queuedChunk) => {
408
- await waitForQueueSpace();
409
- if (consumerClosed || isSignalAborted(options.signal)) {
410
- stream.controller.abort();
411
- throw new Error("AbortError: User aborted the request.");
412
- }
413
- queuedChunks.push(queuedChunk);
414
- if (queuedChunk.smooth) bufferedTextLength += queuedChunk.textLength;
415
- notifyConsumerForChunk();
416
- };
417
- const enqueueChunk = async ({ token, chunk, smooth }) => {
418
- await enqueue({
419
- token,
420
- smooth,
421
- textLength: smooth ? token.length : 0,
422
- chunk: this.createGenerationChunk({
423
- token,
424
- chunk,
425
- shouldStreamUsage
426
- })
427
- });
428
- };
429
- const enqueueTextChunks = (token, tokenType, chunk) => {
430
- if (token === "") return Promise.resolve();
431
- if (this._lc_stream_delay <= 0) return enqueueChunk({
432
- token,
433
- chunk,
434
- smooth: false
435
- });
436
- const tokenChunks = splitStreamToken(token);
437
- if (tokenChunks.length <= 1) return enqueueChunk({
306
+ const toEmittedChunk = (token, chunk) => ({
307
+ token,
308
+ chunk: this.createGenerationChunk({
438
309
  token,
439
310
  chunk,
440
- smooth: true
441
- });
442
- let emittedUsage = false;
443
- return tokenChunks.reduce(async (previous, currentToken) => {
444
- await previous;
445
- const newChunk = cloneChunk(currentToken, tokenType, chunk);
446
- await enqueueChunk({
447
- token: currentToken,
448
- chunk: emittedUsage && newChunk.usage_metadata != null ? new AIMessageChunk(Object.assign({}, newChunk, { usage_metadata: void 0 })) : newChunk,
449
- smooth: true
450
- });
451
- if (newChunk.usage_metadata != null && !emittedUsage) emittedUsage = true;
452
- }, Promise.resolve());
453
- };
454
- const producer = (async () => {
455
- try {
311
+ shouldStreamUsage
312
+ })
313
+ });
314
+ const smoothed = smoothStream({
315
+ source: (async function* () {
456
316
  for await (const data of stream) {
457
- if (isSignalAborted(options.signal)) {
458
- stream.controller.abort();
459
- throw new Error("AbortError: User aborted the request.");
460
- }
461
317
  const result = _makeMessageChunkFromAnthropicEvent(data, {
462
318
  streamUsage: shouldStreamUsage,
463
319
  coerceContentToString
@@ -478,63 +334,36 @@ var CustomAnthropic = class extends ChatAnthropicMessages {
478
334
  }
479
335
  const [token = "", tokenType] = extractToken(chunk);
480
336
  if (!tokenType || tokenType === "input" || token === "" && (chunk.usage_metadata != null || chunk.id != null)) {
481
- await enqueueChunk({
482
- token,
483
- chunk,
484
- smooth: false
485
- });
337
+ yield {
338
+ text: "",
339
+ smooth: false,
340
+ emit: () => toEmittedChunk(token, chunk)
341
+ };
486
342
  continue;
487
343
  }
488
- await enqueueTextChunks(token, tokenType, chunk);
344
+ if (token === "") continue;
345
+ yield {
346
+ text: token,
347
+ smooth: true,
348
+ emit: (piece) => {
349
+ if (piece.isFirst && piece.isLast) return toEmittedChunk(token, chunk);
350
+ const cloned = cloneChunk(piece.text, tokenType, chunk);
351
+ const chunkForPiece = !piece.isFirst && cloned.usage_metadata != null ? new AIMessageChunk(Object.assign({}, cloned, { usage_metadata: void 0 })) : cloned;
352
+ return toEmittedChunk(piece.text, chunkForPiece);
353
+ }
354
+ };
489
355
  }
490
- } catch (error) {
491
- producerState.error = error;
492
- } finally {
493
- producerState.done = true;
494
- notifyConsumerForChunk();
495
- }
496
- })();
497
- let hasEmittedText = false;
498
- let lastVisibleTextAt;
499
- let keepStreaming = true;
356
+ })(),
357
+ delayMs: this._lc_stream_delay,
358
+ signal: options.signal,
359
+ abortUpstream: () => stream.controller.abort()
360
+ });
500
361
  try {
501
- while (keepStreaming) {
502
- if (isSignalAborted(options.signal)) {
503
- stream.controller.abort();
504
- throw new Error("AbortError: User aborted the request.");
505
- }
506
- await waitForNextChunk();
507
- const queuedChunk = dequeue();
508
- if (!queuedChunk) {
509
- if (producerState.error != null) throw producerState.error;
510
- if (producerState.done) keepStreaming = false;
511
- continue;
512
- }
513
- if (queuedChunk.smooth) {
514
- bufferedTextLength = Math.max(0, bufferedTextLength - queuedChunk.textLength);
515
- notifyProducerForSpace();
516
- await waitForStreamDelay(getCadencedStreamDelay({
517
- targetDelay: hasEmittedText ? this._lc_stream_delay : 0,
518
- lastVisibleTextAt,
519
- now: Date.now()
520
- }), options.signal);
521
- if (isSignalAborted(options.signal)) {
522
- stream.controller.abort();
523
- throw new Error("AbortError: User aborted the request.");
524
- }
525
- hasEmittedText = true;
526
- lastVisibleTextAt = Date.now();
527
- } else notifyProducerForSpace();
528
- yield queuedChunk.chunk;
529
- await runManager?.handleLLMNewToken(queuedChunk.token, void 0, void 0, void 0, void 0, { chunk: queuedChunk.chunk });
362
+ for await (const emitted of smoothed) {
363
+ yield emitted.chunk;
364
+ await runManager?.handleLLMNewToken(emitted.token, void 0, void 0, void 0, void 0, { chunk: emitted.chunk });
530
365
  }
531
366
  } finally {
532
- consumerClosed = true;
533
- if (!producerState.done) {
534
- stream.controller.abort();
535
- notifyProducerForSpace();
536
- }
537
- await producer;
538
367
  this.resetTokenEvents();
539
368
  }
540
369
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/llm/anthropic/index.ts"],"sourcesContent":["import { AIMessageChunk } from '@langchain/core/messages';\nimport { ChatAnthropicMessages } from '@langchain/anthropic';\nimport { ChatGenerationChunk } from '@langchain/core/outputs';\nimport type { BaseChatModelParams } from '@langchain/core/language_models/chat_models';\nimport type {\n BaseMessage,\n MessageContentComplex,\n} from '@langchain/core/messages';\nimport type { ChatModelStreamEvent } from '@langchain/core/language_models/event';\nimport type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';\nimport type { AnthropicInput } from '@langchain/anthropic';\nimport type { Anthropic } from '@anthropic-ai/sdk';\nimport type {\n AnthropicMessageCreateParams,\n AnthropicStreamingMessageCreateParams,\n AnthropicOutputConfig,\n AnthropicBeta,\n ChatAnthropicToolType,\n AnthropicMCPServerURLDefinition,\n AnthropicContextManagementConfigParam,\n AnthropicRequestOptions,\n AnthropicMessageStreamEvent,\n} from '@/llm/anthropic/types';\nimport type { AnthropicUsageData } from './utils/message_outputs';\nimport {\n _convertMessagesToAnthropicPayload,\n stripUnsupportedAssistantPrefill,\n} from './utils/message_inputs';\nimport { _makeMessageChunkFromAnthropicEvent } from './utils/message_outputs';\nimport { convertAnthropicStream } from './utils/stream_events';\nimport { handleToolChoice } from './utils/tools';\n\nconst DEFAULT_STREAM_DELAY = 25;\nconst MAX_STREAM_QUEUE_CHUNKS = 256;\nconst MAX_STREAM_QUEUE_TEXT_CHARS = 8192;\nconst STREAM_CHUNK_MIN_SIZE = 4;\nconst STREAM_BOUNDARIES = new Set([' ', '.', ',', '!', '?', ';', ':']);\n\ntype StreamTokenType = 'string' | 'input' | 'content';\n\ninterface AnthropicStreamUsage {\n inputTokens: number;\n cacheCreationInputTokens: number;\n cacheReadInputTokens: number;\n outputTokens: number;\n}\n\ninterface CumulativeUsageValue {\n cumulative: number;\n increment: number;\n}\n\ninterface AnthropicEventStream\n extends AsyncIterable<AnthropicMessageStreamEvent> {\n controller?: { abort: () => void };\n}\n\nconst ANTHROPIC_TOOL_BETAS: Partial<Record<string, AnthropicBeta>> = {\n tool_search_tool_regex_20251119: 'advanced-tool-use-2025-11-20',\n tool_search_tool_bm25_20251119: 'advanced-tool-use-2025-11-20',\n memory_20250818: 'context-management-2025-06-27',\n web_fetch_20250910: 'web-fetch-2025-09-10',\n code_execution_20250825: 'code-execution-2025-08-25',\n computer_20251124: 'computer-use-2025-11-24',\n computer_20250124: 'computer-use-2025-01-24',\n mcp_toolset: 'mcp-client-2025-11-20',\n};\n\nfunction _toolsInParams(\n params: AnthropicMessageCreateParams | AnthropicStreamingMessageCreateParams\n): boolean {\n return !!(params.tools && params.tools.length > 0);\n}\nexport function _documentsInParams(\n params: AnthropicMessageCreateParams | AnthropicStreamingMessageCreateParams\n): boolean {\n for (const message of params.messages) {\n if (typeof message.content === 'string') {\n continue;\n }\n for (const block of message.content) {\n const maybeBlock: unknown = block;\n if (\n typeof maybeBlock === 'object' &&\n maybeBlock !== null &&\n 'type' in maybeBlock &&\n maybeBlock.type === 'document' &&\n 'citations' in maybeBlock &&\n maybeBlock.citations != null &&\n typeof maybeBlock.citations === 'object' &&\n 'enabled' in maybeBlock.citations &&\n maybeBlock.citations.enabled === true\n ) {\n return true;\n }\n }\n }\n return false;\n}\n\nfunction _thinkingInParams(\n params: AnthropicMessageCreateParams | AnthropicStreamingMessageCreateParams\n): boolean {\n return !!(\n params.thinking &&\n (params.thinking.type === 'enabled' || params.thinking.type === 'adaptive')\n );\n}\n\nfunction _compactionInParams(\n params: (\n | AnthropicMessageCreateParams\n | AnthropicStreamingMessageCreateParams\n ) & {\n context_management?: AnthropicContextManagementConfigParam;\n }\n): boolean {\n return (\n params.context_management?.edits?.some(\n (edit) => edit.type === 'compact_20260112'\n ) === true\n );\n}\n\nfunction isThinkingEnabled(thinking: Anthropic.ThinkingConfigParam): boolean {\n return thinking.type === 'enabled' || thinking.type === 'adaptive';\n}\n\nfunction isOpus47Model(model?: string): boolean {\n return /^claude-opus-4-7(?:-|$)/.test(model ?? '');\n}\n\nfunction combineBetas(\n ...betaGroups: (AnthropicBeta[] | undefined)[]\n): AnthropicBeta[] {\n const betas = new Set<AnthropicBeta>();\n for (const betaGroup of betaGroups) {\n for (const beta of betaGroup ?? []) {\n betas.add(beta);\n }\n }\n return [...betas];\n}\n\nfunction getToolBetas(tools?: ChatAnthropicToolType[]): AnthropicBeta[] {\n const betas = new Set<AnthropicBeta>();\n for (const tool of tools ?? []) {\n if (typeof tool !== 'object' || !('type' in tool)) {\n continue;\n }\n const beta = ANTHROPIC_TOOL_BETAS[String(tool.type)];\n if (beta != null) {\n betas.add(beta);\n }\n }\n return [...betas];\n}\n\nfunction getCompactionBetas(\n contextManagement?: AnthropicContextManagementConfigParam\n): AnthropicBeta[] {\n return contextManagement?.edits?.some(\n (edit) => edit.type === 'compact_20260112'\n ) === true\n ? ['compact-2026-01-12']\n : [];\n}\n\nfunction getTaskBudgetBetas(\n model: string,\n outputConfig?: AnthropicOutputConfig\n): AnthropicBeta[] {\n return isOpus47Model(model) &&\n outputConfig != null &&\n 'task_budget' in outputConfig &&\n outputConfig.task_budget != null\n ? ['task-budgets-2026-03-13']\n : [];\n}\n\nfunction isSetSamplingValue(value?: number | null): value is number {\n return value != null && value !== -1;\n}\n\nfunction isNonDefaultTemperature(value?: number): boolean {\n return isSetSamplingValue(value) && value !== 1;\n}\n\nfunction validateInvocationParamCompatibility({\n model,\n thinking,\n topK,\n topP,\n temperature,\n}: {\n model: string;\n thinking: Anthropic.ThinkingConfigParam;\n topK?: number;\n topP?: number | null;\n temperature?: number;\n}): void {\n const opus47 = isOpus47Model(model);\n if (opus47 && thinking.type === 'enabled') {\n throw new Error(\n 'thinking.type=\"enabled\" is not supported for claude-opus-4-7; use thinking.type=\"adaptive\" instead'\n );\n }\n if (opus47 && 'budget_tokens' in thinking) {\n throw new Error(\n 'thinking.budget_tokens is not supported for claude-opus-4-7; use outputConfig.effort instead'\n );\n }\n if (opus47) {\n if (isSetSamplingValue(topK)) {\n throw new Error(\n 'topK is not supported for claude-opus-4-7; omit topK/topP/temperature or use model prompting instead'\n );\n }\n if (isSetSamplingValue(topP) && topP !== 1) {\n throw new Error(\n 'topP is not supported for claude-opus-4-7 when set to non-default values'\n );\n }\n if (isNonDefaultTemperature(temperature)) {\n throw new Error(\n 'temperature is not supported for claude-opus-4-7 when set to non-default values'\n );\n }\n }\n if (!isThinkingEnabled(thinking)) {\n return;\n }\n if (isSetSamplingValue(topK)) {\n throw new Error('topK is not supported when thinking is enabled');\n }\n if (isSetSamplingValue(topP)) {\n throw new Error('topP is not supported when thinking is enabled');\n }\n if (isNonDefaultTemperature(temperature)) {\n throw new Error('temperature is not supported when thinking is enabled');\n }\n}\n\nfunction getSamplingParams({\n model,\n thinking,\n topK,\n topP,\n temperature,\n}: {\n model: string;\n thinking: Anthropic.ThinkingConfigParam;\n topK?: number;\n topP?: number | null;\n temperature?: number;\n}): {\n temperature?: number;\n top_k?: number;\n top_p?: number;\n} {\n if (isThinkingEnabled(thinking) || isOpus47Model(model)) {\n return {};\n }\n return {\n ...(isSetSamplingValue(temperature) ? { temperature } : {}),\n ...(isSetSamplingValue(topK) ? { top_k: topK } : {}),\n ...(isSetSamplingValue(topP) ? { top_p: topP } : {}),\n };\n}\n\nfunction findStreamChunkBoundary(text: string, minSize: number): number {\n if (minSize >= text.length) {\n return text.length;\n }\n\n for (let position = minSize; position < text.length; position++) {\n if (STREAM_BOUNDARIES.has(text[position])) {\n return position + 1;\n }\n }\n\n return text.length;\n}\n\nfunction splitStreamToken(text: string): string[] {\n const chunks: string[] = [];\n let currentIndex = 0;\n\n while (currentIndex < text.length) {\n const remainingText = text.slice(currentIndex);\n const chunkSize = findStreamChunkBoundary(\n remainingText,\n STREAM_CHUNK_MIN_SIZE\n );\n chunks.push(text.slice(currentIndex, currentIndex + chunkSize));\n currentIndex += chunkSize;\n }\n\n return chunks;\n}\n\nfunction getCadencedStreamDelay({\n targetDelay,\n lastVisibleTextAt,\n now,\n}: {\n targetDelay: number;\n lastVisibleTextAt?: number;\n now: number;\n}): number {\n if (targetDelay <= 0 || lastVisibleTextAt == null) {\n return 0;\n }\n return Math.max(0, targetDelay - (now - lastVisibleTextAt));\n}\n\nasync function waitForStreamDelay(\n delay: number,\n signal?: AbortSignal\n): Promise<void> {\n if (delay <= 0 || isSignalAborted(signal)) {\n return;\n }\n await new Promise<void>((resolve) => {\n const timeoutRef: { current?: ReturnType<typeof setTimeout> } = {};\n const onAbort = (): void => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n signal?.removeEventListener('abort', onAbort);\n resolve();\n };\n timeoutRef.current = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort);\n resolve();\n }, delay);\n signal?.addEventListener('abort', onAbort, { once: true });\n if (isSignalAborted(signal)) {\n onAbort();\n }\n });\n}\n\nfunction isSignalAborted(signal?: AbortSignal): boolean {\n return signal?.aborted === true;\n}\n\nasync function* abortableAnthropicStream(\n source: AnthropicEventStream,\n signal?: AbortSignal\n): AsyncGenerator<AnthropicMessageStreamEvent> {\n for await (const data of source) {\n if (isSignalAborted(signal)) {\n source.controller?.abort();\n return;\n }\n yield data;\n }\n}\n\nfunction extractToken(\n chunk: AIMessageChunk\n): [string, StreamTokenType] | [undefined] {\n if (typeof chunk.content === 'string') {\n return [chunk.content, 'string'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'input' in chunk.content[0]\n ) {\n return typeof chunk.content[0].input === 'string'\n ? [chunk.content[0].input, 'input']\n : [JSON.stringify(chunk.content[0].input), 'input'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'text' in chunk.content[0]\n ) {\n const text = chunk.content[0].text;\n return typeof text === 'string' ? [text, 'content'] : [undefined];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'thinking' in chunk.content[0]\n ) {\n const thinking = chunk.content[0].thinking;\n return typeof thinking === 'string' ? [thinking, 'content'] : [undefined];\n }\n return [undefined];\n}\n\nfunction cloneChunk(\n text: string,\n tokenType: StreamTokenType,\n chunk: AIMessageChunk\n): AIMessageChunk {\n if (tokenType === 'string') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: text }));\n } else if (tokenType === 'input') {\n return chunk;\n }\n const content = chunk.content[0] as MessageContentComplex;\n if (content.type === 'text') {\n return new AIMessageChunk(\n Object.assign({}, chunk, {\n content: [Object.assign({}, content, { text })],\n })\n );\n } else if (content.type === 'text_delta') {\n return new AIMessageChunk(\n Object.assign({}, chunk, {\n content: [Object.assign({}, content, { text })],\n })\n );\n } else if (\n typeof content.type === 'string' &&\n content.type.startsWith('thinking')\n ) {\n return new AIMessageChunk(\n Object.assign({}, chunk, {\n content: [Object.assign({}, content, { thinking: text })],\n })\n );\n }\n\n return chunk;\n}\n\nfunction resolveCumulativeUsageValue(\n current: number | null | undefined,\n previous: number\n): CumulativeUsageValue {\n if (current == null) {\n return { cumulative: previous, increment: 0 };\n }\n const cumulative = Math.max(previous, current);\n return { cumulative, increment: cumulative - previous };\n}\n\nfunction withIncrementalMessageDeltaUsage(\n chunk: AIMessageChunk,\n previousUsage: AnthropicStreamUsage,\n cumulativeUsage: AnthropicUsageData\n): { chunk: AIMessageChunk; usage: AnthropicStreamUsage } {\n const usage = chunk.usage_metadata;\n if (usage == null) {\n return { chunk, usage: previousUsage };\n }\n\n const inputTokens = resolveCumulativeUsageValue(\n cumulativeUsage.input_tokens,\n previousUsage.inputTokens\n );\n const cacheCreationInputTokens = resolveCumulativeUsageValue(\n cumulativeUsage.cache_creation_input_tokens,\n previousUsage.cacheCreationInputTokens\n );\n const cacheReadInputTokens = resolveCumulativeUsageValue(\n cumulativeUsage.cache_read_input_tokens,\n previousUsage.cacheReadInputTokens\n );\n const outputTokens = resolveCumulativeUsageValue(\n cumulativeUsage.output_tokens,\n previousUsage.outputTokens\n );\n const incrementalInputTokens =\n inputTokens.increment +\n cacheCreationInputTokens.increment +\n cacheReadInputTokens.increment;\n const hasCacheUsage =\n cumulativeUsage.cache_creation_input_tokens != null ||\n cumulativeUsage.cache_read_input_tokens != null;\n const inputTokenDetails = {\n ...(cumulativeUsage.cache_creation_input_tokens != null && {\n cache_creation: cacheCreationInputTokens.increment,\n }),\n ...(cumulativeUsage.cache_read_input_tokens != null && {\n cache_read: cacheReadInputTokens.increment,\n }),\n };\n\n return {\n chunk: new AIMessageChunk(\n Object.assign({}, chunk, {\n usage_metadata: {\n ...usage,\n input_tokens: incrementalInputTokens,\n output_tokens: outputTokens.increment,\n total_tokens: incrementalInputTokens + outputTokens.increment,\n input_token_details: hasCacheUsage ? inputTokenDetails : undefined,\n },\n })\n ),\n usage: {\n inputTokens: inputTokens.cumulative,\n cacheCreationInputTokens: cacheCreationInputTokens.cumulative,\n cacheReadInputTokens: cacheReadInputTokens.cumulative,\n outputTokens: outputTokens.cumulative,\n },\n };\n}\n\nexport type CustomAnthropicInput = AnthropicInput & {\n _lc_stream_delay?: number;\n outputConfig?: AnthropicOutputConfig;\n inferenceGeo?: string;\n contextManagement?: AnthropicContextManagementConfigParam;\n} & BaseChatModelParams;\n\nexport type CustomAnthropicCallOptions = {\n outputConfig?: AnthropicOutputConfig;\n outputFormat?: Anthropic.Messages.JSONOutputFormat;\n inferenceGeo?: string;\n betas?: AnthropicBeta[];\n container?: string;\n mcp_servers?: AnthropicMCPServerURLDefinition[];\n};\n\ntype CustomAnthropicInvocationParams = {\n betas?: AnthropicBeta[];\n container?: string;\n context_management?: AnthropicContextManagementConfigParam;\n inference_geo?: string;\n mcp_servers?: AnthropicMCPServerURLDefinition[];\n output_config?: AnthropicOutputConfig;\n};\n\ntype QueuedGenerationChunk = {\n chunk: ChatGenerationChunk;\n token: string;\n smooth: boolean;\n textLength: number;\n};\n\nexport class CustomAnthropic extends ChatAnthropicMessages {\n _lc_stream_delay: number;\n private tools_in_params?: boolean;\n top_k: number | undefined;\n outputConfig?: AnthropicOutputConfig;\n inferenceGeo?: string;\n contextManagement?: AnthropicContextManagementConfigParam;\n constructor(fields?: CustomAnthropicInput) {\n super(fields);\n this.resetTokenEvents();\n this.setDirectFields(fields);\n this._lc_stream_delay = Math.max(\n 0,\n fields?._lc_stream_delay ?? DEFAULT_STREAM_DELAY\n );\n this.outputConfig = fields?.outputConfig;\n this.inferenceGeo = fields?.inferenceGeo;\n this.contextManagement = fields?.contextManagement;\n }\n\n static lc_name(): 'LibreChatAnthropic' {\n return 'LibreChatAnthropic';\n }\n\n /**\n * Get the parameters used to invoke the model\n */\n override invocationParams(\n options?: this['ParsedCallOptions'] & CustomAnthropicCallOptions\n ): Omit<\n AnthropicMessageCreateParams | AnthropicStreamingMessageCreateParams,\n 'messages'\n > &\n CustomAnthropicInvocationParams {\n const tool_choice:\n | Anthropic.Messages.ToolChoiceAuto\n | Anthropic.Messages.ToolChoiceAny\n | Anthropic.Messages.ToolChoiceTool\n | Anthropic.Messages.ToolChoiceNone\n | undefined = handleToolChoice(options?.tool_choice);\n\n const callOptions = options as CustomAnthropicCallOptions | undefined;\n const mergedOutputConfig: AnthropicOutputConfig | undefined = (():\n | AnthropicOutputConfig\n | undefined => {\n const base = {\n ...this.outputConfig,\n ...callOptions?.outputConfig,\n };\n if (callOptions?.outputFormat && !base.format) {\n base.format = callOptions.outputFormat;\n }\n return Object.keys(base).length > 0 ? base : undefined;\n })();\n\n const inferenceGeo = callOptions?.inferenceGeo ?? this.inferenceGeo;\n\n const contextManagement = this.contextManagement;\n const toolBetas = getToolBetas(options?.tools);\n const compactionBetas = getCompactionBetas(contextManagement);\n const taskBudgetBetas = getTaskBudgetBetas(this.model, mergedOutputConfig);\n const formattedTools = this.formatStructuredToolToAnthropic(\n options?.tools,\n {\n strict: options?.strict,\n }\n );\n\n const sharedParams = {\n tools: formattedTools,\n tool_choice,\n // Match upstream: omit `thinking` unless the user set it, so we don't send\n // `{ type: 'disabled' }` (an unsupported param on some models) by default.\n thinking: this.thinkingExplicitlySet ? this.thinking : undefined,\n context_management: contextManagement,\n ...this.invocationKwargs,\n container: callOptions?.container,\n betas: combineBetas(\n this.betas,\n callOptions?.betas,\n toolBetas,\n compactionBetas,\n taskBudgetBetas\n ),\n output_config: mergedOutputConfig,\n inference_geo: inferenceGeo,\n mcp_servers: callOptions?.mcp_servers,\n // Top-level request cache_control (1.5.x): API auto-advances the cache\n // breakpoint across turns. Additive — independent of our block-level cache.\n cache_control: options?.cache_control,\n };\n validateInvocationParamCompatibility({\n model: this.model,\n thinking: this.thinking,\n topK: this.top_k,\n topP: this.topP,\n temperature: this.temperature,\n });\n\n return {\n model: this.model,\n stop_sequences: options?.stop ?? this.stopSequences,\n stream: this.streaming,\n max_tokens: this.maxTokens,\n ...getSamplingParams({\n model: this.model,\n thinking: this.thinking,\n topK: this.top_k,\n topP: this.topP,\n temperature: this.temperature,\n }),\n ...sharedParams,\n };\n }\n\n resetTokenEvents(): void {\n this.tools_in_params = undefined;\n }\n\n setDirectFields(fields?: CustomAnthropicInput): void {\n this.temperature = fields?.temperature ?? undefined;\n this.topP = fields?.topP ?? undefined;\n this.top_k = fields?.topK;\n if (this.temperature === -1 || this.temperature === 1) {\n this.temperature = undefined;\n }\n if (this.topP === -1) {\n this.topP = undefined;\n }\n if (this.top_k === -1) {\n this.top_k = undefined;\n }\n }\n\n private createGenerationChunk({\n token,\n chunk,\n shouldStreamUsage,\n }: {\n token?: string;\n chunk: AIMessageChunk;\n shouldStreamUsage: boolean;\n }): ChatGenerationChunk {\n const usage_metadata = shouldStreamUsage ? chunk.usage_metadata : undefined;\n return new ChatGenerationChunk({\n message: new AIMessageChunk({\n // Just yield chunk as it is and tool_use will be concat by BaseChatModel._generateUncached().\n content: chunk.content,\n additional_kwargs: chunk.additional_kwargs,\n tool_call_chunks: chunk.tool_call_chunks,\n response_metadata: chunk.response_metadata,\n usage_metadata,\n id: chunk.id,\n }),\n text: token ?? '',\n });\n }\n\n protected override async createStreamWithRetry(\n request: AnthropicStreamingMessageCreateParams,\n options?: AnthropicRequestOptions\n ): ReturnType<ChatAnthropicMessages['createStreamWithRetry']> {\n return super.createStreamWithRetry(\n stripUnsupportedAssistantPrefill(request),\n options\n );\n }\n\n protected override async completionWithRetry(\n request: AnthropicMessageCreateParams,\n options: AnthropicRequestOptions\n ): ReturnType<ChatAnthropicMessages['completionWithRetry']> {\n return super.completionWithRetry(\n stripUnsupportedAssistantPrefill(request),\n options\n );\n }\n\n async *_streamChatModelEvents(\n messages: BaseMessage[],\n options: this['ParsedCallOptions'],\n _runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatModelStreamEvent> {\n const params = this.invocationParams(options);\n const formattedMessages = _convertMessagesToAnthropicPayload(messages);\n const payload = stripUnsupportedAssistantPrefill({\n ...params,\n ...formattedMessages,\n stream: true,\n } as const);\n const stream = await this.createStreamWithRetry(payload, {\n headers: options.headers,\n signal: options.signal,\n });\n const shouldStreamUsage = options.streamUsage ?? this.streamUsage;\n yield* convertAnthropicStream(\n abortableAnthropicStream(stream, options.signal),\n { streamUsage: shouldStreamUsage }\n );\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this['ParsedCallOptions'],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n this.resetTokenEvents();\n const params = this.invocationParams(options);\n const formattedMessages = _convertMessagesToAnthropicPayload(messages);\n const payload = stripUnsupportedAssistantPrefill({\n ...params,\n ...formattedMessages,\n stream: true,\n } as const);\n const coerceContentToString =\n !_toolsInParams(payload) &&\n !_documentsInParams(payload) &&\n !_thinkingInParams(payload) &&\n !_compactionInParams(payload);\n\n const stream = await this.createStreamWithRetry(payload, {\n headers: options.headers,\n signal: options.signal,\n });\n\n const shouldStreamUsage = options.streamUsage ?? this.streamUsage;\n let streamUsage: AnthropicStreamUsage = {\n inputTokens: 0,\n cacheCreationInputTokens: 0,\n cacheReadInputTokens: 0,\n outputTokens: 0,\n };\n const queuedChunks: QueuedGenerationChunk[] = [];\n const producerState: {\n done: boolean;\n error?: unknown;\n } = { done: false };\n let queuedChunkIndex = 0;\n let bufferedTextLength = 0;\n let consumerClosed = false;\n let notifyConsumer: (() => void) | undefined;\n let notifyProducer: (() => void) | undefined;\n\n const notifyConsumerForChunk = (): void => {\n notifyConsumer?.();\n notifyConsumer = undefined;\n };\n\n const notifyProducerForSpace = (): void => {\n notifyProducer?.();\n notifyProducer = undefined;\n };\n\n const hasQueuedChunks = (): boolean =>\n queuedChunkIndex < queuedChunks.length;\n\n const getQueuedChunkCount = (): number =>\n queuedChunks.length - queuedChunkIndex;\n\n const isQueueAtCapacity = (): boolean =>\n getQueuedChunkCount() >= MAX_STREAM_QUEUE_CHUNKS ||\n bufferedTextLength >= MAX_STREAM_QUEUE_TEXT_CHARS;\n\n const waitForNextChunk = async (): Promise<void> => {\n if (\n hasQueuedChunks() ||\n producerState.done ||\n producerState.error != null\n ) {\n return;\n }\n await new Promise<void>((resolve) => {\n notifyConsumer = resolve;\n });\n };\n\n const waitForQueueSpace = async (): Promise<void> => {\n while (\n isQueueAtCapacity() &&\n !consumerClosed &&\n !isSignalAborted(options.signal)\n ) {\n await new Promise<void>((resolve) => {\n const signal = options.signal;\n const onAbort = (): void => {\n signal?.removeEventListener('abort', onAbort);\n resolve();\n };\n const onSpace = (): void => {\n signal?.removeEventListener('abort', onAbort);\n resolve();\n };\n notifyProducer = onSpace;\n signal?.addEventListener('abort', onAbort, { once: true });\n if (isSignalAborted(signal)) {\n onAbort();\n }\n });\n }\n };\n\n const dequeue = (): QueuedGenerationChunk | undefined => {\n if (!hasQueuedChunks()) {\n return undefined;\n }\n const queuedChunk = queuedChunks[queuedChunkIndex];\n queuedChunkIndex++;\n if (\n queuedChunkIndex > 128 &&\n queuedChunkIndex * 2 >= queuedChunks.length\n ) {\n queuedChunks.splice(0, queuedChunkIndex);\n queuedChunkIndex = 0;\n }\n return queuedChunk;\n };\n\n const enqueue = async (\n queuedChunk: QueuedGenerationChunk\n ): Promise<void> => {\n await waitForQueueSpace();\n if (consumerClosed || isSignalAborted(options.signal)) {\n stream.controller.abort();\n throw new Error('AbortError: User aborted the request.');\n }\n queuedChunks.push(queuedChunk);\n if (queuedChunk.smooth) {\n bufferedTextLength += queuedChunk.textLength;\n }\n notifyConsumerForChunk();\n };\n\n const enqueueChunk = async ({\n token,\n chunk,\n smooth,\n }: {\n token: string;\n chunk: AIMessageChunk;\n smooth: boolean;\n }): Promise<void> => {\n await enqueue({\n token,\n smooth,\n textLength: smooth ? token.length : 0,\n chunk: this.createGenerationChunk({\n token,\n chunk,\n shouldStreamUsage,\n }),\n });\n };\n\n const enqueueTextChunks = (\n token: string,\n tokenType: StreamTokenType,\n chunk: AIMessageChunk\n ): Promise<void> => {\n if (token === '') {\n return Promise.resolve();\n }\n if (this._lc_stream_delay <= 0) {\n return enqueueChunk({ token, chunk, smooth: false });\n }\n\n const tokenChunks = splitStreamToken(token);\n if (tokenChunks.length <= 1) {\n return enqueueChunk({ token, chunk, smooth: true });\n }\n\n let emittedUsage = false;\n return tokenChunks.reduce(async (previous, currentToken) => {\n await previous;\n const newChunk = cloneChunk(currentToken, tokenType, chunk);\n const chunkForToken =\n emittedUsage && newChunk.usage_metadata != null\n ? new AIMessageChunk(\n Object.assign({}, newChunk, { usage_metadata: undefined })\n )\n : newChunk;\n\n await enqueueChunk({\n token: currentToken,\n chunk: chunkForToken,\n smooth: true,\n });\n\n if (newChunk.usage_metadata != null && !emittedUsage) {\n emittedUsage = true;\n }\n }, Promise.resolve());\n };\n\n const producer = (async (): Promise<void> => {\n try {\n for await (const data of stream) {\n if (isSignalAborted(options.signal)) {\n stream.controller.abort();\n throw new Error('AbortError: User aborted the request.');\n }\n\n const result = _makeMessageChunkFromAnthropicEvent(\n data as Anthropic.Beta.Messages.BetaRawMessageStreamEvent,\n {\n streamUsage: shouldStreamUsage,\n coerceContentToString,\n }\n );\n if (!result) {\n continue;\n }\n\n let { chunk } = result;\n if (data.type === 'message_start') {\n streamUsage = {\n ...streamUsage,\n inputTokens: data.message.usage.input_tokens,\n outputTokens: data.message.usage.output_tokens,\n cacheCreationInputTokens:\n data.message.usage.cache_creation_input_tokens ?? 0,\n cacheReadInputTokens:\n data.message.usage.cache_read_input_tokens ?? 0,\n };\n }\n if (data.type === 'message_delta') {\n const incremental = withIncrementalMessageDeltaUsage(\n chunk,\n streamUsage,\n data.usage\n );\n chunk = incremental.chunk;\n streamUsage = incremental.usage;\n }\n\n const [token = '', tokenType] = extractToken(chunk);\n if (\n !tokenType ||\n tokenType === 'input' ||\n (token === '' && (chunk.usage_metadata != null || chunk.id != null))\n ) {\n await enqueueChunk({ token, chunk, smooth: false });\n continue;\n }\n\n await enqueueTextChunks(token, tokenType, chunk);\n }\n } catch (error) {\n producerState.error = error;\n } finally {\n producerState.done = true;\n notifyConsumerForChunk();\n }\n })();\n\n let hasEmittedText = false;\n let lastVisibleTextAt: number | undefined;\n let keepStreaming = true;\n try {\n while (keepStreaming) {\n if (isSignalAborted(options.signal)) {\n stream.controller.abort();\n throw new Error('AbortError: User aborted the request.');\n }\n\n await waitForNextChunk();\n const queuedChunk = dequeue();\n\n if (!queuedChunk) {\n if (producerState.error != null) {\n throw producerState.error;\n }\n if (producerState.done) {\n keepStreaming = false;\n }\n continue;\n }\n\n if (queuedChunk.smooth) {\n bufferedTextLength = Math.max(\n 0,\n bufferedTextLength - queuedChunk.textLength\n );\n notifyProducerForSpace();\n await waitForStreamDelay(\n getCadencedStreamDelay({\n targetDelay: hasEmittedText ? this._lc_stream_delay : 0,\n lastVisibleTextAt,\n now: Date.now(),\n }),\n options.signal\n );\n if (isSignalAborted(options.signal)) {\n stream.controller.abort();\n throw new Error('AbortError: User aborted the request.');\n }\n hasEmittedText = true;\n lastVisibleTextAt = Date.now();\n } else {\n notifyProducerForSpace();\n }\n\n yield queuedChunk.chunk;\n await runManager?.handleLLMNewToken(\n queuedChunk.token,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: queuedChunk.chunk }\n );\n }\n } finally {\n consumerClosed = true;\n if (!producerState.done) {\n stream.controller.abort();\n notifyProducerForSpace();\n }\n await producer;\n this.resetTokenEvents();\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/llm/anthropic/index.ts"],"sourcesContent":["import { AIMessageChunk } from '@langchain/core/messages';\nimport { ChatAnthropicMessages } from '@langchain/anthropic';\nimport { ChatGenerationChunk } from '@langchain/core/outputs';\nimport type { BaseChatModelParams } from '@langchain/core/language_models/chat_models';\nimport type {\n BaseMessage,\n MessageContentComplex,\n} from '@langchain/core/messages';\nimport type { ChatModelStreamEvent } from '@langchain/core/language_models/event';\nimport type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';\nimport type { AnthropicInput } from '@langchain/anthropic';\nimport type { Anthropic } from '@anthropic-ai/sdk';\nimport type {\n AnthropicMessageCreateParams,\n AnthropicStreamingMessageCreateParams,\n AnthropicOutputConfig,\n AnthropicBeta,\n ChatAnthropicToolType,\n AnthropicMCPServerURLDefinition,\n AnthropicContextManagementConfigParam,\n AnthropicRequestOptions,\n AnthropicMessageStreamEvent,\n} from '@/llm/anthropic/types';\nimport type { SmoothItem } from '@/llm/stream/smoother';\nimport type { AnthropicUsageData } from './utils/message_outputs';\nimport {\n _convertMessagesToAnthropicPayload,\n stripUnsupportedAssistantPrefill,\n} from './utils/message_inputs';\nimport { _makeMessageChunkFromAnthropicEvent } from './utils/message_outputs';\nimport { smoothStream, resolveStreamDelay, isSignalAborted } from '@/llm/stream/smoother';\nimport { convertAnthropicStream } from './utils/stream_events';\nimport { handleToolChoice } from './utils/tools';\n\ntype StreamTokenType = 'string' | 'input' | 'content';\n\ninterface AnthropicStreamUsage {\n inputTokens: number;\n cacheCreationInputTokens: number;\n cacheReadInputTokens: number;\n outputTokens: number;\n}\n\ninterface CumulativeUsageValue {\n cumulative: number;\n increment: number;\n}\n\ninterface AnthropicEventStream\n extends AsyncIterable<AnthropicMessageStreamEvent> {\n controller?: { abort: () => void };\n}\n\nconst ANTHROPIC_TOOL_BETAS: Partial<Record<string, AnthropicBeta>> = {\n tool_search_tool_regex_20251119: 'advanced-tool-use-2025-11-20',\n tool_search_tool_bm25_20251119: 'advanced-tool-use-2025-11-20',\n memory_20250818: 'context-management-2025-06-27',\n web_fetch_20250910: 'web-fetch-2025-09-10',\n code_execution_20250825: 'code-execution-2025-08-25',\n computer_20251124: 'computer-use-2025-11-24',\n computer_20250124: 'computer-use-2025-01-24',\n mcp_toolset: 'mcp-client-2025-11-20',\n};\n\nfunction _toolsInParams(\n params: AnthropicMessageCreateParams | AnthropicStreamingMessageCreateParams\n): boolean {\n return !!(params.tools && params.tools.length > 0);\n}\nexport function _documentsInParams(\n params: AnthropicMessageCreateParams | AnthropicStreamingMessageCreateParams\n): boolean {\n for (const message of params.messages) {\n if (typeof message.content === 'string') {\n continue;\n }\n for (const block of message.content) {\n const maybeBlock: unknown = block;\n if (\n typeof maybeBlock === 'object' &&\n maybeBlock !== null &&\n 'type' in maybeBlock &&\n maybeBlock.type === 'document' &&\n 'citations' in maybeBlock &&\n maybeBlock.citations != null &&\n typeof maybeBlock.citations === 'object' &&\n 'enabled' in maybeBlock.citations &&\n maybeBlock.citations.enabled === true\n ) {\n return true;\n }\n }\n }\n return false;\n}\n\nfunction _thinkingInParams(\n params: AnthropicMessageCreateParams | AnthropicStreamingMessageCreateParams\n): boolean {\n return !!(\n params.thinking &&\n (params.thinking.type === 'enabled' || params.thinking.type === 'adaptive')\n );\n}\n\nfunction _compactionInParams(\n params: (\n | AnthropicMessageCreateParams\n | AnthropicStreamingMessageCreateParams\n ) & {\n context_management?: AnthropicContextManagementConfigParam;\n }\n): boolean {\n return (\n params.context_management?.edits?.some(\n (edit) => edit.type === 'compact_20260112'\n ) === true\n );\n}\n\nfunction isThinkingEnabled(thinking: Anthropic.ThinkingConfigParam): boolean {\n return thinking.type === 'enabled' || thinking.type === 'adaptive';\n}\n\nfunction isOpus47Model(model?: string): boolean {\n return /^claude-opus-4-7(?:-|$)/.test(model ?? '');\n}\n\nfunction combineBetas(\n ...betaGroups: (AnthropicBeta[] | undefined)[]\n): AnthropicBeta[] {\n const betas = new Set<AnthropicBeta>();\n for (const betaGroup of betaGroups) {\n for (const beta of betaGroup ?? []) {\n betas.add(beta);\n }\n }\n return [...betas];\n}\n\nfunction getToolBetas(tools?: ChatAnthropicToolType[]): AnthropicBeta[] {\n const betas = new Set<AnthropicBeta>();\n for (const tool of tools ?? []) {\n if (typeof tool !== 'object' || !('type' in tool)) {\n continue;\n }\n const beta = ANTHROPIC_TOOL_BETAS[String(tool.type)];\n if (beta != null) {\n betas.add(beta);\n }\n }\n return [...betas];\n}\n\nfunction getCompactionBetas(\n contextManagement?: AnthropicContextManagementConfigParam\n): AnthropicBeta[] {\n return contextManagement?.edits?.some(\n (edit) => edit.type === 'compact_20260112'\n ) === true\n ? ['compact-2026-01-12']\n : [];\n}\n\nfunction getTaskBudgetBetas(\n model: string,\n outputConfig?: AnthropicOutputConfig\n): AnthropicBeta[] {\n return isOpus47Model(model) &&\n outputConfig != null &&\n 'task_budget' in outputConfig &&\n outputConfig.task_budget != null\n ? ['task-budgets-2026-03-13']\n : [];\n}\n\nfunction isSetSamplingValue(value?: number | null): value is number {\n return value != null && value !== -1;\n}\n\nfunction isNonDefaultTemperature(value?: number): boolean {\n return isSetSamplingValue(value) && value !== 1;\n}\n\nfunction validateInvocationParamCompatibility({\n model,\n thinking,\n topK,\n topP,\n temperature,\n}: {\n model: string;\n thinking: Anthropic.ThinkingConfigParam;\n topK?: number;\n topP?: number | null;\n temperature?: number;\n}): void {\n const opus47 = isOpus47Model(model);\n if (opus47 && thinking.type === 'enabled') {\n throw new Error(\n 'thinking.type=\"enabled\" is not supported for claude-opus-4-7; use thinking.type=\"adaptive\" instead'\n );\n }\n if (opus47 && 'budget_tokens' in thinking) {\n throw new Error(\n 'thinking.budget_tokens is not supported for claude-opus-4-7; use outputConfig.effort instead'\n );\n }\n if (opus47) {\n if (isSetSamplingValue(topK)) {\n throw new Error(\n 'topK is not supported for claude-opus-4-7; omit topK/topP/temperature or use model prompting instead'\n );\n }\n if (isSetSamplingValue(topP) && topP !== 1) {\n throw new Error(\n 'topP is not supported for claude-opus-4-7 when set to non-default values'\n );\n }\n if (isNonDefaultTemperature(temperature)) {\n throw new Error(\n 'temperature is not supported for claude-opus-4-7 when set to non-default values'\n );\n }\n }\n if (!isThinkingEnabled(thinking)) {\n return;\n }\n if (isSetSamplingValue(topK)) {\n throw new Error('topK is not supported when thinking is enabled');\n }\n if (isSetSamplingValue(topP)) {\n throw new Error('topP is not supported when thinking is enabled');\n }\n if (isNonDefaultTemperature(temperature)) {\n throw new Error('temperature is not supported when thinking is enabled');\n }\n}\n\nfunction getSamplingParams({\n model,\n thinking,\n topK,\n topP,\n temperature,\n}: {\n model: string;\n thinking: Anthropic.ThinkingConfigParam;\n topK?: number;\n topP?: number | null;\n temperature?: number;\n}): {\n temperature?: number;\n top_k?: number;\n top_p?: number;\n} {\n if (isThinkingEnabled(thinking) || isOpus47Model(model)) {\n return {};\n }\n return {\n ...(isSetSamplingValue(temperature) ? { temperature } : {}),\n ...(isSetSamplingValue(topK) ? { top_k: topK } : {}),\n ...(isSetSamplingValue(topP) ? { top_p: topP } : {}),\n };\n}\n\nasync function* abortableAnthropicStream(\n source: AnthropicEventStream,\n signal?: AbortSignal\n): AsyncGenerator<AnthropicMessageStreamEvent> {\n for await (const data of source) {\n if (isSignalAborted(signal)) {\n source.controller?.abort();\n return;\n }\n yield data;\n }\n}\n\nfunction extractToken(\n chunk: AIMessageChunk\n): [string, StreamTokenType] | [undefined] {\n if (typeof chunk.content === 'string') {\n return [chunk.content, 'string'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'input' in chunk.content[0]\n ) {\n return typeof chunk.content[0].input === 'string'\n ? [chunk.content[0].input, 'input']\n : [JSON.stringify(chunk.content[0].input), 'input'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'text' in chunk.content[0]\n ) {\n const text = chunk.content[0].text;\n return typeof text === 'string' ? [text, 'content'] : [undefined];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'thinking' in chunk.content[0]\n ) {\n const thinking = chunk.content[0].thinking;\n return typeof thinking === 'string' ? [thinking, 'content'] : [undefined];\n }\n return [undefined];\n}\n\nfunction cloneChunk(\n text: string,\n tokenType: StreamTokenType,\n chunk: AIMessageChunk\n): AIMessageChunk {\n if (tokenType === 'string') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: text }));\n } else if (tokenType === 'input') {\n return chunk;\n }\n const content = chunk.content[0] as MessageContentComplex;\n if (content.type === 'text') {\n return new AIMessageChunk(\n Object.assign({}, chunk, {\n content: [Object.assign({}, content, { text })],\n })\n );\n } else if (content.type === 'text_delta') {\n return new AIMessageChunk(\n Object.assign({}, chunk, {\n content: [Object.assign({}, content, { text })],\n })\n );\n } else if (\n typeof content.type === 'string' &&\n content.type.startsWith('thinking')\n ) {\n return new AIMessageChunk(\n Object.assign({}, chunk, {\n content: [Object.assign({}, content, { thinking: text })],\n })\n );\n }\n\n return chunk;\n}\n\nfunction resolveCumulativeUsageValue(\n current: number | null | undefined,\n previous: number\n): CumulativeUsageValue {\n if (current == null) {\n return { cumulative: previous, increment: 0 };\n }\n const cumulative = Math.max(previous, current);\n return { cumulative, increment: cumulative - previous };\n}\n\nfunction withIncrementalMessageDeltaUsage(\n chunk: AIMessageChunk,\n previousUsage: AnthropicStreamUsage,\n cumulativeUsage: AnthropicUsageData\n): { chunk: AIMessageChunk; usage: AnthropicStreamUsage } {\n const usage = chunk.usage_metadata;\n if (usage == null) {\n return { chunk, usage: previousUsage };\n }\n\n const inputTokens = resolveCumulativeUsageValue(\n cumulativeUsage.input_tokens,\n previousUsage.inputTokens\n );\n const cacheCreationInputTokens = resolveCumulativeUsageValue(\n cumulativeUsage.cache_creation_input_tokens,\n previousUsage.cacheCreationInputTokens\n );\n const cacheReadInputTokens = resolveCumulativeUsageValue(\n cumulativeUsage.cache_read_input_tokens,\n previousUsage.cacheReadInputTokens\n );\n const outputTokens = resolveCumulativeUsageValue(\n cumulativeUsage.output_tokens,\n previousUsage.outputTokens\n );\n const incrementalInputTokens =\n inputTokens.increment +\n cacheCreationInputTokens.increment +\n cacheReadInputTokens.increment;\n const hasCacheUsage =\n cumulativeUsage.cache_creation_input_tokens != null ||\n cumulativeUsage.cache_read_input_tokens != null;\n const inputTokenDetails = {\n ...(cumulativeUsage.cache_creation_input_tokens != null && {\n cache_creation: cacheCreationInputTokens.increment,\n }),\n ...(cumulativeUsage.cache_read_input_tokens != null && {\n cache_read: cacheReadInputTokens.increment,\n }),\n };\n\n return {\n chunk: new AIMessageChunk(\n Object.assign({}, chunk, {\n usage_metadata: {\n ...usage,\n input_tokens: incrementalInputTokens,\n output_tokens: outputTokens.increment,\n total_tokens: incrementalInputTokens + outputTokens.increment,\n input_token_details: hasCacheUsage ? inputTokenDetails : undefined,\n },\n })\n ),\n usage: {\n inputTokens: inputTokens.cumulative,\n cacheCreationInputTokens: cacheCreationInputTokens.cumulative,\n cacheReadInputTokens: cacheReadInputTokens.cumulative,\n outputTokens: outputTokens.cumulative,\n },\n };\n}\n\nexport type CustomAnthropicInput = AnthropicInput & {\n _lc_stream_delay?: number;\n outputConfig?: AnthropicOutputConfig;\n inferenceGeo?: string;\n contextManagement?: AnthropicContextManagementConfigParam;\n} & BaseChatModelParams;\n\nexport type CustomAnthropicCallOptions = {\n outputConfig?: AnthropicOutputConfig;\n outputFormat?: Anthropic.Messages.JSONOutputFormat;\n inferenceGeo?: string;\n betas?: AnthropicBeta[];\n container?: string;\n mcp_servers?: AnthropicMCPServerURLDefinition[];\n};\n\ntype CustomAnthropicInvocationParams = {\n betas?: AnthropicBeta[];\n container?: string;\n context_management?: AnthropicContextManagementConfigParam;\n inference_geo?: string;\n mcp_servers?: AnthropicMCPServerURLDefinition[];\n output_config?: AnthropicOutputConfig;\n};\n\ntype AnthropicEmittedChunk = {\n chunk: ChatGenerationChunk;\n token: string;\n};\n\nexport class CustomAnthropic extends ChatAnthropicMessages {\n _lc_stream_delay: number;\n private tools_in_params?: boolean;\n top_k: number | undefined;\n outputConfig?: AnthropicOutputConfig;\n inferenceGeo?: string;\n contextManagement?: AnthropicContextManagementConfigParam;\n constructor(fields?: CustomAnthropicInput) {\n super(fields);\n this.resetTokenEvents();\n this.setDirectFields(fields);\n this._lc_stream_delay = resolveStreamDelay(fields?._lc_stream_delay);\n this.outputConfig = fields?.outputConfig;\n this.inferenceGeo = fields?.inferenceGeo;\n this.contextManagement = fields?.contextManagement;\n }\n\n static lc_name(): 'LibreChatAnthropic' {\n return 'LibreChatAnthropic';\n }\n\n /**\n * Get the parameters used to invoke the model\n */\n override invocationParams(\n options?: this['ParsedCallOptions'] & CustomAnthropicCallOptions\n ): Omit<\n AnthropicMessageCreateParams | AnthropicStreamingMessageCreateParams,\n 'messages'\n > &\n CustomAnthropicInvocationParams {\n const tool_choice:\n | Anthropic.Messages.ToolChoiceAuto\n | Anthropic.Messages.ToolChoiceAny\n | Anthropic.Messages.ToolChoiceTool\n | Anthropic.Messages.ToolChoiceNone\n | undefined = handleToolChoice(options?.tool_choice);\n\n const callOptions = options as CustomAnthropicCallOptions | undefined;\n const mergedOutputConfig: AnthropicOutputConfig | undefined = (():\n | AnthropicOutputConfig\n | undefined => {\n const base = {\n ...this.outputConfig,\n ...callOptions?.outputConfig,\n };\n if (callOptions?.outputFormat && !base.format) {\n base.format = callOptions.outputFormat;\n }\n return Object.keys(base).length > 0 ? base : undefined;\n })();\n\n const inferenceGeo = callOptions?.inferenceGeo ?? this.inferenceGeo;\n\n const contextManagement = this.contextManagement;\n const toolBetas = getToolBetas(options?.tools);\n const compactionBetas = getCompactionBetas(contextManagement);\n const taskBudgetBetas = getTaskBudgetBetas(this.model, mergedOutputConfig);\n const formattedTools = this.formatStructuredToolToAnthropic(\n options?.tools,\n {\n strict: options?.strict,\n }\n );\n\n const sharedParams = {\n tools: formattedTools,\n tool_choice,\n // Match upstream: omit `thinking` unless the user set it, so we don't send\n // `{ type: 'disabled' }` (an unsupported param on some models) by default.\n thinking: this.thinkingExplicitlySet ? this.thinking : undefined,\n context_management: contextManagement,\n ...this.invocationKwargs,\n container: callOptions?.container,\n betas: combineBetas(\n this.betas,\n callOptions?.betas,\n toolBetas,\n compactionBetas,\n taskBudgetBetas\n ),\n output_config: mergedOutputConfig,\n inference_geo: inferenceGeo,\n mcp_servers: callOptions?.mcp_servers,\n // Top-level request cache_control (1.5.x): API auto-advances the cache\n // breakpoint across turns. Additive — independent of our block-level cache.\n cache_control: options?.cache_control,\n };\n validateInvocationParamCompatibility({\n model: this.model,\n thinking: this.thinking,\n topK: this.top_k,\n topP: this.topP,\n temperature: this.temperature,\n });\n\n return {\n model: this.model,\n stop_sequences: options?.stop ?? this.stopSequences,\n stream: this.streaming,\n max_tokens: this.maxTokens,\n ...getSamplingParams({\n model: this.model,\n thinking: this.thinking,\n topK: this.top_k,\n topP: this.topP,\n temperature: this.temperature,\n }),\n ...sharedParams,\n };\n }\n\n resetTokenEvents(): void {\n this.tools_in_params = undefined;\n }\n\n setDirectFields(fields?: CustomAnthropicInput): void {\n this.temperature = fields?.temperature ?? undefined;\n this.topP = fields?.topP ?? undefined;\n this.top_k = fields?.topK;\n if (this.temperature === -1 || this.temperature === 1) {\n this.temperature = undefined;\n }\n if (this.topP === -1) {\n this.topP = undefined;\n }\n if (this.top_k === -1) {\n this.top_k = undefined;\n }\n }\n\n private createGenerationChunk({\n token,\n chunk,\n shouldStreamUsage,\n }: {\n token?: string;\n chunk: AIMessageChunk;\n shouldStreamUsage: boolean;\n }): ChatGenerationChunk {\n const usage_metadata = shouldStreamUsage ? chunk.usage_metadata : undefined;\n return new ChatGenerationChunk({\n message: new AIMessageChunk({\n // Just yield chunk as it is and tool_use will be concat by BaseChatModel._generateUncached().\n content: chunk.content,\n additional_kwargs: chunk.additional_kwargs,\n tool_call_chunks: chunk.tool_call_chunks,\n response_metadata: chunk.response_metadata,\n usage_metadata,\n id: chunk.id,\n }),\n text: token ?? '',\n });\n }\n\n protected override async createStreamWithRetry(\n request: AnthropicStreamingMessageCreateParams,\n options?: AnthropicRequestOptions\n ): ReturnType<ChatAnthropicMessages['createStreamWithRetry']> {\n return super.createStreamWithRetry(\n stripUnsupportedAssistantPrefill(request),\n options\n );\n }\n\n protected override async completionWithRetry(\n request: AnthropicMessageCreateParams,\n options: AnthropicRequestOptions\n ): ReturnType<ChatAnthropicMessages['completionWithRetry']> {\n return super.completionWithRetry(\n stripUnsupportedAssistantPrefill(request),\n options\n );\n }\n\n async *_streamChatModelEvents(\n messages: BaseMessage[],\n options: this['ParsedCallOptions'],\n _runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatModelStreamEvent> {\n const params = this.invocationParams(options);\n const formattedMessages = _convertMessagesToAnthropicPayload(messages);\n const payload = stripUnsupportedAssistantPrefill({\n ...params,\n ...formattedMessages,\n stream: true,\n } as const);\n const stream = await this.createStreamWithRetry(payload, {\n headers: options.headers,\n signal: options.signal,\n });\n const shouldStreamUsage = options.streamUsage ?? this.streamUsage;\n yield* convertAnthropicStream(\n abortableAnthropicStream(stream, options.signal),\n { streamUsage: shouldStreamUsage }\n );\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this['ParsedCallOptions'],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n this.resetTokenEvents();\n const params = this.invocationParams(options);\n const formattedMessages = _convertMessagesToAnthropicPayload(messages);\n const payload = stripUnsupportedAssistantPrefill({\n ...params,\n ...formattedMessages,\n stream: true,\n } as const);\n const coerceContentToString =\n !_toolsInParams(payload) &&\n !_documentsInParams(payload) &&\n !_thinkingInParams(payload) &&\n !_compactionInParams(payload);\n\n const stream = await this.createStreamWithRetry(payload, {\n headers: options.headers,\n signal: options.signal,\n });\n\n const shouldStreamUsage = options.streamUsage ?? this.streamUsage;\n let streamUsage: AnthropicStreamUsage = {\n inputTokens: 0,\n cacheCreationInputTokens: 0,\n cacheReadInputTokens: 0,\n outputTokens: 0,\n };\n const toEmittedChunk = (\n token: string,\n chunk: AIMessageChunk\n ): AnthropicEmittedChunk => ({\n token,\n chunk: this.createGenerationChunk({ token, chunk, shouldStreamUsage }),\n });\n\n const source = (async function* (): AsyncGenerator<\n SmoothItem<AnthropicEmittedChunk>\n > {\n for await (const data of stream) {\n const result = _makeMessageChunkFromAnthropicEvent(\n data as Anthropic.Beta.Messages.BetaRawMessageStreamEvent,\n {\n streamUsage: shouldStreamUsage,\n coerceContentToString,\n }\n );\n if (!result) {\n continue;\n }\n\n let { chunk } = result;\n if (data.type === 'message_start') {\n streamUsage = {\n ...streamUsage,\n inputTokens: data.message.usage.input_tokens,\n outputTokens: data.message.usage.output_tokens,\n cacheCreationInputTokens:\n data.message.usage.cache_creation_input_tokens ?? 0,\n cacheReadInputTokens:\n data.message.usage.cache_read_input_tokens ?? 0,\n };\n }\n if (data.type === 'message_delta') {\n const incremental = withIncrementalMessageDeltaUsage(\n chunk,\n streamUsage,\n data.usage\n );\n chunk = incremental.chunk;\n streamUsage = incremental.usage;\n }\n\n const [token = '', tokenType] = extractToken(chunk);\n if (\n !tokenType ||\n tokenType === 'input' ||\n (token === '' && (chunk.usage_metadata != null || chunk.id != null))\n ) {\n yield {\n text: '',\n smooth: false,\n emit: (): AnthropicEmittedChunk => toEmittedChunk(token, chunk),\n };\n continue;\n }\n\n if (token === '') {\n continue;\n }\n\n yield {\n text: token,\n smooth: true,\n emit: (piece): AnthropicEmittedChunk => {\n if (piece.isFirst && piece.isLast) {\n return toEmittedChunk(token, chunk);\n }\n const cloned = cloneChunk(piece.text, tokenType, chunk);\n const chunkForPiece =\n !piece.isFirst && cloned.usage_metadata != null\n ? new AIMessageChunk(\n Object.assign({}, cloned, { usage_metadata: undefined })\n )\n : cloned;\n return toEmittedChunk(piece.text, chunkForPiece);\n },\n };\n }\n })();\n\n const smoothed = smoothStream({\n source,\n delayMs: this._lc_stream_delay,\n signal: options.signal,\n abortUpstream: () => stream.controller.abort(),\n });\n\n try {\n for await (const emitted of smoothed) {\n yield emitted.chunk;\n await runManager?.handleLLMNewToken(\n emitted.token,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: emitted.chunk }\n );\n }\n } finally {\n this.resetTokenEvents();\n }\n }\n}\n"],"mappings":"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"}