UNPKG

@mariozechner/claude-bridge

Version:

Use non-Anthropic models with Claude Code by proxying requests through the lemmy unified interface

1,815 lines (1,789 loc) 64.4 kB
#!/usr/bin/env node // src/cli.ts import * as fs2 from "fs"; import * as os from "os"; // ../../packages/lemmy/dist/src/clients/anthropic.js import Anthropic from "@anthropic-ai/sdk"; // ../../packages/lemmy/dist/src/tools/zod-converter.js import { zodToJsonSchema } from "zod-to-json-schema"; // ../../packages/lemmy/dist/src/clients/google.js import { GoogleGenAI } from "@google/genai"; // ../../packages/lemmy/dist/src/clients/openai.js import OpenAI from "openai"; // ../../packages/lemmy/dist/src/generated/models.js var AnthropicModelData = { "claude-2.0": { contextWindow: 2e5, maxOutputTokens: 4096, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 3, outputPerMillion: 15 } }, "claude-2.1": { contextWindow: 2e5, maxOutputTokens: 4096, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 3, outputPerMillion: 15 } }, "claude-3-5-haiku-20241022": { contextWindow: 2e5, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.8, outputPerMillion: 4 } }, "claude-3-5-haiku-latest": { contextWindow: 2e5, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.8, outputPerMillion: 4 } }, "claude-3-5-sonnet-20240620": { contextWindow: 2e5, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 3, outputPerMillion: 15 } }, "claude-3-5-sonnet-20241022": { contextWindow: 2e5, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 3, outputPerMillion: 15 } }, "claude-3-5-sonnet-latest": { contextWindow: 2e5, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 3, outputPerMillion: 15 } }, "claude-3-7-sonnet-20250219": { contextWindow: 2e5, maxOutputTokens: 64e3, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 3, outputPerMillion: 15 } }, "claude-3-7-sonnet-latest": { contextWindow: 2e5, maxOutputTokens: 64e3, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 3, outputPerMillion: 15 } }, "claude-3-haiku-20240307": { contextWindow: 2e5, maxOutputTokens: 4096, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.25, outputPerMillion: 1.25 } }, "claude-3-opus-20240229": { contextWindow: 2e5, maxOutputTokens: 4096, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 15, outputPerMillion: 75 } }, "claude-3-opus-latest": { contextWindow: 2e5, maxOutputTokens: 4096, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 15, outputPerMillion: 75 } }, "claude-3-sonnet-20240229": { contextWindow: 2e5, maxOutputTokens: 4096, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 3, outputPerMillion: 15 } }, "claude-opus-4-20250514": { contextWindow: 2e5, maxOutputTokens: 32e3, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 15, outputPerMillion: 75 } }, "claude-sonnet-4-20250514": { contextWindow: 2e5, maxOutputTokens: 64e3, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 3, outputPerMillion: 15 } } }; var OpenAIModelData = { "babbage-002": { contextWindow: 0, maxOutputTokens: 16384, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.4, outputPerMillion: 0.4 } }, "chatgpt-4o-latest": { contextWindow: 128e3, maxOutputTokens: 16384, supportsTools: false, supportsImageInput: true, pricing: { inputPerMillion: 5, outputPerMillion: 15 } }, "codex-mini-latest": { contextWindow: 2e5, maxOutputTokens: 1e5, supportsTools: false, supportsImageInput: true, pricing: { inputPerMillion: 1.5, outputPerMillion: 6 } }, "computer-use-preview": { contextWindow: 8192, maxOutputTokens: 1024, supportsTools: false, supportsImageInput: true, pricing: { inputPerMillion: 3, outputPerMillion: 12 } }, "computer-use-preview-2025-03-11": { contextWindow: 8192, maxOutputTokens: 1024, supportsTools: false, supportsImageInput: true, pricing: { inputPerMillion: 3, outputPerMillion: 12 } }, "davinci-002": { contextWindow: 0, maxOutputTokens: 16384, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 2, outputPerMillion: 2 } }, "gpt-3.5-turbo": { contextWindow: 16385, maxOutputTokens: 4096, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.5, outputPerMillion: 1.5 } }, "gpt-3.5-turbo-0125": { contextWindow: 16385, maxOutputTokens: 4096, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.5, outputPerMillion: 1.5 } }, "gpt-3.5-turbo-1106": { contextWindow: 16385, maxOutputTokens: 4096, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.5, outputPerMillion: 1.5 } }, "gpt-3.5-turbo-16k": { contextWindow: 16385, maxOutputTokens: 4096, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.5, outputPerMillion: 1.5 } }, "gpt-3.5-turbo-instruct": { contextWindow: 16385, maxOutputTokens: 4096, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.5, outputPerMillion: 1.5 } }, "gpt-3.5-turbo-instruct-0914": { contextWindow: 16385, maxOutputTokens: 4096, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.5, outputPerMillion: 1.5 } }, "gpt-4": { contextWindow: 8192, maxOutputTokens: 8192, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 30, outputPerMillion: 60 } }, "gpt-4-0125-preview": { contextWindow: 4096, maxOutputTokens: 16384, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.5, outputPerMillion: 1.5 } }, "gpt-4-0613": { contextWindow: 8192, maxOutputTokens: 8192, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 30, outputPerMillion: 60 } }, "gpt-4-1106-preview": { contextWindow: 4096, maxOutputTokens: 16384, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.5, outputPerMillion: 1.5 } }, "gpt-4-turbo": { contextWindow: 128e3, maxOutputTokens: 4096, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 10, outputPerMillion: 30 } }, "gpt-4-turbo-2024-04-09": { contextWindow: 128e3, maxOutputTokens: 4096, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 10, outputPerMillion: 30 } }, "gpt-4-turbo-preview": { contextWindow: 128e3, maxOutputTokens: 4096, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 10, outputPerMillion: 30 } }, "gpt-4.1": { contextWindow: 1047576, maxOutputTokens: 32768, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 2, outputPerMillion: 8 } }, "gpt-4.1-2025-04-14": { contextWindow: 1047576, maxOutputTokens: 32768, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 2, outputPerMillion: 8 } }, "gpt-4.1-mini": { contextWindow: 1047576, maxOutputTokens: 32768, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.4, outputPerMillion: 1.6 } }, "gpt-4.1-mini-2025-04-14": { contextWindow: 1047576, maxOutputTokens: 32768, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.4, outputPerMillion: 1.6 } }, "gpt-4.1-nano": { contextWindow: 1047576, maxOutputTokens: 32768, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.1, outputPerMillion: 0.4 } }, "gpt-4.1-nano-2025-04-14": { contextWindow: 1047576, maxOutputTokens: 32768, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.1, outputPerMillion: 0.4 } }, "gpt-4.5-preview": { contextWindow: 128e3, maxOutputTokens: 4096, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 10, outputPerMillion: 30 } }, "gpt-4.5-preview-2025-02-27": { contextWindow: 128e3, maxOutputTokens: 4096, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 10, outputPerMillion: 30 } }, "gpt-4o": { contextWindow: 128e3, maxOutputTokens: 16384, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 2.5, outputPerMillion: 10 } }, "gpt-4o-2024-05-13": { contextWindow: 128e3, maxOutputTokens: 16384, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 2.5, outputPerMillion: 10 } }, "gpt-4o-2024-08-06": { contextWindow: 128e3, maxOutputTokens: 16384, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 2.5, outputPerMillion: 10 } }, "gpt-4o-2024-11-20": { contextWindow: 128e3, maxOutputTokens: 16384, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 2.5, outputPerMillion: 10 } }, "gpt-4o-audio-preview": { contextWindow: 128e3, maxOutputTokens: 16384, supportsTools: true, supportsImageInput: false, pricing: { inputPerMillion: 2.5, outputPerMillion: 10 } }, "gpt-4o-audio-preview-2024-10-01": { contextWindow: 128e3, maxOutputTokens: 16384, supportsTools: true, supportsImageInput: false, pricing: { inputPerMillion: 2.5, outputPerMillion: 10 } }, "gpt-4o-audio-preview-2024-12-17": { contextWindow: 128e3, maxOutputTokens: 16384, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 2.5, outputPerMillion: 10 } }, "gpt-4o-mini": { contextWindow: 128e3, maxOutputTokens: 16384, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.15, outputPerMillion: 0.6 } }, "gpt-4o-mini-2024-07-18": { contextWindow: 128e3, maxOutputTokens: 16384, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.15, outputPerMillion: 0.6 } }, "gpt-4o-mini-audio-preview": { contextWindow: 128e3, maxOutputTokens: 16384, supportsTools: true, supportsImageInput: false, pricing: { inputPerMillion: 0.15, outputPerMillion: 0.6 } }, "gpt-4o-mini-audio-preview-2024-12-17": { contextWindow: 128e3, maxOutputTokens: 16384, supportsTools: true, supportsImageInput: false, pricing: { inputPerMillion: 0.15, outputPerMillion: 0.6 } }, "gpt-4o-mini-realtime-preview": { contextWindow: 128e3, maxOutputTokens: 4096, supportsTools: true, supportsImageInput: false, pricing: { inputPerMillion: 0.6, outputPerMillion: 2.4 } }, "gpt-4o-mini-realtime-preview-2024-12-17": { contextWindow: 128e3, maxOutputTokens: 4096, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.6, outputPerMillion: 2.4 } }, "gpt-4o-mini-search-preview": { contextWindow: 128e3, maxOutputTokens: 16384, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.15, outputPerMillion: 0.6 } }, "gpt-4o-mini-search-preview-2025-03-11": { contextWindow: 128e3, maxOutputTokens: 16384, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.15, outputPerMillion: 0.6 } }, "gpt-4o-mini-transcribe": { contextWindow: 16e3, maxOutputTokens: 2e3, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 1.25, outputPerMillion: 5 } }, "gpt-4o-realtime-preview": { contextWindow: 128e3, maxOutputTokens: 4096, supportsTools: true, supportsImageInput: false, pricing: { inputPerMillion: 5, outputPerMillion: 20 } }, "gpt-4o-realtime-preview-2024-10-01": { contextWindow: 128e3, maxOutputTokens: 4096, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 5, outputPerMillion: 20 } }, "gpt-4o-realtime-preview-2024-12-17": { contextWindow: 128e3, maxOutputTokens: 4096, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 5, outputPerMillion: 20 } }, "gpt-4o-search-preview": { contextWindow: 128e3, maxOutputTokens: 16384, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 2.5, outputPerMillion: 10 } }, "gpt-4o-search-preview-2025-03-11": { contextWindow: 128e3, maxOutputTokens: 16384, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 2.5, outputPerMillion: 10 } }, "gpt-4o-transcribe": { contextWindow: 16e3, maxOutputTokens: 2e3, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 2.5, outputPerMillion: 10 } }, o1: { contextWindow: 2e5, maxOutputTokens: 1e5, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 15, outputPerMillion: 60 } }, "o1-2024-12-17": { contextWindow: 2e5, maxOutputTokens: 1e5, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 15, outputPerMillion: 60 } }, "o1-mini": { contextWindow: 128e3, maxOutputTokens: 65536, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 1.1, outputPerMillion: 4.4 } }, "o1-mini-2024-09-12": { contextWindow: 128e3, maxOutputTokens: 65536, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 1.1, outputPerMillion: 4.4 } }, "o1-preview": { contextWindow: 2e5, maxOutputTokens: 1e5, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 15, outputPerMillion: 60 } }, "o1-preview-2024-09-12": { contextWindow: 2e5, maxOutputTokens: 1e5, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 15, outputPerMillion: 60 } }, "o1-pro": { contextWindow: 2e5, maxOutputTokens: 1e5, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 150, outputPerMillion: 600 } }, "o1-pro-2025-03-19": { contextWindow: 2e5, maxOutputTokens: 1e5, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 150, outputPerMillion: 600 } }, o3: { contextWindow: 2e5, maxOutputTokens: 1e5, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 10, outputPerMillion: 40 } }, "o3-2025-04-16": { contextWindow: 2e5, maxOutputTokens: 1e5, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 10, outputPerMillion: 40 } }, "o3-mini": { contextWindow: 2e5, maxOutputTokens: 1e5, supportsTools: true, supportsImageInput: false, pricing: { inputPerMillion: 1.1, outputPerMillion: 4.4 } }, "o3-mini-2025-01-31": { contextWindow: 2e5, maxOutputTokens: 1e5, supportsTools: true, supportsImageInput: false, pricing: { inputPerMillion: 1.1, outputPerMillion: 4.4 } }, "o4-mini": { contextWindow: 2e5, maxOutputTokens: 1e5, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 1.1, outputPerMillion: 4.4 } }, "o4-mini-2025-04-16": { contextWindow: 2e5, maxOutputTokens: 1e5, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 1.1, outputPerMillion: 4.4 } }, "omni-moderation-2024-09-26": { contextWindow: 0, maxOutputTokens: 0, supportsTools: false, supportsImageInput: true, pricing: null }, "omni-moderation-latest": { contextWindow: 0, maxOutputTokens: 0, supportsTools: false, supportsImageInput: true, pricing: null }, "text-embedding-3-large": { contextWindow: 0, maxOutputTokens: 0, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.13, outputPerMillion: 0 } }, "text-embedding-3-small": { contextWindow: 0, maxOutputTokens: 0, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.02, outputPerMillion: 0 } }, "text-embedding-ada-002": { contextWindow: 0, maxOutputTokens: 0, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.1, outputPerMillion: 0 } }, "text-moderation-latest": { contextWindow: 0, maxOutputTokens: 32768, supportsTools: false, supportsImageInput: false, pricing: null }, "tts-1-1106": { contextWindow: 0, maxOutputTokens: 0, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 15, outputPerMillion: 15 } }, "tts-1-hd-1106": { contextWindow: 0, maxOutputTokens: 0, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 30, outputPerMillion: 30 } } }; var GoogleModelData = { aqa: { contextWindow: 7168, maxOutputTokens: 1024, supportsTools: false, supportsImageInput: false, pricing: null }, "embedding-gecko-001": { contextWindow: 1024, maxOutputTokens: 1, supportsTools: false, supportsImageInput: false, pricing: null }, "gemini-1.0-pro-vision-latest": { contextWindow: 12288, maxOutputTokens: 4096, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemini-1.5-flash": { contextWindow: 1048576, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemini-1.5-flash-001": { contextWindow: 1048576, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemini-1.5-flash-001-tuning": { contextWindow: 16384, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemini-1.5-flash-002": { contextWindow: 1048576, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemini-1.5-flash-8b": { contextWindow: 1048576, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemini-1.5-flash-8b-001": { contextWindow: 1048576, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemini-1.5-flash-8b-exp-0827": { contextWindow: 1e6, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.0375, outputPerMillion: 0.15 } }, "gemini-1.5-flash-8b-exp-0924": { contextWindow: 1e6, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.0375, outputPerMillion: 0.15 } }, "gemini-1.5-flash-8b-latest": { contextWindow: 1048576, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemini-1.5-flash-latest": { contextWindow: 1048576, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemini-1.5-pro": { contextWindow: 2097152, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 1.25, outputPerMillion: 5 } }, "gemini-1.5-pro-001": { contextWindow: 2097152, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 1.25, outputPerMillion: 5 } }, "gemini-1.5-pro-002": { contextWindow: 2097152, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 1.25, outputPerMillion: 5 } }, "gemini-1.5-pro-latest": { contextWindow: 2097152, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 1.25, outputPerMillion: 5 } }, "gemini-2.0-flash": { contextWindow: 1048576, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.1, outputPerMillion: 0.4 } }, "gemini-2.0-flash-001": { contextWindow: 1048576, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.1, outputPerMillion: 0.4 } }, "gemini-2.0-flash-exp": { contextWindow: 1048576, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.1, outputPerMillion: 0.4 } }, "gemini-2.0-flash-lite": { contextWindow: 1048576, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.1, outputPerMillion: 0.4 } }, "gemini-2.0-flash-lite-001": { contextWindow: 1048576, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.1, outputPerMillion: 0.4 } }, "gemini-2.0-flash-lite-preview": { contextWindow: 1048576, maxOutputTokens: 8192, supportsTools: false, supportsImageInput: true, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemini-2.0-flash-lite-preview-02-05": { contextWindow: 1048576, maxOutputTokens: 8192, supportsTools: false, supportsImageInput: true, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemini-2.0-flash-live-001": { contextWindow: 1048576, maxOutputTokens: 8192, supportsTools: true, supportsImageInput: false, pricing: { inputPerMillion: 0.1, outputPerMillion: 0.4 } }, "gemini-2.0-flash-preview-image-generation": { contextWindow: 32e3, maxOutputTokens: 8192, supportsTools: false, supportsImageInput: true, pricing: { inputPerMillion: 0.1, outputPerMillion: 0.4 } }, "gemini-2.0-flash-thinking-exp": { contextWindow: 1048576, maxOutputTokens: 65536, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.1, outputPerMillion: 0.4 } }, "gemini-2.0-flash-thinking-exp-01-21": { contextWindow: 1048576, maxOutputTokens: 65536, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.1, outputPerMillion: 0.4 } }, "gemini-2.0-flash-thinking-exp-1219": { contextWindow: 1048576, maxOutputTokens: 65536, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.1, outputPerMillion: 0.4 } }, "gemini-2.0-pro-exp": { contextWindow: 1048576, maxOutputTokens: 65536, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemini-2.0-pro-exp-02-05": { contextWindow: 1048576, maxOutputTokens: 65536, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemini-2.5-flash-exp-native-audio-thinking-dialog": { contextWindow: 128e3, maxOutputTokens: 8e3, supportsTools: true, supportsImageInput: false, pricing: { inputPerMillion: 0.5, outputPerMillion: 2 } }, "gemini-2.5-flash-preview-04-17": { contextWindow: 1048576, maxOutputTokens: 65536, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemini-2.5-flash-preview-04-17-thinking": { contextWindow: 1048576, maxOutputTokens: 65536, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemini-2.5-flash-preview-05-20": { contextWindow: 1048576, maxOutputTokens: 65536, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.15, outputPerMillion: 0.6 } }, "gemini-2.5-flash-preview-native-audio-dialog": { contextWindow: 128e3, maxOutputTokens: 8e3, supportsTools: true, supportsImageInput: false, pricing: { inputPerMillion: 0.5, outputPerMillion: 2 } }, "gemini-2.5-pro-exp-03-25": { contextWindow: 1048576, maxOutputTokens: 65536, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.12, outputPerMillion: 0.5 } }, "gemini-2.5-pro-preview-03-25": { contextWindow: 1048576, maxOutputTokens: 65536, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemini-2.5-pro-preview-05-06": { contextWindow: 1048576, maxOutputTokens: 65536, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 1.25, outputPerMillion: 10 } }, "gemini-embedding-exp": { contextWindow: 8192, maxOutputTokens: 1, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 2e-3, outputPerMillion: 4e-3 } }, "gemini-exp-1206": { contextWindow: 1048576, maxOutputTokens: 65536, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemini-pro-vision": { contextWindow: 12288, maxOutputTokens: 4096, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemma-3-12b-it": { contextWindow: 32768, maxOutputTokens: 8192, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemma-3-1b-it": { contextWindow: 32768, maxOutputTokens: 8192, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemma-3-27b-it": { contextWindow: 131072, maxOutputTokens: 8192, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemma-3-4b-it": { contextWindow: 32768, maxOutputTokens: 8192, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "gemma-3n-e4b-it": { contextWindow: 8192, maxOutputTokens: 2048, supportsTools: false, supportsImageInput: false, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } }, "learnlm-2.0-flash-experimental": { contextWindow: 1048576, maxOutputTokens: 32768, supportsTools: true, supportsImageInput: true, pricing: { inputPerMillion: 0.075, outputPerMillion: 0.3 } } }; var ModelToProvider = { "claude-2.0": "anthropic", "claude-2.1": "anthropic", "claude-3-5-haiku-20241022": "anthropic", "claude-3-5-haiku-latest": "anthropic", "claude-3-5-sonnet-20240620": "anthropic", "claude-3-5-sonnet-20241022": "anthropic", "claude-3-5-sonnet-latest": "anthropic", "claude-3-7-sonnet-20250219": "anthropic", "claude-3-7-sonnet-latest": "anthropic", "claude-3-haiku-20240307": "anthropic", "claude-3-opus-20240229": "anthropic", "claude-3-opus-latest": "anthropic", "claude-3-sonnet-20240229": "anthropic", "claude-opus-4-20250514": "anthropic", "claude-sonnet-4-20250514": "anthropic", "babbage-002": "openai", "chatgpt-4o-latest": "openai", "codex-mini-latest": "openai", "computer-use-preview": "openai", "computer-use-preview-2025-03-11": "openai", "davinci-002": "openai", "gpt-3.5-turbo": "openai", "gpt-3.5-turbo-0125": "openai", "gpt-3.5-turbo-1106": "openai", "gpt-3.5-turbo-16k": "openai", "gpt-3.5-turbo-instruct": "openai", "gpt-3.5-turbo-instruct-0914": "openai", "gpt-4": "openai", "gpt-4-0125-preview": "openai", "gpt-4-0613": "openai", "gpt-4-1106-preview": "openai", "gpt-4-turbo": "openai", "gpt-4-turbo-2024-04-09": "openai", "gpt-4-turbo-preview": "openai", "gpt-4.1": "openai", "gpt-4.1-2025-04-14": "openai", "gpt-4.1-mini": "openai", "gpt-4.1-mini-2025-04-14": "openai", "gpt-4.1-nano": "openai", "gpt-4.1-nano-2025-04-14": "openai", "gpt-4.5-preview": "openai", "gpt-4.5-preview-2025-02-27": "openai", "gpt-4o": "openai", "gpt-4o-2024-05-13": "openai", "gpt-4o-2024-08-06": "openai", "gpt-4o-2024-11-20": "openai", "gpt-4o-audio-preview": "openai", "gpt-4o-audio-preview-2024-10-01": "openai", "gpt-4o-audio-preview-2024-12-17": "openai", "gpt-4o-mini": "openai", "gpt-4o-mini-2024-07-18": "openai", "gpt-4o-mini-audio-preview": "openai", "gpt-4o-mini-audio-preview-2024-12-17": "openai", "gpt-4o-mini-realtime-preview": "openai", "gpt-4o-mini-realtime-preview-2024-12-17": "openai", "gpt-4o-mini-search-preview": "openai", "gpt-4o-mini-search-preview-2025-03-11": "openai", "gpt-4o-mini-transcribe": "openai", "gpt-4o-realtime-preview": "openai", "gpt-4o-realtime-preview-2024-10-01": "openai", "gpt-4o-realtime-preview-2024-12-17": "openai", "gpt-4o-search-preview": "openai", "gpt-4o-search-preview-2025-03-11": "openai", "gpt-4o-transcribe": "openai", o1: "openai", "o1-2024-12-17": "openai", "o1-mini": "openai", "o1-mini-2024-09-12": "openai", "o1-preview": "openai", "o1-preview-2024-09-12": "openai", "o1-pro": "openai", "o1-pro-2025-03-19": "openai", o3: "openai", "o3-2025-04-16": "openai", "o3-mini": "openai", "o3-mini-2025-01-31": "openai", "o4-mini": "openai", "o4-mini-2025-04-16": "openai", "omni-moderation-2024-09-26": "openai", "omni-moderation-latest": "openai", "text-embedding-3-large": "openai", "text-embedding-3-small": "openai", "text-embedding-ada-002": "openai", "text-moderation-latest": "openai", "tts-1-1106": "openai", "tts-1-hd-1106": "openai", aqa: "google", "embedding-gecko-001": "google", "gemini-1.0-pro-vision-latest": "google", "gemini-1.5-flash": "google", "gemini-1.5-flash-001": "google", "gemini-1.5-flash-001-tuning": "google", "gemini-1.5-flash-002": "google", "gemini-1.5-flash-8b": "google", "gemini-1.5-flash-8b-001": "google", "gemini-1.5-flash-8b-exp-0827": "google", "gemini-1.5-flash-8b-exp-0924": "google", "gemini-1.5-flash-8b-latest": "google", "gemini-1.5-flash-latest": "google", "gemini-1.5-pro": "google", "gemini-1.5-pro-001": "google", "gemini-1.5-pro-002": "google", "gemini-1.5-pro-latest": "google", "gemini-2.0-flash": "google", "gemini-2.0-flash-001": "google", "gemini-2.0-flash-exp": "google", "gemini-2.0-flash-lite": "google", "gemini-2.0-flash-lite-001": "google", "gemini-2.0-flash-lite-preview": "google", "gemini-2.0-flash-lite-preview-02-05": "google", "gemini-2.0-flash-live-001": "google", "gemini-2.0-flash-preview-image-generation": "google", "gemini-2.0-flash-thinking-exp": "google", "gemini-2.0-flash-thinking-exp-01-21": "google", "gemini-2.0-flash-thinking-exp-1219": "google", "gemini-2.0-pro-exp": "google", "gemini-2.0-pro-exp-02-05": "google", "gemini-2.5-flash-exp-native-audio-thinking-dialog": "google", "gemini-2.5-flash-preview-04-17": "google", "gemini-2.5-flash-preview-04-17-thinking": "google", "gemini-2.5-flash-preview-05-20": "google", "gemini-2.5-flash-preview-native-audio-dialog": "google", "gemini-2.5-pro-exp-03-25": "google", "gemini-2.5-pro-preview-03-25": "google", "gemini-2.5-pro-preview-05-06": "google", "gemini-embedding-exp": "google", "gemini-exp-1206": "google", "gemini-pro-vision": "google", "gemma-3-12b-it": "google", "gemma-3-1b-it": "google", "gemma-3-27b-it": "google", "gemma-3-4b-it": "google", "gemma-3n-e4b-it": "google", "learnlm-2.0-flash-experimental": "google" }; // ../../packages/lemmy/dist/src/model-registry.js function findModelData(model) { if (AnthropicModelData[model]) { return AnthropicModelData[model]; } if (OpenAIModelData[model]) { return OpenAIModelData[model]; } if (GoogleModelData[model]) { return GoogleModelData[model]; } return void 0; } // ../../packages/lemmy/dist/src/tools/index.js import { z } from "zod"; // ../../packages/lemmy/dist/src/context.js import { zodToJsonSchema as zodToJsonSchema2 } from "zod-to-json-schema"; // ../../packages/lemmy/dist/src/configs.js import { z as z2 } from "zod"; var ProviderSchema = z2.enum(["anthropic", "openai", "google"]); var BaseAskOptionsSchema = z2.object({ maxOutputTokens: z2.coerce.number().min(1).optional().describe("Maximum number of output tokens to generate"), abortSignal: z2.custom().optional().describe("AbortSignal to cancel the request") }); var AnthropicAskOptionsSchema = BaseAskOptionsSchema.extend({ thinkingEnabled: z2.coerce.boolean().optional().describe("Whether to enable extended thinking for this request"), maxThinkingTokens: z2.coerce.number().min(1024).optional().describe("Maximum number of thinking tokens for this request (must be \u22651024 and less than max_tokens)"), temperature: z2.coerce.number().min(0).max(1).optional().describe("Temperature for sampling (0.0-1.0, defaults to 1.0)"), topK: z2.coerce.number().min(1).optional().describe("Only sample from the top K options for each token"), topP: z2.coerce.number().min(0).max(1).optional().describe("Use nucleus sampling with specified probability cutoff (0.0-1.0)"), stopSequences: z2.string().optional().describe("Stop sequence (single string)"), toolChoice: z2.enum(["auto", "any", "none"]).optional().describe("How the model should use the provided tools"), disableParallelToolUse: z2.coerce.boolean().optional().describe("Whether to disable parallel tool use"), serviceTier: z2.enum(["auto", "standard_only"]).optional().describe("Priority tier for the request"), userId: z2.string().optional().describe("External identifier for the user (uuid/hash)") }); var OpenAIAskOptionsSchema = BaseAskOptionsSchema.extend({ reasoningEffort: z2.enum(["low", "medium", "high"]).optional().describe("Reasoning effort level - only supported by reasoning models (o1-mini, o1-preview)"), temperature: z2.coerce.number().min(0).max(2).optional().describe("Temperature for sampling (0.0-2.0)"), topP: z2.coerce.number().min(0).max(1).optional().describe("Top-p sampling parameter (0.0-1.0)"), presencePenalty: z2.coerce.number().min(-2).max(2).optional().describe("Presence penalty (-2.0 to 2.0) - penalizes tokens based on presence"), frequencyPenalty: z2.coerce.number().min(-2).max(2).optional().describe("Frequency penalty (-2.0 to 2.0) - penalizes tokens based on frequency"), logprobs: z2.coerce.boolean().optional().describe("Whether to return log probabilities of output tokens"), topLogprobs: z2.coerce.number().min(0).max(20).optional().describe("Number of most likely tokens to return at each position (0-20)"), maxCompletionTokens: z2.coerce.number().min(1).optional().describe("Upper bound for tokens in completion (including reasoning tokens)"), n: z2.coerce.number().min(1).max(128).optional().describe("Number of chat completion choices to generate (1-128)"), parallelToolCalls: z2.coerce.boolean().optional().describe("Enable parallel function calling during tool use"), responseFormat: z2.enum(["text", "json_object"]).optional().describe("Output format specification"), seed: z2.coerce.number().optional().describe("For deterministic sampling (beta feature)"), serviceTier: z2.enum(["auto", "default", "flex"]).optional().describe("Latency tier for scale tier customers"), stop: z2.string().optional().describe("Stop sequence (single string)"), store: z2.coerce.boolean().optional().describe("Store output for model distillation/evals"), toolChoice: z2.enum(["none", "auto", "required"]).optional().describe("Controls which tool is called"), user: z2.string().optional().describe("Stable identifier for end-users") }); var GoogleAskOptionsSchema = BaseAskOptionsSchema.extend({ includeThoughts: z2.coerce.boolean().optional().describe("Whether to include thinking tokens for this request"), thinkingBudget: z2.coerce.number().min(1).optional().describe("Thinking budget in tokens"), temperature: z2.coerce.number().min(0).max(2).optional().describe("Temperature for sampling (0.0-2.0)"), topP: z2.coerce.number().min(0).max(1).optional().describe("Top-p sampling parameter (0.0-1.0)"), topK: z2.coerce.number().min(1).optional().describe("Top-k sampling parameter (positive integer)"), candidateCount: z2.coerce.number().min(1).optional().describe("Number of response variations to return"), stopSequences: z2.string().optional().describe("Stop sequence (single string)"), responseLogprobs: z2.coerce.boolean().optional().describe("Whether to return the log probabilities of chosen tokens"), logprobs: z2.coerce.number().min(0).optional().describe("Number of top candidate tokens to return log probabilities for"), presencePenalty: z2.coerce.number().min(0).optional().describe("Positive values penalize tokens that already appear (presence penalty)"), frequencyPenalty: z2.coerce.number().min(0).optional().describe("Positive values penalize tokens that repeatedly appear (frequency penalty)"), seed: z2.coerce.number().optional().describe("Fixed seed for deterministic responses"), responseMimeType: z2.enum(["text/plain", "application/json"]).optional().describe("Output response mimetype") }); var BaseClientConfigSchema = z2.object({ apiKey: z2.string().describe("API key for the provider"), baseURL: z2.string().optional().describe("Optional custom API base URL"), maxRetries: z2.coerce.number().min(0).optional().describe("Maximum number of retries for failed requests") }); var AnthropicConfigSchema = BaseClientConfigSchema.extend({ model: z2.string().describe("Model name (e.g. 'claude-3-5-sonnet-20241022')"), defaults: AnthropicAskOptionsSchema.optional().describe("Default options for ask requests") }); var OpenAIConfigSchema = BaseClientConfigSchema.extend({ model: z2.string().describe("Model name (e.g. 'gpt-4o')"), organization: z2.string().optional().describe("Optional OpenAI organization ID"), defaults: OpenAIAskOptionsSchema.optional().describe("Default options for ask requests") }); var GoogleConfigSchema = BaseClientConfigSchema.extend({ model: z2.string().describe("Model name (e.g. 'gemini-1.5-pro')"), projectId: z2.string().optional().describe("Optional Google Cloud project ID"), defaults: GoogleAskOptionsSchema.optional().describe("Default options for ask requests") }); var CLIENT_CONFIG_SCHEMAS = { base: BaseClientConfigSchema.omit({ apiKey: true }), // Remove apiKey for CLI options anthropic: AnthropicAskOptionsSchema, openai: OpenAIAskOptionsSchema, google: GoogleAskOptionsSchema }; // ../../packages/lemmy-cli-args/dist/schema-introspection.js import { z as z3 } from "zod"; // ../../packages/lemmy-cli-args/dist/provider-validation.js function validateProvider(provider, validProviders) { return validProviders.includes(provider); } function getValidProviders() { const providers = ["anthropic", "openai", "google"]; const exhaustiveCheck = { anthropic: true, openai: true, google: true }; for (const provider of providers) { if (!exhaustiveCheck[provider]) { throw new Error(`Provider ${provider} missing from exhaustive check`); } } return providers; } function getModelProvider(model, modelToProvider) { return modelToProvider[model]; } function getCapableModels(config, targetProvider) { const capableModels = { anthropic: [], openai: [], google: [] }; for (const [registryName, registry] of Object.entries(config.modelRegistries)) { for (const [model, data] of Object.entries(registry)) { const meetsRequirements = !config.requiredCapabilities || (!config.requiredCapabilities.tools || data.supportsTools) && (!config.requiredCapabilities.images || data.supportsImageInput) && (!config.requiredCapabilities.minContextWindow || data.contextWindow >= config.requiredCapabilities.minContextWindow) && (!config.requiredCapabilities.minOutputTokens || data.maxOutputTokens >= config.requiredCapabilities.minOutputTokens); if (meetsRequirements) { const provider = getModelProvider(model, config.modelToProvider); if (provider && (!targetProvider || provider === targetProvider)) { capableModels[provider].push(model); } } } } return capableModels; } function filterProviders(allProviders, excludeProviders) { return allProviders.filter((provider) => !excludeProviders.includes(provider)); } // ../../packages/lemmy-cli-args/dist/command-generation.js import { Command, Option } from "commander"; import { z as z4 } from "zod"; // src/cli.ts import { spawnSync, execSync } from "child_process"; import path2 from "path"; import { fileURLToPath } from "url"; // src/patch-claude.ts import fs from "fs"; import path from "path"; function patchClaudeBinary(claudePath, logDir) { if (!fs.existsSync(logDir)) { fs.mkdirSync(logDir, { recursive: true }); } const claudeFilename = path.basename(claudePath); const backupPath = path.join(logDir, `${claudeFilename}.backup`); if (!fs.existsSync(backupPath)) { fs.copyFileSync(claudePath, backupPath); console.log(`\u{1F4C1} Created backup at ${backupPath}`); } const content = fs.readFileSync(claudePath, "utf8"); const patterns = [ // Standard pattern: if(PF5())process.exit(1); /if\([A-Za-z0-9_$]+\(\)\)process\.exit\(1\);/g, // With spaces: if (PF5()) process.exit(1); /if\s*\([A-Za-z0-9_$]+\(\)\)\s*process\.exit\(1\);/g, // Different exit codes: if(PF5())process.exit(2); /if\([A-Za-z0-9_$]+\(\)\)process\.exit\(\d+\);/g ]; let patchedContent = content; let patched = false; for (const pattern of patterns) { const newContent = patchedContent.replace(pattern, "if(false)process.exit(1);"); if (newContent !== patchedContent) { patchedContent = newContent; patched = true; console.log(`\u{1F527} Applied patch for pattern: ${pattern}`); } } if (!patched) { console.log("\u26A0\uFE0F No anti-debugging pattern found - Claude binary may have changed"); return claudePath; } fs.writeFileSync(claudePath, patchedContent); console.log(`\u{1F527} Patched Claude binary (backup saved to ${backupPath})`); return claudePath; } // src/version.ts var versionString; try { versionString = "1.0.14"; } catch (error) { versionString = "dev-tsx-mode"; } var VERSION = versionString; // src/cli.ts process.removeAllListeners("warning"); var modelValidationConfig = { allowUnknownModels: true, requiredCapabilities: { tools: true, images: true }, modelRegistries: { anthropic: AnthropicModelData, openai: OpenAIModelData, google: GoogleModelData }, modelToProvider: ModelToProvider }; function getCapableModelsLocal() { return getCapableModels(modelValidationConfig); } function getCapableModelsForProvider(provider) { const allCapableModels = getCapableModelsLocal(); return allCapableModels[provider] || []; } function getNonAnthropicProviders() { return filterProviders(getValidProviders(), ["anthropic"]); } function formatModelInfo(model, data) { const tools = data.supportsTools ? "\u2713" : "\u2717"; const images = data.supportsImageInput ? "\u2713" : "\u2717"; const maxInput = data.contextWindow.toLocaleString(); const maxOutput = data.maxOutputTokens.toLocaleString(); return ` ${model.padEnd(35)} ${tools.padStart(6)} ${images.padStart(7)} ${maxInput.padStart(12)} ${maxOutput.padStart(12)}`; } function showHelp() { console.log(`claude-bridge - Use non-Anthropic models with Claude Code Version: ${VERSION} USAGE: claude-bridge Show all available providers claude-bridge <provider> Show models for a provider claude-bridge <provider> <model> Run with provider and model claude-bridge --trace <claude args> Spy on Claude Code \u2194 Anthropic communication claude-bridge --version Show version information claude-bridge --help Show this help EXAMPLES: # Natural discovery flow claude-bridge # Shows: openai, google claude-bridge openai # Shows OpenAI models claude-bridge google # Shows Google models # Execution claude-bridge openai gpt-4o claude-bridge google gemini-2.0-flash-exp # With custom configuration claude-bridge openai gpt-4o --apiKey sk-... --baseURL https://api.openai.com/v1 # Single-shot prompts claude-bridge openai gpt-4o -p "Hello world" claude-bridge google gemini-1.5-pro -p "Debug this code" OPTIONS: --apiKey <key> API key for the provider --baseURL <url> Custom API base URL --maxRetries <num> Maximum number of retries for failed requests --max-output-tokens <num> Maximum output tokens (overrides provider defaults) --log-dir <dir> Directory for log files (default: .claude-bridge) --claude-binary <path> Path to Claude Code CLI binary (default: auto-detect) --patch-claude Patch Claude binary to disable anti-debugging checks --debug Enable debug logging (requests/responses to .claude-bridge/) --trace Spy mode: log all Claude \u2194 Anthropic communication (implies --debug) --version Show version information --help, -h Show this help ENVIRONMENT VARIABLES: OPENAI_API_KEY API key for OpenAI (if --apiKey not provided) GOOGLE_API_KEY API key for Google (if --apiKey not provided) NOTE: Only models with both tools and image support are shown by default. Use --debug to enable request/response logging to .claude-bridge/ `); } function showProviders() { const nonAnthropicProviders = getNonAnthropicProviders(); console.log(`Available providers (only showing providers with capable models): `); for (const provider of nonAnthropicProviders) { const models = getCapableModelsForProvider(provider); if (models.length > 0) { switch (provider) { case "openai": console.log(` openai OpenAI models (GPT-4o, etc.)`); break; case "google": console.log(` google Google models (Gemini, etc.)`); break; default: { const _exhaustiveCheck = provider; _exhaustiveCheck; } } } } console.log(` Usage: claude-bridge <provider> Show models for a provider claude-bridge --help Show detailed help Examples: claude-bridge openai # Show OpenAI models claude-bridge google # Show Google models`); } function showProviderModels(provider) { const validProviders = getValidProviders(); if (!validateProvider(provider, validProviders)) { console.error(`\u274C Invalid provider: ${provider}`); const nonAnthropicProviders = getNonAnthropicProviders(); console.error(`Available providers: ${nonAnthropicProviders.join(", ")}`); process.exit(1); } if (provider === "anthropic"