From d31efc9dc6f4bf996ee8b05285e4bffb302b5d54 Mon Sep 17 00:00:00 2001 From: alban bertolini Date: Fri, 23 Jan 2026 15:37:27 +0100 Subject: [PATCH 1/2] feat(ai-proxy): add Anthropic LLM provider support Add support for Anthropic's Claude models in the ai-proxy package using @langchain/anthropic. This allows users to configure Claude as their AI provider alongside OpenAI. Changes: - Add @langchain/anthropic dependency - Add ANTHROPIC_MODELS constant with supported Claude models - Add AnthropicConfiguration type and AnthropicModel type - Add AnthropicUnprocessableError for Anthropic-specific errors - Implement message conversion from OpenAI format to LangChain format - Implement response conversion from LangChain format back to OpenAI format - Add tool binding support for Anthropic with tool_choice conversion - Add comprehensive tests for Anthropic provider Co-Authored-By: Claude Opus 4.5 --- package.json | 3 + packages/ai-proxy/package.json | 1 + packages/ai-proxy/src/provider-dispatcher.ts | 212 ++++++++- packages/ai-proxy/src/types/errors.ts | 7 + .../ai-proxy/test/provider-dispatcher.test.ts | 363 ++++++++++++++- yarn.lock | 419 ++++++++---------- 6 files changed, 770 insertions(+), 235 deletions(-) diff --git a/package.json b/package.json index f576a15c8..f711a396a 100644 --- a/package.json +++ b/package.json @@ -60,5 +60,8 @@ "micromatch": "^4.0.8", "@babel/helpers": "^7.26.10", "semantic-release": "^25.0.0" + }, + "dependencies": { + "@langchain/anthropic": "^0.3.17" } } diff --git a/packages/ai-proxy/package.json b/packages/ai-proxy/package.json index 6c8abaa01..6f2cc57c0 100644 --- a/packages/ai-proxy/package.json +++ b/packages/ai-proxy/package.json @@ -13,6 +13,7 @@ }, "dependencies": { "@forestadmin/datasource-toolkit": "1.50.1", + "@langchain/anthropic": "^0.3.17", "@langchain/community": "1.1.4", "@langchain/core": "1.1.15", "@langchain/langgraph": "^1.1.0", diff --git a/packages/ai-proxy/src/provider-dispatcher.ts b/packages/ai-proxy/src/provider-dispatcher.ts index 5f04f3288..8aed5e189 100644 --- a/packages/ai-proxy/src/provider-dispatcher.ts +++ b/packages/ai-proxy/src/provider-dispatcher.ts @@ -1,12 +1,34 @@ import type { RemoteTools } from './remote-tools'; -import type { BaseMessageLike } from '@langchain/core/messages'; +import type { AnthropicInput } from '@langchain/anthropic'; +import type { BaseMessage, BaseMessageLike } from '@langchain/core/messages'; import type { ChatOpenAIFields, OpenAIChatModelId } from '@langchain/openai'; import type OpenAI from 'openai'; +import { ChatAnthropic } from '@langchain/anthropic'; +import { AIMessage, HumanMessage, SystemMessage, ToolMessage } from '@langchain/core/messages'; import { convertToOpenAIFunction } from '@langchain/core/utils/function_calling'; import { ChatOpenAI } from '@langchain/openai'; -import { AINotConfiguredError, OpenAIUnprocessableError } from './types/errors'; +import { + AINotConfiguredError, + AnthropicUnprocessableError, + OpenAIUnprocessableError, +} from './types/errors'; + +export const ANTHROPIC_MODELS = [ + 'claude-sonnet-4-5-20250514', + 'claude-opus-4-20250514', + 'claude-3-5-sonnet-latest', + 'claude-3-5-sonnet-20241022', + 'claude-3-5-haiku-latest', + 'claude-3-5-haiku-20241022', + 'claude-3-opus-latest', + 'claude-3-opus-20240229', + 'claude-3-sonnet-20240229', + 'claude-3-haiku-20240307', +] as const; + +export type AnthropicModel = (typeof ANTHROPIC_MODELS)[number]; /** * OpenAI model prefixes that do NOT support function calling (tools). @@ -65,8 +87,19 @@ export type OpenAiConfiguration = BaseAiConfiguration & model: OpenAIChatModelId | (string & NonNullable); }; -export type AiProvider = 'openai'; -export type AiConfiguration = OpenAiConfiguration; +/** + * Anthropic-specific configuration. + * Extends base with all ChatAnthropic options (temperature, maxTokens, etc.) + * Supports both `apiKey` (unified) and `anthropicApiKey` (native) for flexibility. + */ +export type AnthropicConfiguration = BaseAiConfiguration & + Omit & { + provider: 'anthropic'; + model: AnthropicModel; + }; + +export type AiProvider = 'openai' | 'anthropic'; +export type AiConfiguration = OpenAiConfiguration | AnthropicConfiguration; export type ChatCompletionResponse = OpenAI.Chat.Completions.ChatCompletion; export type ChatCompletionMessage = OpenAI.Chat.Completions.ChatCompletionMessageParam; @@ -79,8 +112,25 @@ export type DispatchBody = { tool_choice?: ChatCompletionToolChoice; }; +interface OpenAIMessage { + role: 'system' | 'user' | 'assistant' | 'tool'; + content: string; + tool_calls?: Array<{ + id: string; + function: { + name: string; + arguments: string; + }; + }>; + tool_call_id?: string; +} + export class ProviderDispatcher { - private readonly chatModel: ChatOpenAI | null = null; + private readonly openaiModel: ChatOpenAI | null = null; + + private readonly anthropicModel: ChatAnthropic | null = null; + + private readonly modelName: string | null = null; private readonly remoteTools: RemoteTools; @@ -89,22 +139,37 @@ export class ProviderDispatcher { if (configuration?.provider === 'openai') { const { provider, name, ...chatOpenAIOptions } = configuration; - this.chatModel = new ChatOpenAI({ + this.openaiModel = new ChatOpenAI({ ...chatOpenAIOptions, __includeRawResponse: true, }); + } else if (configuration?.provider === 'anthropic') { + const { provider, name, model, ...clientOptions } = configuration; + this.anthropicModel = new ChatAnthropic({ + ...clientOptions, + model, + }); + this.modelName = model; } } async dispatch(body: DispatchBody): Promise { - if (!this.chatModel) { - throw new AINotConfiguredError(); + if (this.openaiModel) { + return this.dispatchOpenAI(body); } + if (this.anthropicModel) { + return this.dispatchAnthropic(body); + } + + throw new AINotConfiguredError(); + } + + private async dispatchOpenAI(body: DispatchBody): Promise { const { tools, messages, tool_choice: toolChoice } = body; const enrichedTools = this.enrichToolDefinitions(tools); - const model = this.bindToolsIfNeeded(this.chatModel, enrichedTools, toolChoice); + const model = this.bindToolsIfNeeded(this.openaiModel!, enrichedTools, toolChoice); try { const response = await model.invoke(messages as BaseMessageLike[]); @@ -136,6 +201,33 @@ export class ProviderDispatcher { } } + private async dispatchAnthropic(body: DispatchBody): Promise { + const { tools, messages, tool_choice: toolChoice } = body; + + const langChainMessages = this.convertMessagesToLangChain(messages as OpenAIMessage[]); + const enhancedTools = tools ? this.enrichToolDefinitions(tools) : undefined; + + try { + let response: AIMessage; + + if (enhancedTools?.length) { + const langChainTools = this.convertToolsToLangChain(enhancedTools); + const clientWithTools = this.anthropicModel!.bindTools(langChainTools, { + tool_choice: this.convertToolChoiceToLangChain(toolChoice), + }); + response = await clientWithTools.invoke(langChainMessages); + } else { + response = await this.anthropicModel!.invoke(langChainMessages); + } + + return this.convertLangChainResponseToOpenAI(response); + } catch (error) { + throw new AnthropicUnprocessableError( + `Error while calling Anthropic: ${(error as Error).message}`, + ); + } + } + private bindToolsIfNeeded( chatModel: ChatOpenAI, tools: ChatCompletionTool[] | undefined, @@ -150,6 +242,108 @@ export class ProviderDispatcher { }); } + private convertMessagesToLangChain(messages: OpenAIMessage[]): BaseMessage[] { + return messages.map(msg => { + switch (msg.role) { + case 'system': + return new SystemMessage(msg.content); + case 'user': + return new HumanMessage(msg.content); + case 'assistant': + if (msg.tool_calls) { + return new AIMessage({ + content: msg.content || '', + tool_calls: msg.tool_calls.map(tc => ({ + id: tc.id, + name: tc.function.name, + args: JSON.parse(tc.function.arguments), + })), + }); + } + + return new AIMessage(msg.content); + case 'tool': + return new ToolMessage({ + content: msg.content, + tool_call_id: msg.tool_call_id!, + }); + default: + return new HumanMessage(msg.content); + } + }); + } + + private convertToolsToLangChain(tools: ChatCompletionTool[]): Array<{ + type: 'function'; + function: { name: string; description?: string; parameters?: Record }; + }> { + return tools + .filter((tool): tool is ChatCompletionTool & { type: 'function' } => tool.type === 'function') + .map(tool => ({ + type: 'function' as const, + function: { + name: tool.function.name, + description: tool.function.description, + parameters: tool.function.parameters as Record | undefined, + }, + })); + } + + private convertToolChoiceToLangChain( + toolChoice: ChatCompletionToolChoice | undefined, + ): 'auto' | 'any' | 'none' | { type: 'tool'; name: string } | undefined { + if (!toolChoice) return undefined; + if (toolChoice === 'auto') return 'auto'; + if (toolChoice === 'none') return 'none'; + if (toolChoice === 'required') return 'any'; + + if (typeof toolChoice === 'object' && toolChoice.type === 'function') { + return { type: 'tool', name: toolChoice.function.name }; + } + + return undefined; + } + + private convertLangChainResponseToOpenAI(response: AIMessage): ChatCompletionResponse { + const toolCalls = response.tool_calls?.map(tc => ({ + id: tc.id || `call_${Date.now()}`, + type: 'function' as const, + function: { + name: tc.name, + arguments: JSON.stringify(tc.args), + }, + })); + + const usageMetadata = response.usage_metadata as + | { input_tokens?: number; output_tokens?: number; total_tokens?: number } + | undefined; + + return { + id: response.id || `msg_${Date.now()}`, + object: 'chat.completion', + created: Math.floor(Date.now() / 1000), + model: this.modelName!, + choices: [ + { + index: 0, + message: { + role: 'assistant', + content: typeof response.content === 'string' ? response.content : null, + refusal: null, + tool_calls: toolCalls?.length ? toolCalls : undefined, + }, + finish_reason: toolCalls?.length ? 'tool_calls' : 'stop', + logprobs: null, + }, + ], + usage: { + prompt_tokens: usageMetadata?.input_tokens || 0, + completion_tokens: usageMetadata?.output_tokens || 0, + total_tokens: usageMetadata?.total_tokens || 0, + }, + }; + } + private enrichToolDefinitions(tools?: ChatCompletionTool[]) { if (!tools || !Array.isArray(tools)) return tools; diff --git a/packages/ai-proxy/src/types/errors.ts b/packages/ai-proxy/src/types/errors.ts index 589f5ac4d..185b8478a 100644 --- a/packages/ai-proxy/src/types/errors.ts +++ b/packages/ai-proxy/src/types/errors.ts @@ -60,6 +60,13 @@ export class OpenAIUnprocessableError extends AIUnprocessableError { } } +export class AnthropicUnprocessableError extends AIUnprocessableError { + constructor(message: string) { + super(message); + this.name = 'AnthropicError'; + } +} + export class AIToolUnprocessableError extends AIUnprocessableError { constructor(message: string) { super(message); diff --git a/packages/ai-proxy/test/provider-dispatcher.test.ts b/packages/ai-proxy/test/provider-dispatcher.test.ts index c819fb1bc..45dcd583a 100644 --- a/packages/ai-proxy/test/provider-dispatcher.test.ts +++ b/packages/ai-proxy/test/provider-dispatcher.test.ts @@ -1,8 +1,15 @@ import type { DispatchBody } from '../src'; +import { AIMessage } from '@langchain/core/messages'; import { convertToOpenAIFunction } from '@langchain/core/utils/function_calling'; -import { AINotConfiguredError, isModelSupportingTools, ProviderDispatcher, RemoteTools } from '../src'; +import { + AINotConfiguredError, + AnthropicUnprocessableError, + isModelSupportingTools, + ProviderDispatcher, + RemoteTools, +} from '../src'; // Mock raw OpenAI response (returned via __includeRawResponse: true) const mockOpenAIResponse = { @@ -45,6 +52,20 @@ jest.mock('@langchain/openai', () => ({ })), })); +const anthropicInvokeMock = jest.fn(); +const anthropicBindToolsMock = jest.fn().mockReturnValue({ invoke: anthropicInvokeMock }); + +jest.mock('@langchain/anthropic', () => { + return { + ChatAnthropic: jest.fn().mockImplementation(() => { + return { + invoke: anthropicInvokeMock, + bindTools: anthropicBindToolsMock, + }; + }), + }; +}); + describe('ProviderDispatcher', () => { const apiKeys = { AI_REMOTE_TOOL_BRAVE_SEARCH_API_KEY: 'api-key' }; @@ -257,6 +278,346 @@ describe('ProviderDispatcher', () => { }); }); }); + + describe('anthropic', () => { + describe('when anthropic is configured', () => { + it('should return the response from anthropic in OpenAI format', async () => { + const mockResponse = new AIMessage({ + content: 'Hello from Claude', + id: 'msg_123', + }); + Object.assign(mockResponse, { + usage_metadata: { input_tokens: 10, output_tokens: 20, total_tokens: 30 }, + }); + anthropicInvokeMock.mockResolvedValueOnce(mockResponse); + + const dispatcher = new ProviderDispatcher( + { + name: 'claude', + provider: 'anthropic', + apiKey: 'test-api-key', + model: 'claude-3-5-sonnet-latest', + }, + new RemoteTools(apiKeys), + ); + + const response = await dispatcher.dispatch({ + tools: [], + messages: [{ role: 'user', content: 'Hello' }], + } as unknown as DispatchBody); + + expect(response).toEqual( + expect.objectContaining({ + object: 'chat.completion', + model: 'claude-3-5-sonnet-latest', + choices: [ + expect.objectContaining({ + index: 0, + message: expect.objectContaining({ + role: 'assistant', + content: 'Hello from Claude', + }), + finish_reason: 'stop', + }), + ], + usage: { + prompt_tokens: 10, + completion_tokens: 20, + total_tokens: 30, + }, + }), + ); + }); + + it('should convert OpenAI messages to LangChain format', async () => { + const mockResponse = new AIMessage({ content: 'Response' }); + anthropicInvokeMock.mockResolvedValueOnce(mockResponse); + + const dispatcher = new ProviderDispatcher( + { + name: 'claude', + provider: 'anthropic', + apiKey: 'test-api-key', + model: 'claude-3-5-sonnet-latest', + }, + new RemoteTools(apiKeys), + ); + + await dispatcher.dispatch({ + tools: [], + messages: [ + { role: 'system', content: 'You are helpful' }, + { role: 'user', content: 'Hello' }, + { role: 'assistant', content: 'Hi there' }, + ], + } as unknown as DispatchBody); + + expect(anthropicInvokeMock).toHaveBeenCalledWith([ + expect.objectContaining({ content: 'You are helpful' }), + expect.objectContaining({ content: 'Hello' }), + expect.objectContaining({ content: 'Hi there' }), + ]); + }); + + it('should convert assistant messages with tool_calls correctly', async () => { + const mockResponse = new AIMessage({ content: 'Done' }); + anthropicInvokeMock.mockResolvedValueOnce(mockResponse); + + const dispatcher = new ProviderDispatcher( + { + name: 'claude', + provider: 'anthropic', + apiKey: 'test-api-key', + model: 'claude-3-5-sonnet-latest', + }, + new RemoteTools(apiKeys), + ); + + await dispatcher.dispatch({ + tools: [], + messages: [ + { + role: 'assistant', + content: '', + tool_calls: [ + { + id: 'call_123', + function: { name: 'get_weather', arguments: '{"city":"Paris"}' }, + }, + ], + }, + { role: 'tool', content: 'Sunny', tool_call_id: 'call_123' }, + ], + } as unknown as DispatchBody); + + expect(anthropicInvokeMock).toHaveBeenCalledWith([ + expect.objectContaining({ + content: '', + tool_calls: [{ id: 'call_123', name: 'get_weather', args: { city: 'Paris' } }], + }), + expect.objectContaining({ content: 'Sunny', tool_call_id: 'call_123' }), + ]); + }); + + it('should return tool_calls in OpenAI format when Claude calls tools', async () => { + const mockResponse = new AIMessage({ + content: '', + tool_calls: [{ id: 'call_456', name: 'search', args: { query: 'test' } }], + }); + anthropicInvokeMock.mockResolvedValueOnce(mockResponse); + + const dispatcher = new ProviderDispatcher( + { + name: 'claude', + provider: 'anthropic', + apiKey: 'test-api-key', + model: 'claude-3-5-sonnet-latest', + }, + new RemoteTools(apiKeys), + ); + + const response = (await dispatcher.dispatch({ + tools: [], + messages: [{ role: 'user', content: 'Search for test' }], + } as unknown as DispatchBody)) as { + choices: Array<{ message: { tool_calls: unknown[] }; finish_reason: string }>; + }; + + expect(response.choices[0].message.tool_calls).toEqual([ + { + id: 'call_456', + type: 'function', + function: { name: 'search', arguments: '{"query":"test"}' }, + }, + ]); + expect(response.choices[0].finish_reason).toBe('tool_calls'); + }); + }); + + describe('when tools are provided', () => { + it('should bind tools to the client', async () => { + const mockResponse = new AIMessage({ content: 'Response' }); + anthropicInvokeMock.mockResolvedValueOnce(mockResponse); + + const dispatcher = new ProviderDispatcher( + { + name: 'claude', + provider: 'anthropic', + apiKey: 'test-api-key', + model: 'claude-3-5-sonnet-latest', + }, + new RemoteTools(apiKeys), + ); + + await dispatcher.dispatch({ + tools: [ + { + type: 'function', + function: { + name: 'get_weather', + description: 'Get weather for a city', + parameters: { type: 'object', properties: { city: { type: 'string' } } }, + }, + }, + ], + messages: [{ role: 'user', content: 'What is the weather in Paris?' }], + tool_choice: 'auto', + } as unknown as DispatchBody); + + expect(anthropicBindToolsMock).toHaveBeenCalledWith( + [ + { + type: 'function', + function: { + name: 'get_weather', + description: 'Get weather for a city', + parameters: { type: 'object', properties: { city: { type: 'string' } } }, + }, + }, + ], + { tool_choice: 'auto' }, + ); + }); + + it('should convert tool_choice "required" to "any"', async () => { + const mockResponse = new AIMessage({ content: 'Response' }); + anthropicInvokeMock.mockResolvedValueOnce(mockResponse); + + const dispatcher = new ProviderDispatcher( + { + name: 'claude', + provider: 'anthropic', + apiKey: 'test-api-key', + model: 'claude-3-5-sonnet-latest', + }, + new RemoteTools(apiKeys), + ); + + await dispatcher.dispatch({ + tools: [{ type: 'function', function: { name: 'tool1' } }], + messages: [], + tool_choice: 'required', + } as unknown as DispatchBody); + + expect(anthropicBindToolsMock).toHaveBeenCalledWith(expect.anything(), { + tool_choice: 'any', + }); + }); + + it('should convert specific function tool_choice to Anthropic format', async () => { + const mockResponse = new AIMessage({ content: 'Response' }); + anthropicInvokeMock.mockResolvedValueOnce(mockResponse); + + const dispatcher = new ProviderDispatcher( + { + name: 'claude', + provider: 'anthropic', + apiKey: 'test-api-key', + model: 'claude-3-5-sonnet-latest', + }, + new RemoteTools(apiKeys), + ); + + await dispatcher.dispatch({ + tools: [{ type: 'function', function: { name: 'specific_tool' } }], + messages: [], + tool_choice: { type: 'function', function: { name: 'specific_tool' } }, + } as unknown as DispatchBody); + + expect(anthropicBindToolsMock).toHaveBeenCalledWith(expect.anything(), { + tool_choice: { type: 'tool', name: 'specific_tool' }, + }); + }); + }); + + describe('when the anthropic client throws an error', () => { + it('should throw an AnthropicUnprocessableError', async () => { + anthropicInvokeMock.mockRejectedValueOnce(new Error('Anthropic API error')); + + const dispatcher = new ProviderDispatcher( + { + name: 'claude', + provider: 'anthropic', + apiKey: 'test-api-key', + model: 'claude-3-5-sonnet-latest', + }, + new RemoteTools(apiKeys), + ); + + await expect( + dispatcher.dispatch({ + tools: [], + messages: [{ role: 'user', content: 'Hello' }], + } as unknown as DispatchBody), + ).rejects.toThrow(AnthropicUnprocessableError); + }); + + it('should include the error message from Anthropic', async () => { + anthropicInvokeMock.mockRejectedValueOnce(new Error('Anthropic API error')); + + const dispatcher = new ProviderDispatcher( + { + name: 'claude', + provider: 'anthropic', + apiKey: 'test-api-key', + model: 'claude-3-5-sonnet-latest', + }, + new RemoteTools(apiKeys), + ); + + await expect( + dispatcher.dispatch({ + tools: [], + messages: [{ role: 'user', content: 'Hello' }], + } as unknown as DispatchBody), + ).rejects.toThrow('Error while calling Anthropic: Anthropic API error'); + }); + }); + + describe('when there is a remote tool', () => { + it('should enhance the remote tools definition', async () => { + const mockResponse = new AIMessage({ content: 'Response' }); + anthropicInvokeMock.mockResolvedValueOnce(mockResponse); + + const remoteTools = new RemoteTools(apiKeys); + + const dispatcher = new ProviderDispatcher( + { + name: 'claude', + provider: 'anthropic', + apiKey: 'test-api-key', + model: 'claude-3-5-sonnet-latest', + }, + remoteTools, + ); + + await dispatcher.dispatch({ + tools: [ + { + type: 'function', + function: { name: remoteTools.tools[0].base.name, parameters: {} }, + }, + ], + messages: [], + } as unknown as DispatchBody); + + const expectedEnhancedFunction = convertToOpenAIFunction(remoteTools.tools[0].base); + expect(anthropicBindToolsMock).toHaveBeenCalledWith( + [ + { + type: 'function', + function: { + name: expectedEnhancedFunction.name, + description: expectedEnhancedFunction.description, + parameters: expectedEnhancedFunction.parameters, + }, + }, + ], + expect.anything(), + ); + }); + }); + }); }); describe('isModelSupportingTools', () => { diff --git a/yarn.lock b/yarn.lock index 01b570575..a215711dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8,12 +8,12 @@ integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== "@actions/core@^2.0.0": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@actions/core/-/core-2.0.2.tgz#81c59e1f3437660d2148a064c1ba8e99931f2cf7" - integrity sha512-Ast1V7yHbGAhplAsuVlnb/5J8Mtr/Zl6byPPL+Qjq3lmfIgWF1ak1iYfF/079cRERiuTALTXkSuEUdZeDCfGtA== + version "2.0.1" + resolved "https://registry.yarnpkg.com/@actions/core/-/core-2.0.1.tgz#fc4961acb04f6253bcdf83ad356e013ba29fc218" + integrity sha512-oBfqT3GwkvLlo1fjvhQLQxuwZCGTarTE5OuZ2Wg10hvhBj7LRIlF611WT4aZS6fDhO5ZKlY7lCAZTlpmyaHaeg== dependencies: "@actions/exec" "^2.0.0" - "@actions/http-client" "^3.0.1" + "@actions/http-client" "^3.0.0" "@actions/exec@^2.0.0": version "2.0.0" @@ -22,10 +22,10 @@ dependencies: "@actions/io" "^2.0.0" -"@actions/http-client@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@actions/http-client/-/http-client-3.0.1.tgz#0ac91c3abf179a401e23d40abf0d7caa92324268" - integrity sha512-SbGS8c/vySbNO3kjFgSW77n83C4MQx/Yoe+b1hAdpuvfHxnkHzDq2pWljUpAA56Si1Gae/7zjeZsV0CYjmLo/w== +"@actions/http-client@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@actions/http-client/-/http-client-3.0.0.tgz#6c6058bef29c0580d6683a08c5bf0362c90c2e6e" + integrity sha512-1s3tXAfVMSz9a4ZEBkXXRQD4QhY3+GAsWSbaYpeknPOKEeyRiU3lH+bHiLMZdo2x/fIeQ/hscL1wCkDLVM2DZQ== dependencies: tunnel "^0.0.6" undici "^5.28.5" @@ -43,6 +43,13 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" +"@anthropic-ai/sdk@^0.65.0": + version "0.65.0" + resolved "https://registry.yarnpkg.com/@anthropic-ai/sdk/-/sdk-0.65.0.tgz#3f464fe2029eacf8e7e7fb8197579d00c8ca7502" + integrity sha512-zIdPOcrCVEI8t3Di40nH4z9EoeyGZfXbYSvWdDLsB/KkaSYMnEgC7gmcgWu83g2NTn1ZTpbMvpdttWDGGIk6zw== + dependencies: + json-schema-to-ts "^3.1.1" + "@aws-crypto/crc32@3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@aws-crypto/crc32/-/crc32-3.0.0.tgz#07300eca214409c33e3ff769cd5697b57fdd38fa" @@ -1045,16 +1052,7 @@ "@babel/highlight" "^7.22.13" chalk "^2.4.2" -"@babel/code-frame@^7.26.2", "@babel/code-frame@^7.28.6": - version "7.28.6" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.28.6.tgz#72499312ec58b1e2245ba4a4f550c132be4982f7" - integrity sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q== - dependencies: - "@babel/helper-validator-identifier" "^7.28.5" - js-tokens "^4.0.0" - picocolors "^1.1.1" - -"@babel/code-frame@^7.27.1": +"@babel/code-frame@^7.26.2", "@babel/code-frame@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be" integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== @@ -1257,11 +1255,6 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8" integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== -"@babel/helper-validator-identifier@^7.28.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4" - integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q== - "@babel/helper-validator-option@^7.22.15": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" @@ -1273,12 +1266,12 @@ integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== "@babel/helpers@^7.23.2", "@babel/helpers@^7.26.10", "@babel/helpers@^7.28.4": - version "7.28.6" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.6.tgz#fca903a313ae675617936e8998b814c415cbf5d7" - integrity sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw== + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.4.tgz#fe07274742e95bdf7cf1443593eeb8926ab63827" + integrity sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w== dependencies: - "@babel/template" "^7.28.6" - "@babel/types" "^7.28.6" + "@babel/template" "^7.27.2" + "@babel/types" "^7.28.4" "@babel/highlight@^7.22.13": version "7.22.20" @@ -1301,13 +1294,6 @@ dependencies: "@babel/types" "^7.28.4" -"@babel/parser@^7.28.6": - version "7.28.6" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.6.tgz#f01a8885b7fa1e56dd8a155130226cd698ef13fd" - integrity sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ== - dependencies: - "@babel/types" "^7.28.6" - "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" @@ -1406,6 +1392,11 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" +"@babel/runtime@^7.18.3": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.6.tgz#d267a43cb1836dc4d182cce93ae75ba954ef6d2b" + integrity sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA== + "@babel/template@^7.22.15", "@babel/template@^7.3.3": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" @@ -1424,15 +1415,6 @@ "@babel/parser" "^7.27.2" "@babel/types" "^7.27.1" -"@babel/template@^7.28.6": - version "7.28.6" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.28.6.tgz#0e7e56ecedb78aeef66ce7972b082fce76a23e57" - integrity sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ== - dependencies: - "@babel/code-frame" "^7.28.6" - "@babel/parser" "^7.28.6" - "@babel/types" "^7.28.6" - "@babel/traverse@^7.23.3": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.3.tgz#26ee5f252e725aa7aca3474aa5b324eaf7908b5b" @@ -1479,14 +1461,6 @@ "@babel/helper-string-parser" "^7.27.1" "@babel/helper-validator-identifier" "^7.27.1" -"@babel/types@^7.28.6": - version "7.28.6" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.6.tgz#c3e9377f1b155005bcc4c46020e7e394e13089df" - integrity sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg== - dependencies: - "@babel/helper-string-parser" "^7.27.1" - "@babel/helper-validator-identifier" "^7.28.5" - "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -1832,19 +1806,6 @@ path-to-regexp "^6.3.0" reusify "^1.0.4" -"@forestadmin/ai-proxy@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@forestadmin/ai-proxy/-/ai-proxy-1.1.0.tgz#2e33b6d49f043f4a5d08cc6840b84dbb4d2faf32" - integrity sha512-PaARjKfpeqIiABXekF3THAqGtddlZlmA/9rmFroJDJ9vXzQqbC9kQj+Z+I01zX4QXG/iRc7ESezc1RqIBZ/wGw== - dependencies: - "@forestadmin/datasource-toolkit" "1.50.1" - "@langchain/community" "1.1.4" - "@langchain/core" "1.1.15" - "@langchain/langgraph" "^1.1.0" - "@langchain/mcp-adapters" "1.1.1" - "@langchain/openai" "1.2.2" - zod "^4.3.5" - "@forestadmin/context@1.37.1": version "1.37.1" resolved "https://registry.yarnpkg.com/@forestadmin/context/-/context-1.37.1.tgz#301486c456061d43cb653b3e8be60644edb3f71a" @@ -2420,6 +2381,14 @@ koa-compose "^4.1.0" path-to-regexp "^6.3.0" +"@langchain/anthropic@^0.3.17": + version "0.3.34" + resolved "https://registry.yarnpkg.com/@langchain/anthropic/-/anthropic-0.3.34.tgz#ff131b9b612a76d7e97d960058efe3f0ccad8179" + integrity sha512-8bOW1A2VHRCjbzdYElrjxutKNs9NSIxYRGtR+OJWVzluMqoKKh2NmmFrpPizEyqCUEG2tTq5xt6XA1lwfqMJRA== + dependencies: + "@anthropic-ai/sdk" "^0.65.0" + fast-xml-parser "^4.4.1" + "@langchain/classic@1.0.9": version "1.0.9" resolved "https://registry.yarnpkg.com/@langchain/classic/-/classic-1.0.9.tgz#bdb19539db47469370727f32e1bf63c52777426b" @@ -2474,22 +2443,22 @@ dependencies: uuid "^10.0.0" -"@langchain/langgraph-sdk@~1.5.4": - version "1.5.4" - resolved "https://registry.yarnpkg.com/@langchain/langgraph-sdk/-/langgraph-sdk-1.5.4.tgz#40caf09ebc9a5bcd192610a127e8cad659f1cce6" - integrity sha512-eSYqG875c2qvcPwdvBwQH0niTZxt6roMGc2dAWBqCbWCUiUL0X4ftYHg2OqOelsrNE3SO6faLr/m0LIPc9hDwg== +"@langchain/langgraph-sdk@~1.5.5": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@langchain/langgraph-sdk/-/langgraph-sdk-1.5.5.tgz#a84fe0f27e2ed6452a83106c3759d7673789a1f0" + integrity sha512-SyiAs6TVXPWlt/8cI9pj/43nbIvclY3ytKqUFbL5MplCUnItetEyqvH87EncxyVF5D7iJKRZRfSVYBMmOZbjbQ== dependencies: p-queue "^9.0.1" p-retry "^7.1.1" uuid "^13.0.0" "@langchain/langgraph@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@langchain/langgraph/-/langgraph-1.1.0.tgz#ef873a69db4a43c25c90fb745392d880d9d2dcbb" - integrity sha512-3n1GL0ZTtr57ZwbYvbi4Th26fwiGogmpFn8OA8UXEpBM2HcpGwcv1+c8YSBJF4XRjlcCzIlXtY+DyrNsvinc6g== + version "1.1.1" + resolved "https://registry.yarnpkg.com/@langchain/langgraph/-/langgraph-1.1.1.tgz#7acacca2e9b38c701578d3f43d549432bf3d325b" + integrity sha512-FfFiaUwc2P5cy0AyALTA72S9OuutBLy+TRQECQSkwI5H40UNF+h7HM0U28xGTfmQ6MrqzbnnpRfXRTQX4jqsUw== dependencies: "@langchain/langgraph-checkpoint" "^1.0.0" - "@langchain/langgraph-sdk" "~1.5.4" + "@langchain/langgraph-sdk" "~1.5.5" uuid "^10.0.0" "@langchain/mcp-adapters@1.1.1": @@ -2667,9 +2636,9 @@ sparse-bitfield "^3.0.3" "@mongodb-js/saslprep@^1.3.0": - version "1.4.4" - resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.4.4.tgz#34a946ff6ae142e8f2259b87f2935f8284ba874d" - integrity sha512-p7X/ytJDIdwUfFL/CLOhKgdfJe1Fa8uw9seJYvdOmnP9JBWGWHW69HkOixXS6Wy9yvGf1MbhcS6lVmrhy4jm2g== + version "1.4.5" + resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.4.5.tgz#0f53a6c5a350fbe4bfa12cc80b69e8d358f1bbc0" + integrity sha512-k64Lbyb7ycCSXHSLzxVdb2xsKGPMvYZfCICXvDsI8Z65CeWQzTEKS4YmGbnqw+U9RBvLPTsB6UCmwkgsDTGWIw== dependencies: sparse-bitfield "^3.0.3" @@ -3742,10 +3711,10 @@ resolved "https://registry.yarnpkg.com/@sigstore/core/-/core-1.1.0.tgz#5583d8f7ffe599fa0a89f2bf289301a5af262380" integrity sha512-JzBqdVIyqm2FRQCulY6nbQzMpJJpSiJ8XXWMhtOX9eKgaXXpfNOF53lzQEjIydlStnd/eFtuC1dW4VYdD93oRg== -"@sigstore/core@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@sigstore/core/-/core-3.1.0.tgz#b418de73f56333ad9e369b915173d8c98e9b96d5" - integrity sha512-o5cw1QYhNQ9IroioJxpzexmPjfCe7gzafd2RY3qnMpxr4ZEja+Jad/U8sgFpaue6bOaF+z7RVkyKVV44FN+N8A== +"@sigstore/core@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@sigstore/core/-/core-3.0.0.tgz#42f42f733596f26eb055348635098fa28676f117" + integrity sha512-NgbJ+aW9gQl/25+GIEGYcCyi8M+ng2/5X04BMuIgoDfgvp18vDcoNHOQjQsG9418HGNYRxG3vfEXaR1ayD37gg== "@sigstore/protobuf-specs@^0.3.2": version "0.3.3" @@ -3769,16 +3738,16 @@ proc-log "^4.2.0" promise-retry "^2.0.1" -"@sigstore/sign@^4.1.0": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@sigstore/sign/-/sign-4.1.0.tgz#63df15a137337b29f463a1d1c51e1f7d4c1db2f1" - integrity sha512-Vx1RmLxLGnSUqx/o5/VsCjkuN5L7y+vxEEwawvc7u+6WtX2W4GNa7b9HEjmcRWohw/d6BpATXmvOwc78m+Swdg== +"@sigstore/sign@^4.0.0": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@sigstore/sign/-/sign-4.0.1.tgz#36ed397d0528e4da880b9060e26234098de5d35b" + integrity sha512-KFNGy01gx9Y3IBPG/CergxR9RZpN43N+lt3EozEfeoyqm8vEiLxwRl3ZO5sPx3Obv1ix/p7FWOlPc2Jgwfp9PA== dependencies: "@sigstore/bundle" "^4.0.0" - "@sigstore/core" "^3.1.0" + "@sigstore/core" "^3.0.0" "@sigstore/protobuf-specs" "^0.5.0" - make-fetch-happen "^15.0.3" - proc-log "^6.1.0" + make-fetch-happen "^15.0.2" + proc-log "^5.0.0" promise-retry "^2.0.1" "@sigstore/tuf@^2.3.4": @@ -3789,13 +3758,13 @@ "@sigstore/protobuf-specs" "^0.3.2" tuf-js "^2.2.1" -"@sigstore/tuf@^4.0.0", "@sigstore/tuf@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@sigstore/tuf/-/tuf-4.0.1.tgz#9b080390936d79ea3b6a893b64baf3123e92d6d3" - integrity sha512-OPZBg8y5Vc9yZjmWCHrlWPMBqW5yd8+wFNl+thMdtcWz3vjVSoJQutF8YkrzI0SLGnkuFof4HSsWUhXrf219Lw== +"@sigstore/tuf@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@sigstore/tuf/-/tuf-4.0.0.tgz#8b3ae2bd09e401386d5b6842a46839e8ff484e6c" + integrity sha512-0QFuWDHOQmz7t66gfpfNO6aEjoFrdhkJaej/AOqb4kqWZVbPWFZifXZzkxyQBB1OwTbkhdT3LNpMFxwkTvf+2w== dependencies: "@sigstore/protobuf-specs" "^0.5.0" - tuf-js "^4.1.0" + tuf-js "^4.0.0" "@sigstore/verify@^1.2.1": version "1.2.1" @@ -3806,13 +3775,13 @@ "@sigstore/core" "^1.1.0" "@sigstore/protobuf-specs" "^0.3.2" -"@sigstore/verify@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@sigstore/verify/-/verify-3.1.0.tgz#4046d4186421db779501fe87fa5acaa5d4d21b08" - integrity sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag== +"@sigstore/verify@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@sigstore/verify/-/verify-3.0.0.tgz#59a1ffa98246f8b3f91a17459e3532095ee7fbb7" + integrity sha512-moXtHH33AobOhTZF8xcX1MpOFqdvfCk7v6+teJL8zymBiDXwEsQH6XG9HGx2VIxnJZNm4cNSzflTLDnQLmIdmw== dependencies: "@sigstore/bundle" "^4.0.0" - "@sigstore/core" "^3.1.0" + "@sigstore/core" "^3.0.0" "@sigstore/protobuf-specs" "^0.5.0" "@sinclair/typebox@^0.27.8": @@ -4616,13 +4585,13 @@ "@tufjs/canonical-json" "2.0.0" minimatch "^9.0.4" -"@tufjs/models@4.1.0": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@tufjs/models/-/models-4.1.0.tgz#494b39cf5e2f6855d80031246dd236d8086069b3" - integrity sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww== +"@tufjs/models@4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@tufjs/models/-/models-4.0.0.tgz#91fa6608413bb2d593c87d8aaf8bfbf7f7a79cb8" + integrity sha512-h5x5ga/hh82COe+GoD4+gKUeV4T3iaYOxqLt41GRKApinPI7DMidhCmNVTjKfhCWFJIGXaFJee07XczdT4jdZQ== dependencies: "@tufjs/canonical-json" "2.0.0" - minimatch "^10.1.1" + minimatch "^9.0.5" "@tybys/wasm-util@^0.9.0": version "0.9.0" @@ -6148,24 +6117,6 @@ body-parser@1.20.3: type-is "~1.6.18" unpipe "1.0.0" -body-parser@~1.20.3: - version "1.20.4" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.4.tgz#f8e20f4d06ca8a50a71ed329c15dccad1cdc547f" - integrity sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA== - dependencies: - bytes "~3.1.2" - content-type "~1.0.5" - debug "2.6.9" - depd "2.0.0" - destroy "~1.2.0" - http-errors "~2.0.1" - iconv-lite "~0.4.24" - on-finished "~2.4.1" - qs "~6.14.0" - raw-body "~2.5.3" - type-is "~1.6.18" - unpipe "~1.0.0" - boolbase@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" @@ -7001,7 +6952,7 @@ console-table-printer@^2.12.1: dependencies: simple-wcswidth "^1.1.2" -content-disposition@^0.5.3, content-disposition@~0.5.2, content-disposition@~0.5.4: +content-disposition@0.5.4, content-disposition@^0.5.3, content-disposition@~0.5.2, content-disposition@~0.5.4: version "0.5.4" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== @@ -7139,10 +7090,15 @@ convert-source-map@^2.0.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== -cookie-signature@~1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.7.tgz#ab5dd7ab757c54e60f37ef6550f481c426d10454" - integrity sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA== +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9" + integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w== cookie@^0.4.0: version "0.4.2" @@ -7154,7 +7110,7 @@ cookie@^0.5.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== -cookie@^0.7.0, cookie@~0.7.1: +cookie@^0.7.0: version "0.7.2" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== @@ -7367,7 +7323,7 @@ debug@^3.2.6, debug@^3.2.7: dependencies: ms "^2.1.1" -debug@^4.3.1, debug@^4.4.3: +debug@^4.3.1, debug@^4.4.1, debug@^4.4.3: version "4.4.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== @@ -7512,7 +7468,7 @@ deprecation@^2.0.0: resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== -destroy@1.2.0, destroy@^1.0.4, destroy@^1.2.0, destroy@~1.2.0: +destroy@1.2.0, destroy@^1.0.4, destroy@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== @@ -7561,9 +7517,9 @@ diff@^4.0.1: integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== diff@^8.0.2: - version "8.0.3" - resolved "https://registry.yarnpkg.com/diff/-/diff-8.0.3.tgz#c7da3d9e0e8c283bb548681f8d7174653720c2d5" - integrity sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ== + version "8.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-8.0.2.tgz#712156a6dd288e66ebb986864e190c2fc9eddfae" + integrity sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg== dir-glob@^3.0.0, dir-glob@^3.0.1: version "3.0.1" @@ -7747,7 +7703,7 @@ emojilib@^2.4.0: resolved "https://registry.yarnpkg.com/emojilib/-/emojilib-2.4.0.tgz#ac518a8bb0d5f76dda57289ccb2fdf9d39ae721e" integrity sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw== -encodeurl@^1.0.2: +encodeurl@^1.0.2, encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== @@ -8528,38 +8484,38 @@ express-rate-limit@^7.5.0: integrity sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw== express@4.21.2, express@5.1.0, express@^4.17.1, express@^4.18.2, express@^4.21.1, express@^5.0.1, express@^5.2.1: - version "4.22.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.22.1.tgz#1de23a09745a4fffdb39247b344bb5eaff382069" - integrity sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g== + version "4.21.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.21.2.tgz#cf250e48362174ead6cea4a566abef0162c1ec32" + integrity sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "~1.20.3" - content-disposition "~0.5.4" + body-parser "1.20.3" + content-disposition "0.5.4" content-type "~1.0.4" - cookie "~0.7.1" - cookie-signature "~1.0.6" + cookie "0.7.1" + cookie-signature "1.0.6" debug "2.6.9" depd "2.0.0" encodeurl "~2.0.0" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "~1.3.1" - fresh "~0.5.2" - http-errors "~2.0.0" + finalhandler "1.3.1" + fresh "0.5.2" + http-errors "2.0.0" merge-descriptors "1.0.3" methods "~1.1.2" - on-finished "~2.4.1" + on-finished "2.4.1" parseurl "~1.3.3" - path-to-regexp "~0.1.12" + path-to-regexp "0.1.12" proxy-addr "~2.0.7" - qs "~6.14.0" + qs "6.13.0" range-parser "~1.2.1" safe-buffer "5.2.1" - send "~0.19.0" - serve-static "~1.16.2" + send "0.19.0" + serve-static "1.16.2" setprototypeof "1.2.0" - statuses "~2.0.1" + statuses "2.0.1" type-is "~1.6.18" utils-merge "1.0.1" vary "~1.1.2" @@ -8738,6 +8694,13 @@ fast-xml-parser@4.4.1: dependencies: strnum "^1.0.5" +fast-xml-parser@^4.4.1: + version "4.5.3" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz#c54d6b35aa0f23dc1ea60b6c884340c006dc6efb" + integrity sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig== + dependencies: + strnum "^1.1.1" + fastest-levenshtein@^1.0.16, fastest-levenshtein@^1.0.7: version "1.0.16" resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" @@ -8926,17 +8889,17 @@ fill-range@^7.1.1: dependencies: to-regex-range "^5.0.1" -finalhandler@~1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.2.tgz#1ebc2228fc7673aac4a472c310cc05b77d852b88" - integrity sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg== +finalhandler@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.1.tgz#0c575f1d1d324ddd1da35ad7ece3df7d19088019" + integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ== dependencies: debug "2.6.9" encodeurl "~2.0.0" escape-html "~1.0.3" - on-finished "~2.4.1" + on-finished "2.4.1" parseurl "~1.3.3" - statuses "~2.0.2" + statuses "2.0.1" unpipe "~1.0.0" find-my-way@^2.2.2: @@ -9148,7 +9111,7 @@ forwarded@0.2.0: resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== -fresh@^0.5.2, fresh@~0.5.2: +fresh@0.5.2, fresh@^0.5.2, fresh@~0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== @@ -9940,7 +9903,7 @@ http-errors@^1.6.3, http-errors@~1.8.0: statuses ">= 1.5.0 < 2" toidentifier "1.0.1" -http-errors@~2.0.0, http-errors@~2.0.1: +http-errors@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.1.tgz#36d2f65bc909c8790018dd36fb4d93da6caae06b" integrity sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ== @@ -10046,7 +10009,7 @@ hyperlinker@^1.0.0: resolved "https://registry.yarnpkg.com/hyperlinker/-/hyperlinker-1.0.0.tgz#23dc9e38a206b208ee49bc2d6c8ef47027df0c0e" integrity sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ== -iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@~0.4.24: +iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -11499,6 +11462,14 @@ json-schema-ref-resolver@^1.0.1: dependencies: fast-deep-equal "^3.1.3" +json-schema-to-ts@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz#81f3acaf5a34736492f6f5f51870ef9ece1ca853" + integrity sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g== + dependencies: + "@babel/runtime" "^7.18.3" + ts-algebra "^2.0.0" + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -11804,9 +11775,9 @@ koa@^3.0.1: vary "^1.1.2" "langsmith@>=0.4.0 <1.0.0": - version "0.4.7" - resolved "https://registry.yarnpkg.com/langsmith/-/langsmith-0.4.7.tgz#054232706d6b55518b20cff654fc3f91acb07e5f" - integrity sha512-Esv5g/J8wwRwbGQr10PB9+bLsNk0mWbrXc7nnEreQDhh0azbU57I7epSnT7GC4sS4EOWavhbxk+6p8PTXtreHw== + version "0.4.8" + resolved "https://registry.yarnpkg.com/langsmith/-/langsmith-0.4.8.tgz#846626dd2e8eba5a1ef0cf17f0c1e38de2fdd13e" + integrity sha512-zyhQ4zp/TJqITfoQvtk8ehUmdIkxj24dTA76nEnMw63lb04/JKZgs29r/epH1pmEwbt0nUlQWKlE8n2g6BabUA== dependencies: "@types/uuid" "^10.0.0" chalk "^4.1.2" @@ -12460,7 +12431,7 @@ make-fetch-happen@^13.0.0, make-fetch-happen@^13.0.1: promise-retry "^2.0.1" ssri "^10.0.0" -make-fetch-happen@^15.0.0, make-fetch-happen@^15.0.1, make-fetch-happen@^15.0.3: +make-fetch-happen@^15.0.0, make-fetch-happen@^15.0.2, make-fetch-happen@^15.0.3: version "15.0.3" resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-15.0.3.tgz#1578d72885f2b3f9e5daa120b36a14fc31a84610" integrity sha512-iyyEpDty1mwW3dGlYXAJqC/azFn5PPvgKVwXayOGBSmKLxhKZ9fg4qIan2ePpp1vJIwfFiO34LAPZgq9SZW9Aw== @@ -14063,7 +14034,7 @@ on-exit-leak-free@^2.1.0: resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz#fed195c9ebddb7d9e4c3842f93f281ac8dadd3b8" integrity sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA== -on-finished@2.4.1, on-finished@^2.3.0, on-finished@^2.4.1, on-finished@~2.4.1: +on-finished@2.4.1, on-finished@^2.3.0, on-finished@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== @@ -14679,6 +14650,11 @@ path-scurry@^2.0.0: lru-cache "^11.0.0" minipass "^7.1.2" +path-to-regexp@0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7" + integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ== + path-to-regexp@3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-3.3.0.tgz#f7f31d32e8518c2660862b644414b6d5c63a611b" @@ -14694,11 +14670,6 @@ path-to-regexp@^6.3.0: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.3.0.tgz#2b6a26a337737a8e1416f9272ed0766b1c0389f4" integrity sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ== -path-to-regexp@~0.1.12: - version "0.1.12" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7" - integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ== - path-type@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" @@ -15063,6 +15034,11 @@ proc-log@^4.0.0, proc-log@^4.1.0, proc-log@^4.2.0: resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-4.2.0.tgz#b6f461e4026e75fdfe228b265e9f7a00779d7034" integrity sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA== +proc-log@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-5.0.0.tgz#e6c93cf37aef33f835c53485f314f50ea906a9d8" + integrity sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ== + proc-log@^6.0.0, proc-log@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-6.1.0.tgz#18519482a37d5198e231133a70144a50f21f0215" @@ -15245,13 +15221,6 @@ qs@^6.11.2: dependencies: side-channel "^1.1.0" -qs@~6.14.0: - version "6.14.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.1.tgz#a41d85b9d3902f31d27861790506294881871159" - integrity sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ== - dependencies: - side-channel "^1.1.0" - queue-microtask@^1.1.2, queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -15317,16 +15286,6 @@ raw-body@^3.0.0: iconv-lite "~0.7.0" unpipe "~1.0.0" -raw-body@~2.5.3: - version "2.5.3" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.3.tgz#11c6650ee770a7de1b494f197927de0c923822e2" - integrity sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA== - dependencies: - bytes "~3.1.2" - http-errors "~2.0.1" - iconv-lite "~0.4.24" - unpipe "~1.0.0" - rc@^1.2.7, rc@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" @@ -15970,24 +15929,24 @@ semver@^7.6.3: resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f" integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA== -send@~0.19.0, send@~0.19.1: - version "0.19.2" - resolved "https://registry.yarnpkg.com/send/-/send-0.19.2.tgz#59bc0da1b4ea7ad42736fd642b1c4294e114ff29" - integrity sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg== +send@0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" + integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== dependencies: debug "2.6.9" depd "2.0.0" destroy "1.2.0" - encodeurl "~2.0.0" + encodeurl "~1.0.2" escape-html "~1.0.3" etag "~1.8.1" - fresh "~0.5.2" - http-errors "~2.0.1" + fresh "0.5.2" + http-errors "2.0.0" mime "1.6.0" ms "2.1.3" - on-finished "~2.4.1" + on-finished "2.4.1" range-parser "~1.2.1" - statuses "~2.0.2" + statuses "2.0.1" seq-queue@^0.0.5: version "0.0.5" @@ -16043,15 +16002,15 @@ sequelize@^6.37.7: validator "^13.9.0" wkx "^0.5.0" -serve-static@~1.16.2: - version "1.16.3" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.3.tgz#a97b74d955778583f3862a4f0b841eb4d5d78cf9" - integrity sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA== +serve-static@1.16.2: + version "1.16.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296" + integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== dependencies: encodeurl "~2.0.0" escape-html "~1.0.3" parseurl "~1.3.3" - send "~0.19.1" + send "0.19.0" set-blocking@^2.0.0: version "2.0.0" @@ -16267,16 +16226,16 @@ sigstore@^2.2.0: "@sigstore/verify" "^1.2.1" sigstore@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/sigstore/-/sigstore-4.1.0.tgz#d34b92a544a05e003a2430209d26d8dfafd805a0" - integrity sha512-/fUgUhYghuLzVT/gaJoeVehLCgZiUxPCPMcyVNY0lIf/cTCz58K/WTI7PefDarXxp9nUKpEwg1yyz3eSBMTtgA== + version "4.0.0" + resolved "https://registry.yarnpkg.com/sigstore/-/sigstore-4.0.0.tgz#cc260814a95a6027c5da24b819d5c11334af60f9" + integrity sha512-Gw/FgHtrLM9WP8P5lLcSGh9OQcrTruWCELAiS48ik1QbL0cH+dfjomiRTUE9zzz+D1N6rOLkwXUvVmXZAsNE0Q== dependencies: "@sigstore/bundle" "^4.0.0" - "@sigstore/core" "^3.1.0" + "@sigstore/core" "^3.0.0" "@sigstore/protobuf-specs" "^0.5.0" - "@sigstore/sign" "^4.1.0" - "@sigstore/tuf" "^4.0.1" - "@sigstore/verify" "^3.1.0" + "@sigstore/sign" "^4.0.0" + "@sigstore/tuf" "^4.0.0" + "@sigstore/verify" "^3.0.0" simple-concat@^1.0.0: version "1.0.1" @@ -16615,7 +16574,7 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -statuses@^2.0.1, statuses@~2.0.1, statuses@~2.0.2: +statuses@^2.0.1, statuses@~2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.2.tgz#8f75eecef765b5e1cfcdc080da59409ed424e382" integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== @@ -16874,6 +16833,11 @@ strnum@^1.0.5: resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db" integrity sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA== +strnum@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.1.2.tgz#57bca4fbaa6f271081715dbc9ed7cee5493e28e4" + integrity sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA== + strtok3@^6.2.4: version "6.3.0" resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.3.0.tgz#358b80ffe6d5d5620e19a073aa78ce947a90f9a0" @@ -17300,6 +17264,11 @@ trough@^1.0.0: resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== +ts-algebra@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ts-algebra/-/ts-algebra-2.0.0.tgz#4e3e0953878f26518fce7f6bb115064a65388b7a" + integrity sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw== + ts-invariant@^0.4.0: version "0.4.4" resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.4.4.tgz#97a523518688f93aafad01b0e80eb803eb2abd86" @@ -17409,14 +17378,14 @@ tuf-js@^2.2.1: debug "^4.3.4" make-fetch-happen "^13.0.1" -tuf-js@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/tuf-js/-/tuf-js-4.1.0.tgz#ae4ef9afa456fcb4af103dc50a43bc031f066603" - integrity sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ== +tuf-js@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tuf-js/-/tuf-js-4.0.0.tgz#dbfc7df8b4e04fd6a0c598678a8c789a3e5f9c27" + integrity sha512-Lq7ieeGvXDXwpoSmOSgLWVdsGGV9J4a77oDTAPe/Ltrqnnm/ETaRlBAQTH5JatEh8KXuE6sddf9qAv1Q2282Hg== dependencies: - "@tufjs/models" "4.1.0" - debug "^4.4.3" - make-fetch-happen "^15.0.1" + "@tufjs/models" "4.0.0" + debug "^4.4.1" + make-fetch-happen "^15.0.0" tunnel-agent@^0.6.0: version "0.6.0" @@ -17505,9 +17474,9 @@ type-fest@^4.39.1, type-fest@^4.6.0: integrity sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA== type-fest@^5.2.0: - version "5.4.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-5.4.1.tgz#aa9eaadcdc0acb0b5bd52e54f966ee3e38e125d2" - integrity sha512-xygQcmneDyzsEuKZrFbRMne5HDqMs++aFzefrJTgEIKjQ3rekM+RPfFCVq2Gp1VIDqddoYeppCj4Pcb+RZW0GQ== + version "5.3.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-5.3.1.tgz#251b8d0a813c1dbccf1f9450ba5adcdf7072adc2" + integrity sha512-VCn+LMHbd4t6sF3wfU/+HKT63C9OoyrSIf4b+vtWHpt2U7/4InZG467YDNMFMR70DdHjAdpPWmw2lzRdg0Xqqg== dependencies: tagged-tag "^1.0.0" @@ -17772,9 +17741,9 @@ undici@^5.28.5: "@fastify/busboy" "^2.0.0" undici@^7.0.0: - version "7.18.2" - resolved "https://registry.yarnpkg.com/undici/-/undici-7.18.2.tgz#6cf724ef799a67d94fd55adf66b1e184176efcdf" - integrity sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw== + version "7.16.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-7.16.0.tgz#cb2a1e957726d458b536e3f076bf51f066901c1a" + integrity sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g== unicode-emoji-modifier-base@^1.0.0: version "1.0.0" @@ -18023,9 +17992,9 @@ validate-npm-package-name@^5.0.0: builtins "^5.0.0" validate-npm-package-name@^7.0.0: - version "7.0.2" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-7.0.2.tgz#e57c3d721a4c8bbff454a246e7f7da811559ea0d" - integrity sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A== + version "7.0.0" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-7.0.0.tgz#3b4fe12b4abfb8b0be010d0e75b1fe2b52295bc6" + integrity sha512-bwVk/OK+Qu108aJcMAEiU4yavHUI7aN20TgZNBj9MR2iU1zPUl1Z1Otr7771ExfYTPTvfN8ZJ1pbr5Iklgt4xg== validator@^13.9.0: version "13.11.0" @@ -18518,9 +18487,9 @@ zod@^4.2.1: integrity sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw== zod@^4.3.5: - version "4.3.5" - resolved "https://registry.yarnpkg.com/zod/-/zod-4.3.5.tgz#aeb269a6f9fc259b1212c348c7c5432aaa474d2a" - integrity sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g== + version "4.3.6" + resolved "https://registry.yarnpkg.com/zod/-/zod-4.3.6.tgz#89c56e0aa7d2b05107d894412227087885ab112a" + integrity sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg== zwitch@^1.0.0: version "1.0.5" From 482f6b8c47c498e5365e141a66ad4099ffb414fa Mon Sep 17 00:00:00 2001 From: alban bertolini Date: Fri, 23 Jan 2026 16:19:21 +0100 Subject: [PATCH 2/2] fix(ai-proxy): handle null content and JSON parse errors in Anthropic dispatcher - Move convertMessagesToLangChain inside try-catch to properly handle JSON.parse errors - Update OpenAIMessage interface to allow null content (per OpenAI API spec) - Add null content handling for all message types with fallback to empty string Co-Authored-By: Claude Opus 4.5 --- packages/ai-proxy/src/provider-dispatcher.ts | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/ai-proxy/src/provider-dispatcher.ts b/packages/ai-proxy/src/provider-dispatcher.ts index 8aed5e189..040e0a35e 100644 --- a/packages/ai-proxy/src/provider-dispatcher.ts +++ b/packages/ai-proxy/src/provider-dispatcher.ts @@ -114,7 +114,7 @@ export type DispatchBody = { interface OpenAIMessage { role: 'system' | 'user' | 'assistant' | 'tool'; - content: string; + content: string | null; tool_calls?: Array<{ id: string; function: { @@ -204,10 +204,9 @@ export class ProviderDispatcher { private async dispatchAnthropic(body: DispatchBody): Promise { const { tools, messages, tool_choice: toolChoice } = body; - const langChainMessages = this.convertMessagesToLangChain(messages as OpenAIMessage[]); - const enhancedTools = tools ? this.enrichToolDefinitions(tools) : undefined; - try { + const langChainMessages = this.convertMessagesToLangChain(messages as OpenAIMessage[]); + const enhancedTools = tools ? this.enrichToolDefinitions(tools) : undefined; let response: AIMessage; if (enhancedTools?.length) { @@ -246,9 +245,9 @@ export class ProviderDispatcher { return messages.map(msg => { switch (msg.role) { case 'system': - return new SystemMessage(msg.content); + return new SystemMessage(msg.content || ''); case 'user': - return new HumanMessage(msg.content); + return new HumanMessage(msg.content || ''); case 'assistant': if (msg.tool_calls) { return new AIMessage({ @@ -261,14 +260,14 @@ export class ProviderDispatcher { }); } - return new AIMessage(msg.content); + return new AIMessage(msg.content || ''); case 'tool': return new ToolMessage({ - content: msg.content, + content: msg.content || '', tool_call_id: msg.tool_call_id!, }); default: - return new HumanMessage(msg.content); + return new HumanMessage(msg.content || ''); } }); }