@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.
- package/dist/cjs/graphs/Graph.cjs +10 -0
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/instrumentation.cjs +1 -0
- package/dist/cjs/instrumentation.cjs.map +1 -1
- package/dist/cjs/langfuseSpanRegistry.cjs +6 -3
- package/dist/cjs/langfuseSpanRegistry.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/index.cjs +35 -206
- package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/index.cjs +121 -241
- package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
- package/dist/cjs/llm/google/index.cjs +19 -12
- package/dist/cjs/llm/google/index.cjs.map +1 -1
- package/dist/cjs/llm/mistral/index.cjs +26 -0
- package/dist/cjs/llm/mistral/index.cjs.map +1 -0
- package/dist/cjs/llm/openai/index.cjs +82 -80
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
- package/dist/cjs/llm/providers.cjs +19 -19
- package/dist/cjs/llm/providers.cjs.map +1 -1
- package/dist/cjs/llm/stream/chunkAdapters.cjs +198 -0
- package/dist/cjs/llm/stream/chunkAdapters.cjs.map +1 -0
- package/dist/cjs/llm/stream/smoother.cjs +369 -0
- package/dist/cjs/llm/stream/smoother.cjs.map +1 -0
- package/dist/cjs/llm/vertexai/index.cjs +13 -1
- package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +18 -10
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs +34 -2
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
- package/dist/cjs/utils/tokens.cjs +76 -29
- package/dist/cjs/utils/tokens.cjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +10 -0
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/instrumentation.mjs +1 -0
- package/dist/esm/instrumentation.mjs.map +1 -1
- package/dist/esm/langfuseSpanRegistry.mjs +6 -3
- package/dist/esm/langfuseSpanRegistry.mjs.map +1 -1
- package/dist/esm/llm/anthropic/index.mjs +34 -205
- package/dist/esm/llm/anthropic/index.mjs.map +1 -1
- package/dist/esm/llm/bedrock/index.mjs +120 -240
- package/dist/esm/llm/bedrock/index.mjs.map +1 -1
- package/dist/esm/llm/google/index.mjs +19 -12
- package/dist/esm/llm/google/index.mjs.map +1 -1
- package/dist/esm/llm/mistral/index.mjs +26 -0
- package/dist/esm/llm/mistral/index.mjs.map +1 -0
- package/dist/esm/llm/openai/index.mjs +82 -80
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openrouter/index.mjs.map +1 -1
- package/dist/esm/llm/providers.mjs +3 -3
- package/dist/esm/llm/providers.mjs.map +1 -1
- package/dist/esm/llm/stream/chunkAdapters.mjs +195 -0
- package/dist/esm/llm/stream/chunkAdapters.mjs.map +1 -0
- package/dist/esm/llm/stream/smoother.mjs +365 -0
- package/dist/esm/llm/stream/smoother.mjs.map +1 -0
- package/dist/esm/llm/vertexai/index.mjs +13 -1
- package/dist/esm/llm/vertexai/index.mjs.map +1 -1
- package/dist/esm/main.mjs +4 -2
- package/dist/esm/tools/subagent/SubagentExecutor.mjs +34 -2
- package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
- package/dist/esm/utils/tokens.mjs +76 -30
- package/dist/esm/utils/tokens.mjs.map +1 -1
- package/dist/types/graphs/Graph.d.ts +3 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/llm/google/index.d.ts +2 -0
- package/dist/types/llm/mistral/index.d.ts +11 -0
- package/dist/types/llm/openai/index.d.ts +20 -4
- package/dist/types/llm/openrouter/index.d.ts +4 -1
- package/dist/types/llm/stream/chunkAdapters.d.ts +48 -0
- package/dist/types/llm/stream/smoother.d.ts +95 -0
- package/dist/types/llm/vertexai/index.d.ts +2 -0
- package/dist/types/tools/subagent/SubagentExecutor.d.ts +3 -0
- package/dist/types/types/graph.d.ts +5 -0
- package/dist/types/types/llm.d.ts +21 -14
- package/dist/types/utils/tokens.d.ts +10 -0
- package/package.json +2 -2
- package/src/graphs/Graph.ts +11 -0
- package/src/index.ts +8 -0
- package/src/instrumentation.ts +1 -0
- package/src/langfuseSpanRegistry.ts +9 -0
- package/src/llm/anthropic/index.ts +85 -354
- package/src/llm/bedrock/index.ts +174 -390
- package/src/llm/bedrock/llm.spec.ts +2 -0
- package/src/llm/bedrock/streamSealDispatch.test.ts +76 -0
- package/src/llm/custom-chat-models.smoke.test.ts +16 -1
- package/src/llm/google/index.ts +17 -18
- package/src/llm/google/streamSmoothing.test.ts +121 -0
- package/src/llm/mistral/index.ts +33 -0
- package/src/llm/mistral/streamSmoothing.test.ts +97 -0
- package/src/llm/openai/deepseek.test.ts +56 -0
- package/src/llm/openai/index.ts +119 -126
- package/src/llm/openrouter/index.ts +4 -1
- package/src/llm/providers.ts +3 -3
- package/src/llm/stream/chunkAdapters.test.ts +202 -0
- package/src/llm/stream/chunkAdapters.ts +317 -0
- package/src/llm/stream/reassembly.test.ts +241 -0
- package/src/llm/stream/smoother.bench.test.ts +155 -0
- package/src/llm/stream/smoother.test.ts +519 -0
- package/src/llm/stream/smoother.ts +574 -0
- package/src/llm/vertexai/index.ts +17 -1
- package/src/llm/vertexai/streamSmoothing.test.ts +109 -0
- package/src/specs/langfuse-instrumentation.test.ts +26 -0
- package/src/specs/langfuse-span-registry.test.ts +17 -0
- package/src/specs/subagent.test.ts +44 -0
- package/src/specs/summarization.test.ts +5 -2
- package/src/specs/tokens.test.ts +159 -14
- package/src/tools/__tests__/SubagentExecutor.test.ts +48 -1
- package/src/tools/subagent/SubagentExecutor.ts +69 -5
- package/src/types/graph.ts +5 -0
- package/src/types/llm.ts +53 -36
- 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.cjs","names":["resolveTraceIdSeedForSpan","context","isPresent","traceIdFromSeed","ROOT_CONTEXT","AsyncLocalStorageContextManager","getLangfuseSpanProcessorParams","getLangfuseDestinationKey","createLangfuseSpanProcessor","resolveLangfuseConfigForSpan","createLibreChatTraceAttributes","BasicTracerProvider"],"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":"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"}
|
|
1
|
+
{"version":3,"file":"instrumentation.cjs","names":["resolveTraceIdSeedForSpan","context","isPresent","traceIdFromSeed","ROOT_CONTEXT","AsyncLocalStorageContextManager","getLangfuseSpanProcessorParams","getLangfuseDestinationKey","createLangfuseSpanProcessor","resolveLangfuseConfigForSpan","createLibreChatTraceAttributes","BasicTracerProvider"],"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
|
...require_misc.isPresent(langfuse.baseUrl) ? { baseUrl: langfuse.baseUrl } : {},
|
|
46
|
-
...require_misc.isPresent(environment) ? { environment } : {}
|
|
46
|
+
...require_misc.isPresent(environment) ? { environment } : {},
|
|
47
|
+
...langfuse.mediaUploadEnabled != null ? { mediaUploadEnabled: langfuse.mediaUploadEnabled } : {}
|
|
47
48
|
};
|
|
48
49
|
if (require_langfuseConfig.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
|
...require_misc.isPresent(baseUrl) ? { baseUrl } : {},
|
|
54
|
-
...require_misc.isPresent(environment) ? { environment } : {}
|
|
55
|
+
...require_misc.isPresent(environment) ? { environment } : {},
|
|
56
|
+
...langfuse?.mediaUploadEnabled != null ? { mediaUploadEnabled: langfuse.mediaUploadEnabled } : {}
|
|
55
57
|
};
|
|
56
58
|
}
|
|
57
59
|
if (require_misc.isPresent(langfuse?.baseUrl) && require_langfuseConfig.hasLangfuseEnvCredentials()) return {
|
|
58
60
|
publicKey: process.env.LANGFUSE_PUBLIC_KEY,
|
|
59
61
|
secretKey: process.env.LANGFUSE_SECRET_KEY,
|
|
60
62
|
baseUrl: langfuse.baseUrl,
|
|
61
|
-
...require_misc.isPresent(environment) ? { environment } : {}
|
|
63
|
+
...require_misc.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.cjs","names":["hasLangfuseConfigCredentials","isPresent","hasLangfuseEnvConfig","hasLangfuseEnvCredentials"],"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,IAAIA,uBAAAA,6BAA6B,QAAQ,GACvC,OAAO;EACL,WAAW,SAAS;EACpB,WAAW,SAAS;EACpB,GAAIC,aAAAA,UAAU,SAAS,OAAO,IAAI,EAAE,SAAS,SAAS,QAAQ,IAAI,CAAC;EACnE,GAAIA,aAAAA,UAAU,WAAW,IAAI,EAAE,YAAY,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"langfuseSpanRegistry.cjs","names":["hasLangfuseConfigCredentials","isPresent","hasLangfuseEnvConfig","hasLangfuseEnvCredentials"],"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,IAAIA,uBAAAA,6BAA6B,QAAQ,GACvC,OAAO;EACL,WAAW,SAAS;EACpB,WAAW,SAAS;EACpB,GAAIC,aAAAA,UAAU,SAAS,OAAO,IAAI,EAAE,SAAS,SAAS,QAAQ,IAAI,CAAC;EACnE,GAAIA,aAAAA,UAAU,WAAW,IAAI,EAAE,YAAY,IAAI,CAAC;EAChD,GAAI,SAAS,sBAAsB,OAC/B,EAAE,oBAAoB,SAAS,mBAAmB,IAClD,CAAC;CACP;CAEF,IAAIC,uBAAAA,qBAAqB,GAAG;EAC1B,MAAM,UACJ,UAAU,WACV,QAAQ,IAAI,qBACZ,QAAQ,IAAI;EACd,OAAO;GACL,WAAW,QAAQ,IAAI;GACvB,WAAW,QAAQ,IAAI;GACvB,GAAID,aAAAA,UAAU,OAAO,IAAI,EAAE,QAAQ,IAAI,CAAC;GACxC,GAAIA,aAAAA,UAAU,WAAW,IAAI,EAAE,YAAY,IAAI,CAAC;GAChD,GAAI,UAAU,sBAAsB,OAChC,EAAE,oBAAoB,SAAS,mBAAmB,IAClD,CAAC;EACP;CACF;CACA,IAAIA,aAAAA,UAAU,UAAU,OAAO,KAAKE,uBAAAA,0BAA0B,GAC5D,OAAO;EACL,WAAW,QAAQ,IAAI;EACvB,WAAW,QAAQ,IAAI;EACvB,SAAS,SAAS;EAClB,GAAIF,aAAAA,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,OAAOA,aAAAA,UAAU,KAAK,KAAA,GAAA,YAAA,WAAA,CACP,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
|
const require_message_inputs = require("./utils/message_inputs.cjs");
|
|
2
|
+
const require_smoother = require("../stream/smoother.cjs");
|
|
2
3
|
const require_message_outputs = require("./utils/message_outputs.cjs");
|
|
3
4
|
const require_stream_events = require("./utils/stream_events.cjs");
|
|
4
5
|
const require_tools = require("./utils/tools.cjs");
|
|
@@ -6,19 +7,6 @@ let _langchain_core_messages = require("@langchain/core/messages");
|
|
|
6
7
|
let _langchain_core_outputs = require("@langchain/core/outputs");
|
|
7
8
|
let _langchain_anthropic = require("@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,48 +90,9 @@ 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
|
-
if (isSignalAborted(signal)) {
|
|
95
|
+
if (require_smoother.isSignalAborted(signal)) {
|
|
147
96
|
source.controller?.abort();
|
|
148
97
|
return;
|
|
149
98
|
}
|
|
@@ -225,7 +174,7 @@ var CustomAnthropic = class extends _langchain_anthropic.ChatAnthropicMessages {
|
|
|
225
174
|
super(fields);
|
|
226
175
|
this.resetTokenEvents();
|
|
227
176
|
this.setDirectFields(fields);
|
|
228
|
-
this._lc_stream_delay =
|
|
177
|
+
this._lc_stream_delay = require_smoother.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 _langchain_anthropic.ChatAnthropicMessages {
|
|
|
354
303
|
cacheReadInputTokens: 0,
|
|
355
304
|
outputTokens: 0
|
|
356
305
|
};
|
|
357
|
-
const
|
|
358
|
-
|
|
359
|
-
|
|
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
|
-
|
|
441
|
-
})
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
const newChunk = cloneChunk(currentToken, tokenType, chunk);
|
|
446
|
-
await enqueueChunk({
|
|
447
|
-
token: currentToken,
|
|
448
|
-
chunk: emittedUsage && newChunk.usage_metadata != null ? new _langchain_core_messages.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 = require_smoother.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 = require_message_outputs._makeMessageChunkFromAnthropicEvent(data, {
|
|
462
318
|
streamUsage: shouldStreamUsage,
|
|
463
319
|
coerceContentToString
|
|
@@ -478,63 +334,36 @@ var CustomAnthropic = class extends _langchain_anthropic.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
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
}
|
|
337
|
+
yield {
|
|
338
|
+
text: "",
|
|
339
|
+
smooth: false,
|
|
340
|
+
emit: () => toEmittedChunk(token, chunk)
|
|
341
|
+
};
|
|
486
342
|
continue;
|
|
487
343
|
}
|
|
488
|
-
|
|
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 _langchain_core_messages.AIMessageChunk(Object.assign({}, cloned, { usage_metadata: void 0 })) : cloned;
|
|
352
|
+
return toEmittedChunk(piece.text, chunkForPiece);
|
|
353
|
+
}
|
|
354
|
+
};
|
|
489
355
|
}
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
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
|
-
|
|
502
|
-
|
|
503
|
-
|
|
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.cjs","names":["AIMessageChunk","ChatAnthropicMessages","handleToolChoice","ChatGenerationChunk","stripUnsupportedAssistantPrefill","_convertMessagesToAnthropicPayload","convertAnthropicStream","_makeMessageChunkFromAnthropicEvent"],"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.cjs","names":["isSignalAborted","AIMessageChunk","ChatAnthropicMessages","resolveStreamDelay","handleToolChoice","ChatGenerationChunk","stripUnsupportedAssistantPrefill","_convertMessagesToAnthropicPayload","convertAnthropicStream","smoothStream","_makeMessageChunkFromAnthropicEvent"],"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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"}
|