@mariozechner/pi-ai 0.40.1 → 0.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AnthropicOptions } from \"./providers/anthropic.js\";\nimport type { GoogleOptions } from \"./providers/google.js\";\nimport type { GoogleGeminiCliOptions } from \"./providers/google-gemini-cli.js\";\nimport type { GoogleVertexOptions } from \"./providers/google-vertex.js\";\nimport type { OpenAICodexResponsesOptions } from \"./providers/openai-codex-responses.js\";\nimport type { OpenAICompletionsOptions } from \"./providers/openai-completions.js\";\nimport type { OpenAIResponsesOptions } from \"./providers/openai-responses.js\";\nimport type { AssistantMessageEventStream } from \"./utils/event-stream.js\";\n\nexport type { AssistantMessageEventStream } from \"./utils/event-stream.js\";\n\nexport type Api =\n\t| \"openai-completions\"\n\t| \"openai-responses\"\n\t| \"openai-codex-responses\"\n\t| \"anthropic-messages\"\n\t| \"google-generative-ai\"\n\t| \"google-gemini-cli\"\n\t| \"google-vertex\";\n\nexport interface ApiOptionsMap {\n\t\"anthropic-messages\": AnthropicOptions;\n\t\"openai-completions\": OpenAICompletionsOptions;\n\t\"openai-responses\": OpenAIResponsesOptions;\n\t\"openai-codex-responses\": OpenAICodexResponsesOptions;\n\t\"google-generative-ai\": GoogleOptions;\n\t\"google-gemini-cli\": GoogleGeminiCliOptions;\n\t\"google-vertex\": GoogleVertexOptions;\n}\n\n// Compile-time exhaustiveness check - this will fail if ApiOptionsMap doesn't have all KnownApi keys\ntype _CheckExhaustive = ApiOptionsMap extends Record<Api, StreamOptions>\n\t? Record<Api, StreamOptions> extends ApiOptionsMap\n\t\t? true\n\t\t: [\"ApiOptionsMap is missing some KnownApi values\", Exclude<Api, keyof ApiOptionsMap>]\n\t: [\"ApiOptionsMap doesn't extend Record<KnownApi, StreamOptions>\"];\nconst _exhaustive: _CheckExhaustive = true;\n\n// Helper type to get options for a specific API\nexport type OptionsForApi<TApi extends Api> = ApiOptionsMap[TApi];\n\nexport type KnownProvider =\n\t| \"anthropic\"\n\t| \"google\"\n\t| \"google-gemini-cli\"\n\t| \"google-antigravity\"\n\t| \"google-vertex\"\n\t| \"openai\"\n\t| \"openai-codex\"\n\t| \"github-copilot\"\n\t| \"xai\"\n\t| \"groq\"\n\t| \"cerebras\"\n\t| \"openrouter\"\n\t| \"zai\"\n\t| \"mistral\";\nexport type Provider = KnownProvider | string;\n\nexport type ThinkingLevel = \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n\n/** Token budgets for each thinking level (token-based providers only) */\nexport interface ThinkingBudgets {\n\tminimal?: number;\n\tlow?: number;\n\tmedium?: number;\n\thigh?: number;\n}\n\n// Base options all providers share\nexport interface StreamOptions {\n\ttemperature?: number;\n\tmaxTokens?: number;\n\tsignal?: AbortSignal;\n\tapiKey?: string;\n\t/**\n\t * Optional session identifier for providers that support session-based caching.\n\t * Providers can use this to enable prompt caching, request routing, or other\n\t * session-aware features. Ignored by providers that don't support it.\n\t */\n\tsessionId?: string;\n}\n\n// Unified options with reasoning passed to streamSimple() and completeSimple()\nexport interface SimpleStreamOptions extends StreamOptions {\n\treasoning?: ThinkingLevel;\n\t/** Custom token budgets for thinking levels (token-based providers only) */\n\tthinkingBudgets?: ThinkingBudgets;\n}\n\n// Generic StreamFunction with typed options\nexport type StreamFunction<TApi extends Api> = (\n\tmodel: Model<TApi>,\n\tcontext: Context,\n\toptions: OptionsForApi<TApi>,\n) => AssistantMessageEventStream;\n\nexport interface TextContent {\n\ttype: \"text\";\n\ttext: string;\n\ttextSignature?: string; // e.g., for OpenAI responses, the message ID\n}\n\nexport interface ThinkingContent {\n\ttype: \"thinking\";\n\tthinking: string;\n\tthinkingSignature?: string; // e.g., for OpenAI responses, the reasoning item ID\n}\n\nexport interface ImageContent {\n\ttype: \"image\";\n\tdata: string; // base64 encoded image data\n\tmimeType: string; // e.g., \"image/jpeg\", \"image/png\"\n}\n\nexport interface ToolCall {\n\ttype: \"toolCall\";\n\tid: string;\n\tname: string;\n\targuments: Record<string, any>;\n\tthoughtSignature?: string; // Google-specific: opaque signature for reusing thought context\n}\n\nexport interface Usage {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\ttotalTokens: number;\n\tcost: {\n\t\tinput: number;\n\t\toutput: number;\n\t\tcacheRead: number;\n\t\tcacheWrite: number;\n\t\ttotal: number;\n\t};\n}\n\nexport type StopReason = \"stop\" | \"length\" | \"toolUse\" | \"error\" | \"aborted\";\n\nexport interface UserMessage {\n\trole: \"user\";\n\tcontent: string | (TextContent | ImageContent)[];\n\ttimestamp: number; // Unix timestamp in milliseconds\n}\n\nexport interface AssistantMessage {\n\trole: \"assistant\";\n\tcontent: (TextContent | ThinkingContent | ToolCall)[];\n\tapi: Api;\n\tprovider: Provider;\n\tmodel: string;\n\tusage: Usage;\n\tstopReason: StopReason;\n\terrorMessage?: string;\n\ttimestamp: number; // Unix timestamp in milliseconds\n}\n\nexport interface ToolResultMessage<TDetails = any> {\n\trole: \"toolResult\";\n\ttoolCallId: string;\n\ttoolName: string;\n\tcontent: (TextContent | ImageContent)[]; // Supports text and images\n\tdetails?: TDetails;\n\tisError: boolean;\n\ttimestamp: number; // Unix timestamp in milliseconds\n}\n\nexport type Message = UserMessage | AssistantMessage | ToolResultMessage;\n\nimport type { TSchema } from \"@sinclair/typebox\";\n\nexport interface Tool<TParameters extends TSchema = TSchema> {\n\tname: string;\n\tdescription: string;\n\tparameters: TParameters;\n}\n\nexport interface Context {\n\tsystemPrompt?: string;\n\tmessages: Message[];\n\ttools?: Tool[];\n}\n\nexport type AssistantMessageEvent =\n\t| { type: \"start\"; partial: AssistantMessage }\n\t| { type: \"text_start\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"text_delta\"; contentIndex: number; delta: string; partial: AssistantMessage }\n\t| { type: \"text_end\"; contentIndex: number; content: string; partial: AssistantMessage }\n\t| { type: \"thinking_start\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"thinking_delta\"; contentIndex: number; delta: string; partial: AssistantMessage }\n\t| { type: \"thinking_end\"; contentIndex: number; content: string; partial: AssistantMessage }\n\t| { type: \"toolcall_start\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"toolcall_delta\"; contentIndex: number; delta: string; partial: AssistantMessage }\n\t| { type: \"toolcall_end\"; contentIndex: number; toolCall: ToolCall; partial: AssistantMessage }\n\t| { type: \"done\"; reason: Extract<StopReason, \"stop\" | \"length\" | \"toolUse\">; message: AssistantMessage }\n\t| { type: \"error\"; reason: Extract<StopReason, \"aborted\" | \"error\">; error: AssistantMessage };\n\n/**\n * Compatibility settings for openai-completions API.\n * Use this to override URL-based auto-detection for custom providers.\n */\nexport interface OpenAICompat {\n\t/** Whether the provider supports the `store` field. Default: auto-detected from URL. */\n\tsupportsStore?: boolean;\n\t/** Whether the provider supports the `developer` role (vs `system`). Default: auto-detected from URL. */\n\tsupportsDeveloperRole?: boolean;\n\t/** Whether the provider supports `reasoning_effort`. Default: auto-detected from URL. */\n\tsupportsReasoningEffort?: boolean;\n\t/** Which field to use for max tokens. Default: auto-detected from URL. */\n\tmaxTokensField?: \"max_completion_tokens\" | \"max_tokens\";\n\t/** Whether tool results require the `name` field. Default: auto-detected from URL. */\n\trequiresToolResultName?: boolean;\n\t/** Whether a user message after tool results requires an assistant message in between. Default: auto-detected from URL. */\n\trequiresAssistantAfterToolResult?: boolean;\n\t/** Whether thinking blocks must be converted to text blocks with <thinking> delimiters. Default: auto-detected from URL. */\n\trequiresThinkingAsText?: boolean;\n\t/** Whether tool call IDs must be normalized to Mistral format (exactly 9 alphanumeric chars). Default: auto-detected from URL. */\n\trequiresMistralToolIds?: boolean;\n}\n\n// Model interface for the unified model system\nexport interface Model<TApi extends Api> {\n\tid: string;\n\tname: string;\n\tapi: TApi;\n\tprovider: Provider;\n\tbaseUrl: string;\n\treasoning: boolean;\n\tinput: (\"text\" | \"image\")[];\n\tcost: {\n\t\tinput: number; // $/million tokens\n\t\toutput: number; // $/million tokens\n\t\tcacheRead: number; // $/million tokens\n\t\tcacheWrite: number; // $/million tokens\n\t};\n\tcontextWindow: number;\n\tmaxTokens: number;\n\theaders?: Record<string, string>;\n\t/** Compatibility overrides for openai-completions API. If not set, auto-detected from baseUrl. */\n\tcompat?: TApi extends \"openai-completions\" ? OpenAICompat : never;\n}\n"]}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,uCAAuC,CAAC;AACzF,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAClF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAE3E,YAAY,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAE3E,MAAM,MAAM,GAAG,GACZ,oBAAoB,GACpB,kBAAkB,GAClB,wBAAwB,GACxB,oBAAoB,GACpB,sBAAsB,GACtB,mBAAmB,GACnB,eAAe,CAAC;AAEnB,MAAM,WAAW,aAAa;IAC7B,oBAAoB,EAAE,gBAAgB,CAAC;IACvC,oBAAoB,EAAE,wBAAwB,CAAC;IAC/C,kBAAkB,EAAE,sBAAsB,CAAC;IAC3C,wBAAwB,EAAE,2BAA2B,CAAC;IACtD,sBAAsB,EAAE,aAAa,CAAC;IACtC,mBAAmB,EAAE,sBAAsB,CAAC;IAC5C,eAAe,EAAE,mBAAmB,CAAC;CACrC;AAWD,MAAM,MAAM,aAAa,CAAC,IAAI,SAAS,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC;AAElE,MAAM,MAAM,aAAa,GACtB,WAAW,GACX,QAAQ,GACR,mBAAmB,GACnB,oBAAoB,GACpB,eAAe,GACf,QAAQ,GACR,cAAc,GACd,gBAAgB,GAChB,KAAK,GACL,MAAM,GACN,UAAU,GACV,YAAY,GACZ,KAAK,GACL,SAAS,GACT,UAAU,CAAC;AACd,MAAM,MAAM,QAAQ,GAAG,aAAa,GAAG,MAAM,CAAC;AAE9C,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAE5E,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAGD,MAAM,WAAW,aAAa;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAGD,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACzD,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,4EAA4E;IAC5E,eAAe,CAAC,EAAE,eAAe,CAAC;CAClC;AAGD,MAAM,MAAM,cAAc,CAAC,IAAI,SAAS,GAAG,IAAI,CAC9C,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,EAClB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,KACxB,2BAA2B,CAAC;AAEjC,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACxB,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,KAAK;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;KACd,CAAC;CACF;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE7E,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC;IACjD,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,CAAC,WAAW,GAAG,eAAe,GAAG,QAAQ,CAAC,EAAE,CAAC;IACtD,GAAG,EAAE,GAAG,CAAC;IACT,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IACb,UAAU,EAAE,UAAU,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB,CAAC,QAAQ,GAAG,GAAG;IAChD,IAAI,EAAE,YAAY,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC;IACxC,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,OAAO,GAAG,WAAW,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;AAEzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,WAAW,IAAI,CAAC,WAAW,SAAS,OAAO,GAAG,OAAO;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,WAAW,CAAC;CACxB;AAED,MAAM,WAAW,OAAO;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;CACf;AAED,MAAM,MAAM,qBAAqB,GAC9B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GACvE;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GACtF;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GACtF;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GAC3E;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GAC1F;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GAC1F;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GAC3E;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GAC1F;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GAC7F;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GACvG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,CAAC;IAAC,KAAK,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAEhG;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC5B,wFAAwF;IACxF,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,yGAAyG;IACzG,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,yFAAyF;IACzF,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,0EAA0E;IAC1E,cAAc,CAAC,EAAE,uBAAuB,GAAG,YAAY,CAAC;IACxD,sFAAsF;IACtF,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,2HAA2H;IAC3H,gCAAgC,CAAC,EAAE,OAAO,CAAC;IAC3C,4HAA4H;IAC5H,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,kIAAkI;IAClI,sBAAsB,CAAC,EAAE,OAAO,CAAC;CACjC;AAGD,MAAM,WAAW,KAAK,CAAC,IAAI,SAAS,GAAG;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,IAAI,CAAC;IACV,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,CAAC,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;IAC5B,IAAI,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,kGAAkG;IAClG,MAAM,CAAC,EAAE,IAAI,SAAS,oBAAoB,GAAG,YAAY,GAAG,KAAK,CAAC;CAClE","sourcesContent":["import type { AnthropicOptions } from \"./providers/anthropic.js\";\nimport type { GoogleOptions } from \"./providers/google.js\";\nimport type { GoogleGeminiCliOptions } from \"./providers/google-gemini-cli.js\";\nimport type { GoogleVertexOptions } from \"./providers/google-vertex.js\";\nimport type { OpenAICodexResponsesOptions } from \"./providers/openai-codex-responses.js\";\nimport type { OpenAICompletionsOptions } from \"./providers/openai-completions.js\";\nimport type { OpenAIResponsesOptions } from \"./providers/openai-responses.js\";\nimport type { AssistantMessageEventStream } from \"./utils/event-stream.js\";\n\nexport type { AssistantMessageEventStream } from \"./utils/event-stream.js\";\n\nexport type Api =\n\t| \"openai-completions\"\n\t| \"openai-responses\"\n\t| \"openai-codex-responses\"\n\t| \"anthropic-messages\"\n\t| \"google-generative-ai\"\n\t| \"google-gemini-cli\"\n\t| \"google-vertex\";\n\nexport interface ApiOptionsMap {\n\t\"anthropic-messages\": AnthropicOptions;\n\t\"openai-completions\": OpenAICompletionsOptions;\n\t\"openai-responses\": OpenAIResponsesOptions;\n\t\"openai-codex-responses\": OpenAICodexResponsesOptions;\n\t\"google-generative-ai\": GoogleOptions;\n\t\"google-gemini-cli\": GoogleGeminiCliOptions;\n\t\"google-vertex\": GoogleVertexOptions;\n}\n\n// Compile-time exhaustiveness check - this will fail if ApiOptionsMap doesn't have all KnownApi keys\ntype _CheckExhaustive = ApiOptionsMap extends Record<Api, StreamOptions>\n\t? Record<Api, StreamOptions> extends ApiOptionsMap\n\t\t? true\n\t\t: [\"ApiOptionsMap is missing some KnownApi values\", Exclude<Api, keyof ApiOptionsMap>]\n\t: [\"ApiOptionsMap doesn't extend Record<KnownApi, StreamOptions>\"];\nconst _exhaustive: _CheckExhaustive = true;\n\n// Helper type to get options for a specific API\nexport type OptionsForApi<TApi extends Api> = ApiOptionsMap[TApi];\n\nexport type KnownProvider =\n\t| \"anthropic\"\n\t| \"google\"\n\t| \"google-gemini-cli\"\n\t| \"google-antigravity\"\n\t| \"google-vertex\"\n\t| \"openai\"\n\t| \"openai-codex\"\n\t| \"github-copilot\"\n\t| \"xai\"\n\t| \"groq\"\n\t| \"cerebras\"\n\t| \"openrouter\"\n\t| \"zai\"\n\t| \"mistral\"\n\t| \"opencode\";\nexport type Provider = KnownProvider | string;\n\nexport type ThinkingLevel = \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n\n/** Token budgets for each thinking level (token-based providers only) */\nexport interface ThinkingBudgets {\n\tminimal?: number;\n\tlow?: number;\n\tmedium?: number;\n\thigh?: number;\n}\n\n// Base options all providers share\nexport interface StreamOptions {\n\ttemperature?: number;\n\tmaxTokens?: number;\n\tsignal?: AbortSignal;\n\tapiKey?: string;\n\t/**\n\t * Optional session identifier for providers that support session-based caching.\n\t * Providers can use this to enable prompt caching, request routing, or other\n\t * session-aware features. Ignored by providers that don't support it.\n\t */\n\tsessionId?: string;\n}\n\n// Unified options with reasoning passed to streamSimple() and completeSimple()\nexport interface SimpleStreamOptions extends StreamOptions {\n\treasoning?: ThinkingLevel;\n\t/** Custom token budgets for thinking levels (token-based providers only) */\n\tthinkingBudgets?: ThinkingBudgets;\n}\n\n// Generic StreamFunction with typed options\nexport type StreamFunction<TApi extends Api> = (\n\tmodel: Model<TApi>,\n\tcontext: Context,\n\toptions: OptionsForApi<TApi>,\n) => AssistantMessageEventStream;\n\nexport interface TextContent {\n\ttype: \"text\";\n\ttext: string;\n\ttextSignature?: string; // e.g., for OpenAI responses, the message ID\n}\n\nexport interface ThinkingContent {\n\ttype: \"thinking\";\n\tthinking: string;\n\tthinkingSignature?: string; // e.g., for OpenAI responses, the reasoning item ID\n}\n\nexport interface ImageContent {\n\ttype: \"image\";\n\tdata: string; // base64 encoded image data\n\tmimeType: string; // e.g., \"image/jpeg\", \"image/png\"\n}\n\nexport interface ToolCall {\n\ttype: \"toolCall\";\n\tid: string;\n\tname: string;\n\targuments: Record<string, any>;\n\tthoughtSignature?: string; // Google-specific: opaque signature for reusing thought context\n}\n\nexport interface Usage {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\ttotalTokens: number;\n\tcost: {\n\t\tinput: number;\n\t\toutput: number;\n\t\tcacheRead: number;\n\t\tcacheWrite: number;\n\t\ttotal: number;\n\t};\n}\n\nexport type StopReason = \"stop\" | \"length\" | \"toolUse\" | \"error\" | \"aborted\";\n\nexport interface UserMessage {\n\trole: \"user\";\n\tcontent: string | (TextContent | ImageContent)[];\n\ttimestamp: number; // Unix timestamp in milliseconds\n}\n\nexport interface AssistantMessage {\n\trole: \"assistant\";\n\tcontent: (TextContent | ThinkingContent | ToolCall)[];\n\tapi: Api;\n\tprovider: Provider;\n\tmodel: string;\n\tusage: Usage;\n\tstopReason: StopReason;\n\terrorMessage?: string;\n\ttimestamp: number; // Unix timestamp in milliseconds\n}\n\nexport interface ToolResultMessage<TDetails = any> {\n\trole: \"toolResult\";\n\ttoolCallId: string;\n\ttoolName: string;\n\tcontent: (TextContent | ImageContent)[]; // Supports text and images\n\tdetails?: TDetails;\n\tisError: boolean;\n\ttimestamp: number; // Unix timestamp in milliseconds\n}\n\nexport type Message = UserMessage | AssistantMessage | ToolResultMessage;\n\nimport type { TSchema } from \"@sinclair/typebox\";\n\nexport interface Tool<TParameters extends TSchema = TSchema> {\n\tname: string;\n\tdescription: string;\n\tparameters: TParameters;\n}\n\nexport interface Context {\n\tsystemPrompt?: string;\n\tmessages: Message[];\n\ttools?: Tool[];\n}\n\nexport type AssistantMessageEvent =\n\t| { type: \"start\"; partial: AssistantMessage }\n\t| { type: \"text_start\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"text_delta\"; contentIndex: number; delta: string; partial: AssistantMessage }\n\t| { type: \"text_end\"; contentIndex: number; content: string; partial: AssistantMessage }\n\t| { type: \"thinking_start\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"thinking_delta\"; contentIndex: number; delta: string; partial: AssistantMessage }\n\t| { type: \"thinking_end\"; contentIndex: number; content: string; partial: AssistantMessage }\n\t| { type: \"toolcall_start\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"toolcall_delta\"; contentIndex: number; delta: string; partial: AssistantMessage }\n\t| { type: \"toolcall_end\"; contentIndex: number; toolCall: ToolCall; partial: AssistantMessage }\n\t| { type: \"done\"; reason: Extract<StopReason, \"stop\" | \"length\" | \"toolUse\">; message: AssistantMessage }\n\t| { type: \"error\"; reason: Extract<StopReason, \"aborted\" | \"error\">; error: AssistantMessage };\n\n/**\n * Compatibility settings for openai-completions API.\n * Use this to override URL-based auto-detection for custom providers.\n */\nexport interface OpenAICompat {\n\t/** Whether the provider supports the `store` field. Default: auto-detected from URL. */\n\tsupportsStore?: boolean;\n\t/** Whether the provider supports the `developer` role (vs `system`). Default: auto-detected from URL. */\n\tsupportsDeveloperRole?: boolean;\n\t/** Whether the provider supports `reasoning_effort`. Default: auto-detected from URL. */\n\tsupportsReasoningEffort?: boolean;\n\t/** Which field to use for max tokens. Default: auto-detected from URL. */\n\tmaxTokensField?: \"max_completion_tokens\" | \"max_tokens\";\n\t/** Whether tool results require the `name` field. Default: auto-detected from URL. */\n\trequiresToolResultName?: boolean;\n\t/** Whether a user message after tool results requires an assistant message in between. Default: auto-detected from URL. */\n\trequiresAssistantAfterToolResult?: boolean;\n\t/** Whether thinking blocks must be converted to text blocks with <thinking> delimiters. Default: auto-detected from URL. */\n\trequiresThinkingAsText?: boolean;\n\t/** Whether tool call IDs must be normalized to Mistral format (exactly 9 alphanumeric chars). Default: auto-detected from URL. */\n\trequiresMistralToolIds?: boolean;\n}\n\n// Model interface for the unified model system\nexport interface Model<TApi extends Api> {\n\tid: string;\n\tname: string;\n\tapi: TApi;\n\tprovider: Provider;\n\tbaseUrl: string;\n\treasoning: boolean;\n\tinput: (\"text\" | \"image\")[];\n\tcost: {\n\t\tinput: number; // $/million tokens\n\t\toutput: number; // $/million tokens\n\t\tcacheRead: number; // $/million tokens\n\t\tcacheWrite: number; // $/million tokens\n\t};\n\tcontextWindow: number;\n\tmaxTokens: number;\n\theaders?: Record<string, string>;\n\t/** Compatibility overrides for openai-completions API. If not set, auto-detected from baseUrl. */\n\tcompat?: TApi extends \"openai-completions\" ? OpenAICompat : never;\n}\n"]}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAoCA,MAAM,WAAW,GAAqB,IAAI,CAAC","sourcesContent":["import type { AnthropicOptions } from \"./providers/anthropic.js\";\nimport type { GoogleOptions } from \"./providers/google.js\";\nimport type { GoogleGeminiCliOptions } from \"./providers/google-gemini-cli.js\";\nimport type { GoogleVertexOptions } from \"./providers/google-vertex.js\";\nimport type { OpenAICodexResponsesOptions } from \"./providers/openai-codex-responses.js\";\nimport type { OpenAICompletionsOptions } from \"./providers/openai-completions.js\";\nimport type { OpenAIResponsesOptions } from \"./providers/openai-responses.js\";\nimport type { AssistantMessageEventStream } from \"./utils/event-stream.js\";\n\nexport type { AssistantMessageEventStream } from \"./utils/event-stream.js\";\n\nexport type Api =\n\t| \"openai-completions\"\n\t| \"openai-responses\"\n\t| \"openai-codex-responses\"\n\t| \"anthropic-messages\"\n\t| \"google-generative-ai\"\n\t| \"google-gemini-cli\"\n\t| \"google-vertex\";\n\nexport interface ApiOptionsMap {\n\t\"anthropic-messages\": AnthropicOptions;\n\t\"openai-completions\": OpenAICompletionsOptions;\n\t\"openai-responses\": OpenAIResponsesOptions;\n\t\"openai-codex-responses\": OpenAICodexResponsesOptions;\n\t\"google-generative-ai\": GoogleOptions;\n\t\"google-gemini-cli\": GoogleGeminiCliOptions;\n\t\"google-vertex\": GoogleVertexOptions;\n}\n\n// Compile-time exhaustiveness check - this will fail if ApiOptionsMap doesn't have all KnownApi keys\ntype _CheckExhaustive = ApiOptionsMap extends Record<Api, StreamOptions>\n\t? Record<Api, StreamOptions> extends ApiOptionsMap\n\t\t? true\n\t\t: [\"ApiOptionsMap is missing some KnownApi values\", Exclude<Api, keyof ApiOptionsMap>]\n\t: [\"ApiOptionsMap doesn't extend Record<KnownApi, StreamOptions>\"];\nconst _exhaustive: _CheckExhaustive = true;\n\n// Helper type to get options for a specific API\nexport type OptionsForApi<TApi extends Api> = ApiOptionsMap[TApi];\n\nexport type KnownProvider =\n\t| \"anthropic\"\n\t| \"google\"\n\t| \"google-gemini-cli\"\n\t| \"google-antigravity\"\n\t| \"google-vertex\"\n\t| \"openai\"\n\t| \"openai-codex\"\n\t| \"github-copilot\"\n\t| \"xai\"\n\t| \"groq\"\n\t| \"cerebras\"\n\t| \"openrouter\"\n\t| \"zai\"\n\t| \"mistral\";\nexport type Provider = KnownProvider | string;\n\nexport type ThinkingLevel = \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n\n/** Token budgets for each thinking level (token-based providers only) */\nexport interface ThinkingBudgets {\n\tminimal?: number;\n\tlow?: number;\n\tmedium?: number;\n\thigh?: number;\n}\n\n// Base options all providers share\nexport interface StreamOptions {\n\ttemperature?: number;\n\tmaxTokens?: number;\n\tsignal?: AbortSignal;\n\tapiKey?: string;\n\t/**\n\t * Optional session identifier for providers that support session-based caching.\n\t * Providers can use this to enable prompt caching, request routing, or other\n\t * session-aware features. Ignored by providers that don't support it.\n\t */\n\tsessionId?: string;\n}\n\n// Unified options with reasoning passed to streamSimple() and completeSimple()\nexport interface SimpleStreamOptions extends StreamOptions {\n\treasoning?: ThinkingLevel;\n\t/** Custom token budgets for thinking levels (token-based providers only) */\n\tthinkingBudgets?: ThinkingBudgets;\n}\n\n// Generic StreamFunction with typed options\nexport type StreamFunction<TApi extends Api> = (\n\tmodel: Model<TApi>,\n\tcontext: Context,\n\toptions: OptionsForApi<TApi>,\n) => AssistantMessageEventStream;\n\nexport interface TextContent {\n\ttype: \"text\";\n\ttext: string;\n\ttextSignature?: string; // e.g., for OpenAI responses, the message ID\n}\n\nexport interface ThinkingContent {\n\ttype: \"thinking\";\n\tthinking: string;\n\tthinkingSignature?: string; // e.g., for OpenAI responses, the reasoning item ID\n}\n\nexport interface ImageContent {\n\ttype: \"image\";\n\tdata: string; // base64 encoded image data\n\tmimeType: string; // e.g., \"image/jpeg\", \"image/png\"\n}\n\nexport interface ToolCall {\n\ttype: \"toolCall\";\n\tid: string;\n\tname: string;\n\targuments: Record<string, any>;\n\tthoughtSignature?: string; // Google-specific: opaque signature for reusing thought context\n}\n\nexport interface Usage {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\ttotalTokens: number;\n\tcost: {\n\t\tinput: number;\n\t\toutput: number;\n\t\tcacheRead: number;\n\t\tcacheWrite: number;\n\t\ttotal: number;\n\t};\n}\n\nexport type StopReason = \"stop\" | \"length\" | \"toolUse\" | \"error\" | \"aborted\";\n\nexport interface UserMessage {\n\trole: \"user\";\n\tcontent: string | (TextContent | ImageContent)[];\n\ttimestamp: number; // Unix timestamp in milliseconds\n}\n\nexport interface AssistantMessage {\n\trole: \"assistant\";\n\tcontent: (TextContent | ThinkingContent | ToolCall)[];\n\tapi: Api;\n\tprovider: Provider;\n\tmodel: string;\n\tusage: Usage;\n\tstopReason: StopReason;\n\terrorMessage?: string;\n\ttimestamp: number; // Unix timestamp in milliseconds\n}\n\nexport interface ToolResultMessage<TDetails = any> {\n\trole: \"toolResult\";\n\ttoolCallId: string;\n\ttoolName: string;\n\tcontent: (TextContent | ImageContent)[]; // Supports text and images\n\tdetails?: TDetails;\n\tisError: boolean;\n\ttimestamp: number; // Unix timestamp in milliseconds\n}\n\nexport type Message = UserMessage | AssistantMessage | ToolResultMessage;\n\nimport type { TSchema } from \"@sinclair/typebox\";\n\nexport interface Tool<TParameters extends TSchema = TSchema> {\n\tname: string;\n\tdescription: string;\n\tparameters: TParameters;\n}\n\nexport interface Context {\n\tsystemPrompt?: string;\n\tmessages: Message[];\n\ttools?: Tool[];\n}\n\nexport type AssistantMessageEvent =\n\t| { type: \"start\"; partial: AssistantMessage }\n\t| { type: \"text_start\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"text_delta\"; contentIndex: number; delta: string; partial: AssistantMessage }\n\t| { type: \"text_end\"; contentIndex: number; content: string; partial: AssistantMessage }\n\t| { type: \"thinking_start\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"thinking_delta\"; contentIndex: number; delta: string; partial: AssistantMessage }\n\t| { type: \"thinking_end\"; contentIndex: number; content: string; partial: AssistantMessage }\n\t| { type: \"toolcall_start\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"toolcall_delta\"; contentIndex: number; delta: string; partial: AssistantMessage }\n\t| { type: \"toolcall_end\"; contentIndex: number; toolCall: ToolCall; partial: AssistantMessage }\n\t| { type: \"done\"; reason: Extract<StopReason, \"stop\" | \"length\" | \"toolUse\">; message: AssistantMessage }\n\t| { type: \"error\"; reason: Extract<StopReason, \"aborted\" | \"error\">; error: AssistantMessage };\n\n/**\n * Compatibility settings for openai-completions API.\n * Use this to override URL-based auto-detection for custom providers.\n */\nexport interface OpenAICompat {\n\t/** Whether the provider supports the `store` field. Default: auto-detected from URL. */\n\tsupportsStore?: boolean;\n\t/** Whether the provider supports the `developer` role (vs `system`). Default: auto-detected from URL. */\n\tsupportsDeveloperRole?: boolean;\n\t/** Whether the provider supports `reasoning_effort`. Default: auto-detected from URL. */\n\tsupportsReasoningEffort?: boolean;\n\t/** Which field to use for max tokens. Default: auto-detected from URL. */\n\tmaxTokensField?: \"max_completion_tokens\" | \"max_tokens\";\n\t/** Whether tool results require the `name` field. Default: auto-detected from URL. */\n\trequiresToolResultName?: boolean;\n\t/** Whether a user message after tool results requires an assistant message in between. Default: auto-detected from URL. */\n\trequiresAssistantAfterToolResult?: boolean;\n\t/** Whether thinking blocks must be converted to text blocks with <thinking> delimiters. Default: auto-detected from URL. */\n\trequiresThinkingAsText?: boolean;\n\t/** Whether tool call IDs must be normalized to Mistral format (exactly 9 alphanumeric chars). Default: auto-detected from URL. */\n\trequiresMistralToolIds?: boolean;\n}\n\n// Model interface for the unified model system\nexport interface Model<TApi extends Api> {\n\tid: string;\n\tname: string;\n\tapi: TApi;\n\tprovider: Provider;\n\tbaseUrl: string;\n\treasoning: boolean;\n\tinput: (\"text\" | \"image\")[];\n\tcost: {\n\t\tinput: number; // $/million tokens\n\t\toutput: number; // $/million tokens\n\t\tcacheRead: number; // $/million tokens\n\t\tcacheWrite: number; // $/million tokens\n\t};\n\tcontextWindow: number;\n\tmaxTokens: number;\n\theaders?: Record<string, string>;\n\t/** Compatibility overrides for openai-completions API. If not set, auto-detected from baseUrl. */\n\tcompat?: TApi extends \"openai-completions\" ? OpenAICompat : never;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAoCA,MAAM,WAAW,GAAqB,IAAI,CAAC","sourcesContent":["import type { AnthropicOptions } from \"./providers/anthropic.js\";\nimport type { GoogleOptions } from \"./providers/google.js\";\nimport type { GoogleGeminiCliOptions } from \"./providers/google-gemini-cli.js\";\nimport type { GoogleVertexOptions } from \"./providers/google-vertex.js\";\nimport type { OpenAICodexResponsesOptions } from \"./providers/openai-codex-responses.js\";\nimport type { OpenAICompletionsOptions } from \"./providers/openai-completions.js\";\nimport type { OpenAIResponsesOptions } from \"./providers/openai-responses.js\";\nimport type { AssistantMessageEventStream } from \"./utils/event-stream.js\";\n\nexport type { AssistantMessageEventStream } from \"./utils/event-stream.js\";\n\nexport type Api =\n\t| \"openai-completions\"\n\t| \"openai-responses\"\n\t| \"openai-codex-responses\"\n\t| \"anthropic-messages\"\n\t| \"google-generative-ai\"\n\t| \"google-gemini-cli\"\n\t| \"google-vertex\";\n\nexport interface ApiOptionsMap {\n\t\"anthropic-messages\": AnthropicOptions;\n\t\"openai-completions\": OpenAICompletionsOptions;\n\t\"openai-responses\": OpenAIResponsesOptions;\n\t\"openai-codex-responses\": OpenAICodexResponsesOptions;\n\t\"google-generative-ai\": GoogleOptions;\n\t\"google-gemini-cli\": GoogleGeminiCliOptions;\n\t\"google-vertex\": GoogleVertexOptions;\n}\n\n// Compile-time exhaustiveness check - this will fail if ApiOptionsMap doesn't have all KnownApi keys\ntype _CheckExhaustive = ApiOptionsMap extends Record<Api, StreamOptions>\n\t? Record<Api, StreamOptions> extends ApiOptionsMap\n\t\t? true\n\t\t: [\"ApiOptionsMap is missing some KnownApi values\", Exclude<Api, keyof ApiOptionsMap>]\n\t: [\"ApiOptionsMap doesn't extend Record<KnownApi, StreamOptions>\"];\nconst _exhaustive: _CheckExhaustive = true;\n\n// Helper type to get options for a specific API\nexport type OptionsForApi<TApi extends Api> = ApiOptionsMap[TApi];\n\nexport type KnownProvider =\n\t| \"anthropic\"\n\t| \"google\"\n\t| \"google-gemini-cli\"\n\t| \"google-antigravity\"\n\t| \"google-vertex\"\n\t| \"openai\"\n\t| \"openai-codex\"\n\t| \"github-copilot\"\n\t| \"xai\"\n\t| \"groq\"\n\t| \"cerebras\"\n\t| \"openrouter\"\n\t| \"zai\"\n\t| \"mistral\"\n\t| \"opencode\";\nexport type Provider = KnownProvider | string;\n\nexport type ThinkingLevel = \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n\n/** Token budgets for each thinking level (token-based providers only) */\nexport interface ThinkingBudgets {\n\tminimal?: number;\n\tlow?: number;\n\tmedium?: number;\n\thigh?: number;\n}\n\n// Base options all providers share\nexport interface StreamOptions {\n\ttemperature?: number;\n\tmaxTokens?: number;\n\tsignal?: AbortSignal;\n\tapiKey?: string;\n\t/**\n\t * Optional session identifier for providers that support session-based caching.\n\t * Providers can use this to enable prompt caching, request routing, or other\n\t * session-aware features. Ignored by providers that don't support it.\n\t */\n\tsessionId?: string;\n}\n\n// Unified options with reasoning passed to streamSimple() and completeSimple()\nexport interface SimpleStreamOptions extends StreamOptions {\n\treasoning?: ThinkingLevel;\n\t/** Custom token budgets for thinking levels (token-based providers only) */\n\tthinkingBudgets?: ThinkingBudgets;\n}\n\n// Generic StreamFunction with typed options\nexport type StreamFunction<TApi extends Api> = (\n\tmodel: Model<TApi>,\n\tcontext: Context,\n\toptions: OptionsForApi<TApi>,\n) => AssistantMessageEventStream;\n\nexport interface TextContent {\n\ttype: \"text\";\n\ttext: string;\n\ttextSignature?: string; // e.g., for OpenAI responses, the message ID\n}\n\nexport interface ThinkingContent {\n\ttype: \"thinking\";\n\tthinking: string;\n\tthinkingSignature?: string; // e.g., for OpenAI responses, the reasoning item ID\n}\n\nexport interface ImageContent {\n\ttype: \"image\";\n\tdata: string; // base64 encoded image data\n\tmimeType: string; // e.g., \"image/jpeg\", \"image/png\"\n}\n\nexport interface ToolCall {\n\ttype: \"toolCall\";\n\tid: string;\n\tname: string;\n\targuments: Record<string, any>;\n\tthoughtSignature?: string; // Google-specific: opaque signature for reusing thought context\n}\n\nexport interface Usage {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\ttotalTokens: number;\n\tcost: {\n\t\tinput: number;\n\t\toutput: number;\n\t\tcacheRead: number;\n\t\tcacheWrite: number;\n\t\ttotal: number;\n\t};\n}\n\nexport type StopReason = \"stop\" | \"length\" | \"toolUse\" | \"error\" | \"aborted\";\n\nexport interface UserMessage {\n\trole: \"user\";\n\tcontent: string | (TextContent | ImageContent)[];\n\ttimestamp: number; // Unix timestamp in milliseconds\n}\n\nexport interface AssistantMessage {\n\trole: \"assistant\";\n\tcontent: (TextContent | ThinkingContent | ToolCall)[];\n\tapi: Api;\n\tprovider: Provider;\n\tmodel: string;\n\tusage: Usage;\n\tstopReason: StopReason;\n\terrorMessage?: string;\n\ttimestamp: number; // Unix timestamp in milliseconds\n}\n\nexport interface ToolResultMessage<TDetails = any> {\n\trole: \"toolResult\";\n\ttoolCallId: string;\n\ttoolName: string;\n\tcontent: (TextContent | ImageContent)[]; // Supports text and images\n\tdetails?: TDetails;\n\tisError: boolean;\n\ttimestamp: number; // Unix timestamp in milliseconds\n}\n\nexport type Message = UserMessage | AssistantMessage | ToolResultMessage;\n\nimport type { TSchema } from \"@sinclair/typebox\";\n\nexport interface Tool<TParameters extends TSchema = TSchema> {\n\tname: string;\n\tdescription: string;\n\tparameters: TParameters;\n}\n\nexport interface Context {\n\tsystemPrompt?: string;\n\tmessages: Message[];\n\ttools?: Tool[];\n}\n\nexport type AssistantMessageEvent =\n\t| { type: \"start\"; partial: AssistantMessage }\n\t| { type: \"text_start\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"text_delta\"; contentIndex: number; delta: string; partial: AssistantMessage }\n\t| { type: \"text_end\"; contentIndex: number; content: string; partial: AssistantMessage }\n\t| { type: \"thinking_start\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"thinking_delta\"; contentIndex: number; delta: string; partial: AssistantMessage }\n\t| { type: \"thinking_end\"; contentIndex: number; content: string; partial: AssistantMessage }\n\t| { type: \"toolcall_start\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"toolcall_delta\"; contentIndex: number; delta: string; partial: AssistantMessage }\n\t| { type: \"toolcall_end\"; contentIndex: number; toolCall: ToolCall; partial: AssistantMessage }\n\t| { type: \"done\"; reason: Extract<StopReason, \"stop\" | \"length\" | \"toolUse\">; message: AssistantMessage }\n\t| { type: \"error\"; reason: Extract<StopReason, \"aborted\" | \"error\">; error: AssistantMessage };\n\n/**\n * Compatibility settings for openai-completions API.\n * Use this to override URL-based auto-detection for custom providers.\n */\nexport interface OpenAICompat {\n\t/** Whether the provider supports the `store` field. Default: auto-detected from URL. */\n\tsupportsStore?: boolean;\n\t/** Whether the provider supports the `developer` role (vs `system`). Default: auto-detected from URL. */\n\tsupportsDeveloperRole?: boolean;\n\t/** Whether the provider supports `reasoning_effort`. Default: auto-detected from URL. */\n\tsupportsReasoningEffort?: boolean;\n\t/** Which field to use for max tokens. Default: auto-detected from URL. */\n\tmaxTokensField?: \"max_completion_tokens\" | \"max_tokens\";\n\t/** Whether tool results require the `name` field. Default: auto-detected from URL. */\n\trequiresToolResultName?: boolean;\n\t/** Whether a user message after tool results requires an assistant message in between. Default: auto-detected from URL. */\n\trequiresAssistantAfterToolResult?: boolean;\n\t/** Whether thinking blocks must be converted to text blocks with <thinking> delimiters. Default: auto-detected from URL. */\n\trequiresThinkingAsText?: boolean;\n\t/** Whether tool call IDs must be normalized to Mistral format (exactly 9 alphanumeric chars). Default: auto-detected from URL. */\n\trequiresMistralToolIds?: boolean;\n}\n\n// Model interface for the unified model system\nexport interface Model<TApi extends Api> {\n\tid: string;\n\tname: string;\n\tapi: TApi;\n\tprovider: Provider;\n\tbaseUrl: string;\n\treasoning: boolean;\n\tinput: (\"text\" | \"image\")[];\n\tcost: {\n\t\tinput: number; // $/million tokens\n\t\toutput: number; // $/million tokens\n\t\tcacheRead: number; // $/million tokens\n\t\tcacheWrite: number; // $/million tokens\n\t};\n\tcontextWindow: number;\n\tmaxTokens: number;\n\theaders?: Record<string, string>;\n\t/** Compatibility overrides for openai-completions API. If not set, auto-detected from baseUrl. */\n\tcompat?: TApi extends \"openai-completions\" ? OpenAICompat : never;\n}\n"]}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Anthropic OAuth flow (Claude Pro/Max)
3
+ */
4
+ import type { OAuthCredentials } from "./types.js";
5
+ /**
6
+ * Login with Anthropic OAuth (device code flow)
7
+ *
8
+ * @param onAuthUrl - Callback to handle the authorization URL (e.g., open browser)
9
+ * @param onPromptCode - Callback to prompt user for the authorization code
10
+ */
11
+ export declare function loginAnthropic(onAuthUrl: (url: string) => void, onPromptCode: () => Promise<string>): Promise<OAuthCredentials>;
12
+ /**
13
+ * Refresh Anthropic OAuth token
14
+ */
15
+ export declare function refreshAnthropicToken(refreshToken: string): Promise<OAuthCredentials>;
16
+ //# sourceMappingURL=anthropic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../src/utils/oauth/anthropic.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AASnD;;;;;GAKG;AACH,wBAAsB,cAAc,CACnC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,EAChC,YAAY,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GACjC,OAAO,CAAC,gBAAgB,CAAC,CA8D3B;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA2B3F","sourcesContent":["/**\n * Anthropic OAuth flow (Claude Pro/Max)\n */\n\nimport { generatePKCE } from \"./pkce.js\";\nimport type { OAuthCredentials } from \"./types.js\";\n\nconst decode = (s: string) => atob(s);\nconst CLIENT_ID = decode(\"OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl\");\nconst AUTHORIZE_URL = \"https://claude.ai/oauth/authorize\";\nconst TOKEN_URL = \"https://console.anthropic.com/v1/oauth/token\";\nconst REDIRECT_URI = \"https://console.anthropic.com/oauth/code/callback\";\nconst SCOPES = \"org:create_api_key user:profile user:inference\";\n\n/**\n * Login with Anthropic OAuth (device code flow)\n *\n * @param onAuthUrl - Callback to handle the authorization URL (e.g., open browser)\n * @param onPromptCode - Callback to prompt user for the authorization code\n */\nexport async function loginAnthropic(\n\tonAuthUrl: (url: string) => void,\n\tonPromptCode: () => Promise<string>,\n): Promise<OAuthCredentials> {\n\tconst { verifier, challenge } = await generatePKCE();\n\n\t// Build authorization URL\n\tconst authParams = new URLSearchParams({\n\t\tcode: \"true\",\n\t\tclient_id: CLIENT_ID,\n\t\tresponse_type: \"code\",\n\t\tredirect_uri: REDIRECT_URI,\n\t\tscope: SCOPES,\n\t\tcode_challenge: challenge,\n\t\tcode_challenge_method: \"S256\",\n\t\tstate: verifier,\n\t});\n\n\tconst authUrl = `${AUTHORIZE_URL}?${authParams.toString()}`;\n\n\t// Notify caller with URL to open\n\tonAuthUrl(authUrl);\n\n\t// Wait for user to paste authorization code (format: code#state)\n\tconst authCode = await onPromptCode();\n\tconst splits = authCode.split(\"#\");\n\tconst code = splits[0];\n\tconst state = splits[1];\n\n\t// Exchange code for tokens\n\tconst tokenResponse = await fetch(TOKEN_URL, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t},\n\t\tbody: JSON.stringify({\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tcode: code,\n\t\t\tstate: state,\n\t\t\tredirect_uri: REDIRECT_URI,\n\t\t\tcode_verifier: verifier,\n\t\t}),\n\t});\n\n\tif (!tokenResponse.ok) {\n\t\tconst error = await tokenResponse.text();\n\t\tthrow new Error(`Token exchange failed: ${error}`);\n\t}\n\n\tconst tokenData = (await tokenResponse.json()) as {\n\t\taccess_token: string;\n\t\trefresh_token: string;\n\t\texpires_in: number;\n\t};\n\n\t// Calculate expiry time (current time + expires_in seconds - 5 min buffer)\n\tconst expiresAt = Date.now() + tokenData.expires_in * 1000 - 5 * 60 * 1000;\n\n\t// Save credentials\n\treturn {\n\t\trefresh: tokenData.refresh_token,\n\t\taccess: tokenData.access_token,\n\t\texpires: expiresAt,\n\t};\n}\n\n/**\n * Refresh Anthropic OAuth token\n */\nexport async function refreshAnthropicToken(refreshToken: string): Promise<OAuthCredentials> {\n\tconst response = await fetch(TOKEN_URL, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\tbody: JSON.stringify({\n\t\t\tgrant_type: \"refresh_token\",\n\t\t\tclient_id: CLIENT_ID,\n\t\t\trefresh_token: refreshToken,\n\t\t}),\n\t});\n\n\tif (!response.ok) {\n\t\tconst error = await response.text();\n\t\tthrow new Error(`Anthropic token refresh failed: ${error}`);\n\t}\n\n\tconst data = (await response.json()) as {\n\t\taccess_token: string;\n\t\trefresh_token: string;\n\t\texpires_in: number;\n\t};\n\n\treturn {\n\t\trefresh: data.refresh_token,\n\t\taccess: data.access_token,\n\t\texpires: Date.now() + data.expires_in * 1000 - 5 * 60 * 1000,\n\t};\n}\n"]}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Anthropic OAuth flow (Claude Pro/Max)
3
+ */
4
+ import { generatePKCE } from "./pkce.js";
5
+ const decode = (s) => atob(s);
6
+ const CLIENT_ID = decode("OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl");
7
+ const AUTHORIZE_URL = "https://claude.ai/oauth/authorize";
8
+ const TOKEN_URL = "https://console.anthropic.com/v1/oauth/token";
9
+ const REDIRECT_URI = "https://console.anthropic.com/oauth/code/callback";
10
+ const SCOPES = "org:create_api_key user:profile user:inference";
11
+ /**
12
+ * Login with Anthropic OAuth (device code flow)
13
+ *
14
+ * @param onAuthUrl - Callback to handle the authorization URL (e.g., open browser)
15
+ * @param onPromptCode - Callback to prompt user for the authorization code
16
+ */
17
+ export async function loginAnthropic(onAuthUrl, onPromptCode) {
18
+ const { verifier, challenge } = await generatePKCE();
19
+ // Build authorization URL
20
+ const authParams = new URLSearchParams({
21
+ code: "true",
22
+ client_id: CLIENT_ID,
23
+ response_type: "code",
24
+ redirect_uri: REDIRECT_URI,
25
+ scope: SCOPES,
26
+ code_challenge: challenge,
27
+ code_challenge_method: "S256",
28
+ state: verifier,
29
+ });
30
+ const authUrl = `${AUTHORIZE_URL}?${authParams.toString()}`;
31
+ // Notify caller with URL to open
32
+ onAuthUrl(authUrl);
33
+ // Wait for user to paste authorization code (format: code#state)
34
+ const authCode = await onPromptCode();
35
+ const splits = authCode.split("#");
36
+ const code = splits[0];
37
+ const state = splits[1];
38
+ // Exchange code for tokens
39
+ const tokenResponse = await fetch(TOKEN_URL, {
40
+ method: "POST",
41
+ headers: {
42
+ "Content-Type": "application/json",
43
+ },
44
+ body: JSON.stringify({
45
+ grant_type: "authorization_code",
46
+ client_id: CLIENT_ID,
47
+ code: code,
48
+ state: state,
49
+ redirect_uri: REDIRECT_URI,
50
+ code_verifier: verifier,
51
+ }),
52
+ });
53
+ if (!tokenResponse.ok) {
54
+ const error = await tokenResponse.text();
55
+ throw new Error(`Token exchange failed: ${error}`);
56
+ }
57
+ const tokenData = (await tokenResponse.json());
58
+ // Calculate expiry time (current time + expires_in seconds - 5 min buffer)
59
+ const expiresAt = Date.now() + tokenData.expires_in * 1000 - 5 * 60 * 1000;
60
+ // Save credentials
61
+ return {
62
+ refresh: tokenData.refresh_token,
63
+ access: tokenData.access_token,
64
+ expires: expiresAt,
65
+ };
66
+ }
67
+ /**
68
+ * Refresh Anthropic OAuth token
69
+ */
70
+ export async function refreshAnthropicToken(refreshToken) {
71
+ const response = await fetch(TOKEN_URL, {
72
+ method: "POST",
73
+ headers: { "Content-Type": "application/json" },
74
+ body: JSON.stringify({
75
+ grant_type: "refresh_token",
76
+ client_id: CLIENT_ID,
77
+ refresh_token: refreshToken,
78
+ }),
79
+ });
80
+ if (!response.ok) {
81
+ const error = await response.text();
82
+ throw new Error(`Anthropic token refresh failed: ${error}`);
83
+ }
84
+ const data = (await response.json());
85
+ return {
86
+ refresh: data.refresh_token,
87
+ access: data.access_token,
88
+ expires: Date.now() + data.expires_in * 1000 - 5 * 60 * 1000,
89
+ };
90
+ }
91
+ //# sourceMappingURL=anthropic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../src/utils/oauth/anthropic.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGzC,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACtC,MAAM,SAAS,GAAG,MAAM,CAAC,kDAAkD,CAAC,CAAC;AAC7E,MAAM,aAAa,GAAG,mCAAmC,CAAC;AAC1D,MAAM,SAAS,GAAG,8CAA8C,CAAC;AACjE,MAAM,YAAY,GAAG,mDAAmD,CAAC;AACzE,MAAM,MAAM,GAAG,gDAAgD,CAAC;AAEhE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CACnC,SAAgC,EAChC,YAAmC,EACP;IAC5B,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,YAAY,EAAE,CAAC;IAErD,0BAA0B;IAC1B,MAAM,UAAU,GAAG,IAAI,eAAe,CAAC;QACtC,IAAI,EAAE,MAAM;QACZ,SAAS,EAAE,SAAS;QACpB,aAAa,EAAE,MAAM;QACrB,YAAY,EAAE,YAAY;QAC1B,KAAK,EAAE,MAAM;QACb,cAAc,EAAE,SAAS;QACzB,qBAAqB,EAAE,MAAM;QAC7B,KAAK,EAAE,QAAQ;KACf,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,GAAG,aAAa,IAAI,UAAU,CAAC,QAAQ,EAAE,EAAE,CAAC;IAE5D,iCAAiC;IACjC,SAAS,CAAC,OAAO,CAAC,CAAC;IAEnB,iEAAiE;IACjE,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACvB,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAExB,2BAA2B;IAC3B,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;QAC5C,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACR,cAAc,EAAE,kBAAkB;SAClC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACpB,UAAU,EAAE,oBAAoB;YAChC,SAAS,EAAE,SAAS;YACpB,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,KAAK;YACZ,YAAY,EAAE,YAAY;YAC1B,aAAa,EAAE,QAAQ;SACvB,CAAC;KACF,CAAC,CAAC;IAEH,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,SAAS,GAAG,CAAC,MAAM,aAAa,CAAC,IAAI,EAAE,CAI5C,CAAC;IAEF,2EAA2E;IAC3E,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,UAAU,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;IAE3E,mBAAmB;IACnB,OAAO;QACN,OAAO,EAAE,SAAS,CAAC,aAAa;QAChC,MAAM,EAAE,SAAS,CAAC,YAAY;QAC9B,OAAO,EAAE,SAAS;KAClB,CAAC;AAAA,CACF;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,YAAoB,EAA6B;IAC5F,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;QACvC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACpB,UAAU,EAAE,eAAe;YAC3B,SAAS,EAAE,SAAS;YACpB,aAAa,EAAE,YAAY;SAC3B,CAAC;KACF,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QAClB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,mCAAmC,KAAK,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAIlC,CAAC;IAEF,OAAO;QACN,OAAO,EAAE,IAAI,CAAC,aAAa;QAC3B,MAAM,EAAE,IAAI,CAAC,YAAY;QACzB,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI;KAC5D,CAAC;AAAA,CACF","sourcesContent":["/**\n * Anthropic OAuth flow (Claude Pro/Max)\n */\n\nimport { generatePKCE } from \"./pkce.js\";\nimport type { OAuthCredentials } from \"./types.js\";\n\nconst decode = (s: string) => atob(s);\nconst CLIENT_ID = decode(\"OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl\");\nconst AUTHORIZE_URL = \"https://claude.ai/oauth/authorize\";\nconst TOKEN_URL = \"https://console.anthropic.com/v1/oauth/token\";\nconst REDIRECT_URI = \"https://console.anthropic.com/oauth/code/callback\";\nconst SCOPES = \"org:create_api_key user:profile user:inference\";\n\n/**\n * Login with Anthropic OAuth (device code flow)\n *\n * @param onAuthUrl - Callback to handle the authorization URL (e.g., open browser)\n * @param onPromptCode - Callback to prompt user for the authorization code\n */\nexport async function loginAnthropic(\n\tonAuthUrl: (url: string) => void,\n\tonPromptCode: () => Promise<string>,\n): Promise<OAuthCredentials> {\n\tconst { verifier, challenge } = await generatePKCE();\n\n\t// Build authorization URL\n\tconst authParams = new URLSearchParams({\n\t\tcode: \"true\",\n\t\tclient_id: CLIENT_ID,\n\t\tresponse_type: \"code\",\n\t\tredirect_uri: REDIRECT_URI,\n\t\tscope: SCOPES,\n\t\tcode_challenge: challenge,\n\t\tcode_challenge_method: \"S256\",\n\t\tstate: verifier,\n\t});\n\n\tconst authUrl = `${AUTHORIZE_URL}?${authParams.toString()}`;\n\n\t// Notify caller with URL to open\n\tonAuthUrl(authUrl);\n\n\t// Wait for user to paste authorization code (format: code#state)\n\tconst authCode = await onPromptCode();\n\tconst splits = authCode.split(\"#\");\n\tconst code = splits[0];\n\tconst state = splits[1];\n\n\t// Exchange code for tokens\n\tconst tokenResponse = await fetch(TOKEN_URL, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t},\n\t\tbody: JSON.stringify({\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tcode: code,\n\t\t\tstate: state,\n\t\t\tredirect_uri: REDIRECT_URI,\n\t\t\tcode_verifier: verifier,\n\t\t}),\n\t});\n\n\tif (!tokenResponse.ok) {\n\t\tconst error = await tokenResponse.text();\n\t\tthrow new Error(`Token exchange failed: ${error}`);\n\t}\n\n\tconst tokenData = (await tokenResponse.json()) as {\n\t\taccess_token: string;\n\t\trefresh_token: string;\n\t\texpires_in: number;\n\t};\n\n\t// Calculate expiry time (current time + expires_in seconds - 5 min buffer)\n\tconst expiresAt = Date.now() + tokenData.expires_in * 1000 - 5 * 60 * 1000;\n\n\t// Save credentials\n\treturn {\n\t\trefresh: tokenData.refresh_token,\n\t\taccess: tokenData.access_token,\n\t\texpires: expiresAt,\n\t};\n}\n\n/**\n * Refresh Anthropic OAuth token\n */\nexport async function refreshAnthropicToken(refreshToken: string): Promise<OAuthCredentials> {\n\tconst response = await fetch(TOKEN_URL, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\tbody: JSON.stringify({\n\t\t\tgrant_type: \"refresh_token\",\n\t\t\tclient_id: CLIENT_ID,\n\t\t\trefresh_token: refreshToken,\n\t\t}),\n\t});\n\n\tif (!response.ok) {\n\t\tconst error = await response.text();\n\t\tthrow new Error(`Anthropic token refresh failed: ${error}`);\n\t}\n\n\tconst data = (await response.json()) as {\n\t\taccess_token: string;\n\t\trefresh_token: string;\n\t\texpires_in: number;\n\t};\n\n\treturn {\n\t\trefresh: data.refresh_token,\n\t\taccess: data.access_token,\n\t\texpires: Date.now() + data.expires_in * 1000 - 5 * 60 * 1000,\n\t};\n}\n"]}
@@ -8,6 +8,7 @@
8
8
  * - Google Cloud Code Assist (Gemini CLI)
9
9
  * - Antigravity (Gemini 3, Claude, GPT-OSS via Google Cloud)
10
10
  */
11
+ export { loginAnthropic, refreshAnthropicToken } from "./anthropic.js";
11
12
  export { getGitHubCopilotBaseUrl, loginGitHubCopilot, normalizeDomain, refreshGitHubCopilotToken, } from "./github-copilot.js";
12
13
  export { loginAntigravity, refreshAntigravityToken, } from "./google-antigravity.js";
13
14
  export { loginGeminiCli, refreshGoogleCloudToken, } from "./google-gemini-cli.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/oauth/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EACN,uBAAuB,EACvB,kBAAkB,EAClB,eAAe,EACf,yBAAyB,GACzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACN,gBAAgB,EAChB,uBAAuB,GACvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACN,cAAc,EACd,uBAAuB,GACvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACN,gBAAgB,EAChB,uBAAuB,GACvB,MAAM,mBAAmB,CAAC;AAE3B,cAAc,YAAY,CAAC;AAU3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAErF;;;GAGG;AACH,wBAAsB,iBAAiB,CACtC,QAAQ,EAAE,aAAa,EACvB,WAAW,EAAE,gBAAgB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CA+B3B;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CACnC,QAAQ,EAAE,aAAa,EACvB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAC3C,OAAO,CAAC;IAAE,cAAc,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAmBtE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,iBAAiB,EAAE,CAuBvD","sourcesContent":["/**\n * OAuth credential management for AI providers.\n *\n * This module handles login, token refresh, and credential storage\n * for OAuth-based providers:\n * - Anthropic (Claude Pro/Max)\n * - GitHub Copilot\n * - Google Cloud Code Assist (Gemini CLI)\n * - Antigravity (Gemini 3, Claude, GPT-OSS via Google Cloud)\n */\n\n// GitHub Copilot\nexport {\n\tgetGitHubCopilotBaseUrl,\n\tloginGitHubCopilot,\n\tnormalizeDomain,\n\trefreshGitHubCopilotToken,\n} from \"./github-copilot.js\";\n// Google Antigravity\nexport {\n\tloginAntigravity,\n\trefreshAntigravityToken,\n} from \"./google-antigravity.js\";\n// Google Gemini CLI\nexport {\n\tloginGeminiCli,\n\trefreshGoogleCloudToken,\n} from \"./google-gemini-cli.js\";\n// OpenAI Codex (ChatGPT OAuth)\nexport {\n\tloginOpenAICodex,\n\trefreshOpenAICodexToken,\n} from \"./openai-codex.js\";\n\nexport * from \"./types.js\";\n\n// ============================================================================\n// High-level API\n// ============================================================================\n\nimport { refreshGitHubCopilotToken } from \"./github-copilot.js\";\nimport { refreshAntigravityToken } from \"./google-antigravity.js\";\nimport { refreshGoogleCloudToken } from \"./google-gemini-cli.js\";\nimport { refreshOpenAICodexToken } from \"./openai-codex.js\";\nimport type { OAuthCredentials, OAuthProvider, OAuthProviderInfo } from \"./types.js\";\n\n/**\n * Refresh token for any OAuth provider.\n * Saves the new credentials and returns the new access token.\n */\nexport async function refreshOAuthToken(\n\tprovider: OAuthProvider,\n\tcredentials: OAuthCredentials,\n): Promise<OAuthCredentials> {\n\tif (!credentials) {\n\t\tthrow new Error(`No OAuth credentials found for ${provider}`);\n\t}\n\n\tlet newCredentials: OAuthCredentials;\n\n\tswitch (provider) {\n\t\tcase \"github-copilot\":\n\t\t\tnewCredentials = await refreshGitHubCopilotToken(credentials.refresh, credentials.enterpriseUrl);\n\t\t\tbreak;\n\t\tcase \"google-gemini-cli\":\n\t\t\tif (!credentials.projectId) {\n\t\t\t\tthrow new Error(\"Google Cloud credentials missing projectId\");\n\t\t\t}\n\t\t\tnewCredentials = await refreshGoogleCloudToken(credentials.refresh, credentials.projectId);\n\t\t\tbreak;\n\t\tcase \"google-antigravity\":\n\t\t\tif (!credentials.projectId) {\n\t\t\t\tthrow new Error(\"Antigravity credentials missing projectId\");\n\t\t\t}\n\t\t\tnewCredentials = await refreshAntigravityToken(credentials.refresh, credentials.projectId);\n\t\t\tbreak;\n\t\tcase \"openai-codex\":\n\t\t\tnewCredentials = await refreshOpenAICodexToken(credentials.refresh);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown OAuth provider: ${provider}`);\n\t}\n\n\treturn newCredentials;\n}\n\n/**\n * Get API key for a provider from OAuth credentials.\n * Automatically refreshes expired tokens.\n *\n * For google-gemini-cli and antigravity, returns JSON-encoded { token, projectId }\n *\n * @returns API key string, or null if no credentials\n * @throws Error if refresh fails\n */\nexport async function getOAuthApiKey(\n\tprovider: OAuthProvider,\n\tcredentials: Record<string, OAuthCredentials>,\n): Promise<{ newCredentials: OAuthCredentials; apiKey: string } | null> {\n\tlet creds = credentials[provider];\n\tif (!creds) {\n\t\treturn null;\n\t}\n\n\t// Refresh if expired\n\tif (Date.now() >= creds.expires) {\n\t\ttry {\n\t\t\tcreds = await refreshOAuthToken(provider, creds);\n\t\t} catch (_error) {\n\t\t\tthrow new Error(`Failed to refresh OAuth token for ${provider}`);\n\t\t}\n\t}\n\n\t// For providers that need projectId, return JSON\n\tconst needsProjectId = provider === \"google-gemini-cli\" || provider === \"google-antigravity\";\n\tconst apiKey = needsProjectId ? JSON.stringify({ token: creds.access, projectId: creds.projectId }) : creds.access;\n\treturn { newCredentials: creds, apiKey };\n}\n\n/**\n * Get list of OAuth providers\n */\nexport function getOAuthProviders(): OAuthProviderInfo[] {\n\treturn [\n\t\t{\n\t\t\tid: \"openai-codex\",\n\t\t\tname: \"ChatGPT Plus/Pro (Codex Subscription)\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"github-copilot\",\n\t\t\tname: \"GitHub Copilot\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"google-gemini-cli\",\n\t\t\tname: \"Google Cloud Code Assist (Gemini CLI)\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"google-antigravity\",\n\t\t\tname: \"Antigravity (Gemini 3, Claude, GPT-OSS)\",\n\t\t\tavailable: true,\n\t\t},\n\t];\n}\n"]}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/oauth/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAEvE,OAAO,EACN,uBAAuB,EACvB,kBAAkB,EAClB,eAAe,EACf,yBAAyB,GACzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACN,gBAAgB,EAChB,uBAAuB,GACvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACN,cAAc,EACd,uBAAuB,GACvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACN,gBAAgB,EAChB,uBAAuB,GACvB,MAAM,mBAAmB,CAAC;AAE3B,cAAc,YAAY,CAAC;AAW3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAErF;;;GAGG;AACH,wBAAsB,iBAAiB,CACtC,QAAQ,EAAE,aAAa,EACvB,WAAW,EAAE,gBAAgB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CAkC3B;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CACnC,QAAQ,EAAE,aAAa,EACvB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAC3C,OAAO,CAAC;IAAE,cAAc,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAmBtE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,iBAAiB,EAAE,CA4BvD","sourcesContent":["/**\n * OAuth credential management for AI providers.\n *\n * This module handles login, token refresh, and credential storage\n * for OAuth-based providers:\n * - Anthropic (Claude Pro/Max)\n * - GitHub Copilot\n * - Google Cloud Code Assist (Gemini CLI)\n * - Antigravity (Gemini 3, Claude, GPT-OSS via Google Cloud)\n */\n\n// Anthropic\nexport { loginAnthropic, refreshAnthropicToken } from \"./anthropic.js\";\n// GitHub Copilot\nexport {\n\tgetGitHubCopilotBaseUrl,\n\tloginGitHubCopilot,\n\tnormalizeDomain,\n\trefreshGitHubCopilotToken,\n} from \"./github-copilot.js\";\n// Google Antigravity\nexport {\n\tloginAntigravity,\n\trefreshAntigravityToken,\n} from \"./google-antigravity.js\";\n// Google Gemini CLI\nexport {\n\tloginGeminiCli,\n\trefreshGoogleCloudToken,\n} from \"./google-gemini-cli.js\";\n// OpenAI Codex (ChatGPT OAuth)\nexport {\n\tloginOpenAICodex,\n\trefreshOpenAICodexToken,\n} from \"./openai-codex.js\";\n\nexport * from \"./types.js\";\n\n// ============================================================================\n// High-level API\n// ============================================================================\n\nimport { refreshAnthropicToken } from \"./anthropic.js\";\nimport { refreshGitHubCopilotToken } from \"./github-copilot.js\";\nimport { refreshAntigravityToken } from \"./google-antigravity.js\";\nimport { refreshGoogleCloudToken } from \"./google-gemini-cli.js\";\nimport { refreshOpenAICodexToken } from \"./openai-codex.js\";\nimport type { OAuthCredentials, OAuthProvider, OAuthProviderInfo } from \"./types.js\";\n\n/**\n * Refresh token for any OAuth provider.\n * Saves the new credentials and returns the new access token.\n */\nexport async function refreshOAuthToken(\n\tprovider: OAuthProvider,\n\tcredentials: OAuthCredentials,\n): Promise<OAuthCredentials> {\n\tif (!credentials) {\n\t\tthrow new Error(`No OAuth credentials found for ${provider}`);\n\t}\n\n\tlet newCredentials: OAuthCredentials;\n\n\tswitch (provider) {\n\t\tcase \"anthropic\":\n\t\t\tnewCredentials = await refreshAnthropicToken(credentials.refresh);\n\t\t\tbreak;\n\t\tcase \"github-copilot\":\n\t\t\tnewCredentials = await refreshGitHubCopilotToken(credentials.refresh, credentials.enterpriseUrl);\n\t\t\tbreak;\n\t\tcase \"google-gemini-cli\":\n\t\t\tif (!credentials.projectId) {\n\t\t\t\tthrow new Error(\"Google Cloud credentials missing projectId\");\n\t\t\t}\n\t\t\tnewCredentials = await refreshGoogleCloudToken(credentials.refresh, credentials.projectId);\n\t\t\tbreak;\n\t\tcase \"google-antigravity\":\n\t\t\tif (!credentials.projectId) {\n\t\t\t\tthrow new Error(\"Antigravity credentials missing projectId\");\n\t\t\t}\n\t\t\tnewCredentials = await refreshAntigravityToken(credentials.refresh, credentials.projectId);\n\t\t\tbreak;\n\t\tcase \"openai-codex\":\n\t\t\tnewCredentials = await refreshOpenAICodexToken(credentials.refresh);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown OAuth provider: ${provider}`);\n\t}\n\n\treturn newCredentials;\n}\n\n/**\n * Get API key for a provider from OAuth credentials.\n * Automatically refreshes expired tokens.\n *\n * For google-gemini-cli and antigravity, returns JSON-encoded { token, projectId }\n *\n * @returns API key string, or null if no credentials\n * @throws Error if refresh fails\n */\nexport async function getOAuthApiKey(\n\tprovider: OAuthProvider,\n\tcredentials: Record<string, OAuthCredentials>,\n): Promise<{ newCredentials: OAuthCredentials; apiKey: string } | null> {\n\tlet creds = credentials[provider];\n\tif (!creds) {\n\t\treturn null;\n\t}\n\n\t// Refresh if expired\n\tif (Date.now() >= creds.expires) {\n\t\ttry {\n\t\t\tcreds = await refreshOAuthToken(provider, creds);\n\t\t} catch (_error) {\n\t\t\tthrow new Error(`Failed to refresh OAuth token for ${provider}`);\n\t\t}\n\t}\n\n\t// For providers that need projectId, return JSON\n\tconst needsProjectId = provider === \"google-gemini-cli\" || provider === \"google-antigravity\";\n\tconst apiKey = needsProjectId ? JSON.stringify({ token: creds.access, projectId: creds.projectId }) : creds.access;\n\treturn { newCredentials: creds, apiKey };\n}\n\n/**\n * Get list of OAuth providers\n */\nexport function getOAuthProviders(): OAuthProviderInfo[] {\n\treturn [\n\t\t{\n\t\t\tid: \"anthropic\",\n\t\t\tname: \"Anthropic (Claude Pro/Max)\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"openai-codex\",\n\t\t\tname: \"ChatGPT Plus/Pro (Codex Subscription)\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"github-copilot\",\n\t\t\tname: \"GitHub Copilot\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"google-gemini-cli\",\n\t\t\tname: \"Google Cloud Code Assist (Gemini CLI)\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"google-antigravity\",\n\t\t\tname: \"Antigravity (Gemini 3, Claude, GPT-OSS)\",\n\t\t\tavailable: true,\n\t\t},\n\t];\n}\n"]}
@@ -8,6 +8,8 @@
8
8
  * - Google Cloud Code Assist (Gemini CLI)
9
9
  * - Antigravity (Gemini 3, Claude, GPT-OSS via Google Cloud)
10
10
  */
11
+ // Anthropic
12
+ export { loginAnthropic, refreshAnthropicToken } from "./anthropic.js";
11
13
  // GitHub Copilot
12
14
  export { getGitHubCopilotBaseUrl, loginGitHubCopilot, normalizeDomain, refreshGitHubCopilotToken, } from "./github-copilot.js";
13
15
  // Google Antigravity
@@ -20,6 +22,7 @@ export * from "./types.js";
20
22
  // ============================================================================
21
23
  // High-level API
22
24
  // ============================================================================
25
+ import { refreshAnthropicToken } from "./anthropic.js";
23
26
  import { refreshGitHubCopilotToken } from "./github-copilot.js";
24
27
  import { refreshAntigravityToken } from "./google-antigravity.js";
25
28
  import { refreshGoogleCloudToken } from "./google-gemini-cli.js";
@@ -34,6 +37,9 @@ export async function refreshOAuthToken(provider, credentials) {
34
37
  }
35
38
  let newCredentials;
36
39
  switch (provider) {
40
+ case "anthropic":
41
+ newCredentials = await refreshAnthropicToken(credentials.refresh);
42
+ break;
37
43
  case "github-copilot":
38
44
  newCredentials = await refreshGitHubCopilotToken(credentials.refresh, credentials.enterpriseUrl);
39
45
  break;
@@ -90,6 +96,11 @@ export async function getOAuthApiKey(provider, credentials) {
90
96
  */
91
97
  export function getOAuthProviders() {
92
98
  return [
99
+ {
100
+ id: "anthropic",
101
+ name: "Anthropic (Claude Pro/Max)",
102
+ available: true,
103
+ },
93
104
  {
94
105
  id: "openai-codex",
95
106
  name: "ChatGPT Plus/Pro (Codex Subscription)",
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/oauth/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * OAuth credential management for AI providers.\n *\n * This module handles login, token refresh, and credential storage\n * for OAuth-based providers:\n * - Anthropic (Claude Pro/Max)\n * - GitHub Copilot\n * - Google Cloud Code Assist (Gemini CLI)\n * - Antigravity (Gemini 3, Claude, GPT-OSS via Google Cloud)\n */\n\n// GitHub Copilot\nexport {\n\tgetGitHubCopilotBaseUrl,\n\tloginGitHubCopilot,\n\tnormalizeDomain,\n\trefreshGitHubCopilotToken,\n} from \"./github-copilot.js\";\n// Google Antigravity\nexport {\n\tloginAntigravity,\n\trefreshAntigravityToken,\n} from \"./google-antigravity.js\";\n// Google Gemini CLI\nexport {\n\tloginGeminiCli,\n\trefreshGoogleCloudToken,\n} from \"./google-gemini-cli.js\";\n// OpenAI Codex (ChatGPT OAuth)\nexport {\n\tloginOpenAICodex,\n\trefreshOpenAICodexToken,\n} from \"./openai-codex.js\";\n\nexport * from \"./types.js\";\n\n// ============================================================================\n// High-level API\n// ============================================================================\n\nimport { refreshGitHubCopilotToken } from \"./github-copilot.js\";\nimport { refreshAntigravityToken } from \"./google-antigravity.js\";\nimport { refreshGoogleCloudToken } from \"./google-gemini-cli.js\";\nimport { refreshOpenAICodexToken } from \"./openai-codex.js\";\nimport type { OAuthCredentials, OAuthProvider, OAuthProviderInfo } from \"./types.js\";\n\n/**\n * Refresh token for any OAuth provider.\n * Saves the new credentials and returns the new access token.\n */\nexport async function refreshOAuthToken(\n\tprovider: OAuthProvider,\n\tcredentials: OAuthCredentials,\n): Promise<OAuthCredentials> {\n\tif (!credentials) {\n\t\tthrow new Error(`No OAuth credentials found for ${provider}`);\n\t}\n\n\tlet newCredentials: OAuthCredentials;\n\n\tswitch (provider) {\n\t\tcase \"github-copilot\":\n\t\t\tnewCredentials = await refreshGitHubCopilotToken(credentials.refresh, credentials.enterpriseUrl);\n\t\t\tbreak;\n\t\tcase \"google-gemini-cli\":\n\t\t\tif (!credentials.projectId) {\n\t\t\t\tthrow new Error(\"Google Cloud credentials missing projectId\");\n\t\t\t}\n\t\t\tnewCredentials = await refreshGoogleCloudToken(credentials.refresh, credentials.projectId);\n\t\t\tbreak;\n\t\tcase \"google-antigravity\":\n\t\t\tif (!credentials.projectId) {\n\t\t\t\tthrow new Error(\"Antigravity credentials missing projectId\");\n\t\t\t}\n\t\t\tnewCredentials = await refreshAntigravityToken(credentials.refresh, credentials.projectId);\n\t\t\tbreak;\n\t\tcase \"openai-codex\":\n\t\t\tnewCredentials = await refreshOpenAICodexToken(credentials.refresh);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown OAuth provider: ${provider}`);\n\t}\n\n\treturn newCredentials;\n}\n\n/**\n * Get API key for a provider from OAuth credentials.\n * Automatically refreshes expired tokens.\n *\n * For google-gemini-cli and antigravity, returns JSON-encoded { token, projectId }\n *\n * @returns API key string, or null if no credentials\n * @throws Error if refresh fails\n */\nexport async function getOAuthApiKey(\n\tprovider: OAuthProvider,\n\tcredentials: Record<string, OAuthCredentials>,\n): Promise<{ newCredentials: OAuthCredentials; apiKey: string } | null> {\n\tlet creds = credentials[provider];\n\tif (!creds) {\n\t\treturn null;\n\t}\n\n\t// Refresh if expired\n\tif (Date.now() >= creds.expires) {\n\t\ttry {\n\t\t\tcreds = await refreshOAuthToken(provider, creds);\n\t\t} catch (_error) {\n\t\t\tthrow new Error(`Failed to refresh OAuth token for ${provider}`);\n\t\t}\n\t}\n\n\t// For providers that need projectId, return JSON\n\tconst needsProjectId = provider === \"google-gemini-cli\" || provider === \"google-antigravity\";\n\tconst apiKey = needsProjectId ? JSON.stringify({ token: creds.access, projectId: creds.projectId }) : creds.access;\n\treturn { newCredentials: creds, apiKey };\n}\n\n/**\n * Get list of OAuth providers\n */\nexport function getOAuthProviders(): OAuthProviderInfo[] {\n\treturn [\n\t\t{\n\t\t\tid: \"openai-codex\",\n\t\t\tname: \"ChatGPT Plus/Pro (Codex Subscription)\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"github-copilot\",\n\t\t\tname: \"GitHub Copilot\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"google-gemini-cli\",\n\t\t\tname: \"Google Cloud Code Assist (Gemini CLI)\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"google-antigravity\",\n\t\t\tname: \"Antigravity (Gemini 3, Claude, GPT-OSS)\",\n\t\t\tavailable: true,\n\t\t},\n\t];\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/oauth/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,YAAY;AACZ,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvE,iBAAiB;AACjB,OAAO,EACN,uBAAuB,EACvB,kBAAkB,EAClB,eAAe,EACf,yBAAyB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,qBAAqB;AACrB,OAAO,EACN,gBAAgB,EAChB,uBAAuB,GACvB,MAAM,yBAAyB,CAAC;AACjC,oBAAoB;AACpB,OAAO,EACN,cAAc,EACd,uBAAuB,GACvB,MAAM,wBAAwB,CAAC;AAChC,+BAA+B;AAC/B,OAAO,EACN,gBAAgB,EAChB,uBAAuB,GACvB,MAAM,mBAAmB,CAAC;AAE3B,cAAc,YAAY,CAAC;AAE3B,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAG5D;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACtC,QAAuB,EACvB,WAA6B,EACD;IAC5B,IAAI,CAAC,WAAW,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,kCAAkC,QAAQ,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED,IAAI,cAAgC,CAAC;IAErC,QAAQ,QAAQ,EAAE,CAAC;QAClB,KAAK,WAAW;YACf,cAAc,GAAG,MAAM,qBAAqB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YAClE,MAAM;QACP,KAAK,gBAAgB;YACpB,cAAc,GAAG,MAAM,yBAAyB,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;YACjG,MAAM;QACP,KAAK,mBAAmB;YACvB,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;YAC/D,CAAC;YACD,cAAc,GAAG,MAAM,uBAAuB,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;YAC3F,MAAM;QACP,KAAK,oBAAoB;YACxB,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;YAC9D,CAAC;YACD,cAAc,GAAG,MAAM,uBAAuB,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;YAC3F,MAAM;QACP,KAAK,cAAc;YAClB,cAAc,GAAG,MAAM,uBAAuB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YACpE,MAAM;QACP;YACC,MAAM,IAAI,KAAK,CAAC,2BAA2B,QAAQ,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,cAAc,CAAC;AAAA,CACtB;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CACnC,QAAuB,EACvB,WAA6C,EAC0B;IACvE,IAAI,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IAClC,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC;IACb,CAAC;IAED,qBAAqB;IACrB,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACjC,IAAI,CAAC;YACJ,KAAK,GAAG,MAAM,iBAAiB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,qCAAqC,QAAQ,EAAE,CAAC,CAAC;QAClE,CAAC;IACF,CAAC;IAED,iDAAiD;IACjD,MAAM,cAAc,GAAG,QAAQ,KAAK,mBAAmB,IAAI,QAAQ,KAAK,oBAAoB,CAAC;IAC7F,MAAM,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;IACnH,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAAA,CACzC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,GAAwB;IACxD,OAAO;QACN;YACC,EAAE,EAAE,WAAW;YACf,IAAI,EAAE,4BAA4B;YAClC,SAAS,EAAE,IAAI;SACf;QACD;YACC,EAAE,EAAE,cAAc;YAClB,IAAI,EAAE,uCAAuC;YAC7C,SAAS,EAAE,IAAI;SACf;QACD;YACC,EAAE,EAAE,gBAAgB;YACpB,IAAI,EAAE,gBAAgB;YACtB,SAAS,EAAE,IAAI;SACf;QACD;YACC,EAAE,EAAE,mBAAmB;YACvB,IAAI,EAAE,uCAAuC;YAC7C,SAAS,EAAE,IAAI;SACf;QACD;YACC,EAAE,EAAE,oBAAoB;YACxB,IAAI,EAAE,yCAAyC;YAC/C,SAAS,EAAE,IAAI;SACf;KACD,CAAC;AAAA,CACF","sourcesContent":["/**\n * OAuth credential management for AI providers.\n *\n * This module handles login, token refresh, and credential storage\n * for OAuth-based providers:\n * - Anthropic (Claude Pro/Max)\n * - GitHub Copilot\n * - Google Cloud Code Assist (Gemini CLI)\n * - Antigravity (Gemini 3, Claude, GPT-OSS via Google Cloud)\n */\n\n// Anthropic\nexport { loginAnthropic, refreshAnthropicToken } from \"./anthropic.js\";\n// GitHub Copilot\nexport {\n\tgetGitHubCopilotBaseUrl,\n\tloginGitHubCopilot,\n\tnormalizeDomain,\n\trefreshGitHubCopilotToken,\n} from \"./github-copilot.js\";\n// Google Antigravity\nexport {\n\tloginAntigravity,\n\trefreshAntigravityToken,\n} from \"./google-antigravity.js\";\n// Google Gemini CLI\nexport {\n\tloginGeminiCli,\n\trefreshGoogleCloudToken,\n} from \"./google-gemini-cli.js\";\n// OpenAI Codex (ChatGPT OAuth)\nexport {\n\tloginOpenAICodex,\n\trefreshOpenAICodexToken,\n} from \"./openai-codex.js\";\n\nexport * from \"./types.js\";\n\n// ============================================================================\n// High-level API\n// ============================================================================\n\nimport { refreshAnthropicToken } from \"./anthropic.js\";\nimport { refreshGitHubCopilotToken } from \"./github-copilot.js\";\nimport { refreshAntigravityToken } from \"./google-antigravity.js\";\nimport { refreshGoogleCloudToken } from \"./google-gemini-cli.js\";\nimport { refreshOpenAICodexToken } from \"./openai-codex.js\";\nimport type { OAuthCredentials, OAuthProvider, OAuthProviderInfo } from \"./types.js\";\n\n/**\n * Refresh token for any OAuth provider.\n * Saves the new credentials and returns the new access token.\n */\nexport async function refreshOAuthToken(\n\tprovider: OAuthProvider,\n\tcredentials: OAuthCredentials,\n): Promise<OAuthCredentials> {\n\tif (!credentials) {\n\t\tthrow new Error(`No OAuth credentials found for ${provider}`);\n\t}\n\n\tlet newCredentials: OAuthCredentials;\n\n\tswitch (provider) {\n\t\tcase \"anthropic\":\n\t\t\tnewCredentials = await refreshAnthropicToken(credentials.refresh);\n\t\t\tbreak;\n\t\tcase \"github-copilot\":\n\t\t\tnewCredentials = await refreshGitHubCopilotToken(credentials.refresh, credentials.enterpriseUrl);\n\t\t\tbreak;\n\t\tcase \"google-gemini-cli\":\n\t\t\tif (!credentials.projectId) {\n\t\t\t\tthrow new Error(\"Google Cloud credentials missing projectId\");\n\t\t\t}\n\t\t\tnewCredentials = await refreshGoogleCloudToken(credentials.refresh, credentials.projectId);\n\t\t\tbreak;\n\t\tcase \"google-antigravity\":\n\t\t\tif (!credentials.projectId) {\n\t\t\t\tthrow new Error(\"Antigravity credentials missing projectId\");\n\t\t\t}\n\t\t\tnewCredentials = await refreshAntigravityToken(credentials.refresh, credentials.projectId);\n\t\t\tbreak;\n\t\tcase \"openai-codex\":\n\t\t\tnewCredentials = await refreshOpenAICodexToken(credentials.refresh);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown OAuth provider: ${provider}`);\n\t}\n\n\treturn newCredentials;\n}\n\n/**\n * Get API key for a provider from OAuth credentials.\n * Automatically refreshes expired tokens.\n *\n * For google-gemini-cli and antigravity, returns JSON-encoded { token, projectId }\n *\n * @returns API key string, or null if no credentials\n * @throws Error if refresh fails\n */\nexport async function getOAuthApiKey(\n\tprovider: OAuthProvider,\n\tcredentials: Record<string, OAuthCredentials>,\n): Promise<{ newCredentials: OAuthCredentials; apiKey: string } | null> {\n\tlet creds = credentials[provider];\n\tif (!creds) {\n\t\treturn null;\n\t}\n\n\t// Refresh if expired\n\tif (Date.now() >= creds.expires) {\n\t\ttry {\n\t\t\tcreds = await refreshOAuthToken(provider, creds);\n\t\t} catch (_error) {\n\t\t\tthrow new Error(`Failed to refresh OAuth token for ${provider}`);\n\t\t}\n\t}\n\n\t// For providers that need projectId, return JSON\n\tconst needsProjectId = provider === \"google-gemini-cli\" || provider === \"google-antigravity\";\n\tconst apiKey = needsProjectId ? JSON.stringify({ token: creds.access, projectId: creds.projectId }) : creds.access;\n\treturn { newCredentials: creds, apiKey };\n}\n\n/**\n * Get list of OAuth providers\n */\nexport function getOAuthProviders(): OAuthProviderInfo[] {\n\treturn [\n\t\t{\n\t\t\tid: \"anthropic\",\n\t\t\tname: \"Anthropic (Claude Pro/Max)\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"openai-codex\",\n\t\t\tname: \"ChatGPT Plus/Pro (Codex Subscription)\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"github-copilot\",\n\t\t\tname: \"GitHub Copilot\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"google-gemini-cli\",\n\t\t\tname: \"Google Cloud Code Assist (Gemini CLI)\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"google-antigravity\",\n\t\t\tname: \"Antigravity (Gemini 3, Claude, GPT-OSS)\",\n\t\t\tavailable: true,\n\t\t},\n\t];\n}\n"]}
@@ -7,7 +7,7 @@ export type OAuthCredentials = {
7
7
  email?: string;
8
8
  accountId?: string;
9
9
  };
10
- export type OAuthProvider = "github-copilot" | "google-gemini-cli" | "google-antigravity" | "openai-codex";
10
+ export type OAuthProvider = "anthropic" | "github-copilot" | "google-gemini-cli" | "google-antigravity" | "openai-codex";
11
11
  export type OAuthPrompt = {
12
12
  message: string;
13
13
  placeholder?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/oauth/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,gBAAgB,GAAG,mBAAmB,GAAG,oBAAoB,GAAG,cAAc,CAAC;AAE3G,MAAM,MAAM,WAAW,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,iBAAiB;IACjC,EAAE,EAAE,aAAa,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACnB","sourcesContent":["export type OAuthCredentials = {\n\trefresh: string;\n\taccess: string;\n\texpires: number;\n\tenterpriseUrl?: string;\n\tprojectId?: string;\n\temail?: string;\n\taccountId?: string;\n};\n\nexport type OAuthProvider = \"github-copilot\" | \"google-gemini-cli\" | \"google-antigravity\" | \"openai-codex\";\n\nexport type OAuthPrompt = {\n\tmessage: string;\n\tplaceholder?: string;\n\tallowEmpty?: boolean;\n};\n\nexport type OAuthAuthInfo = {\n\turl: string;\n\tinstructions?: string;\n};\n\nexport interface OAuthProviderInfo {\n\tid: OAuthProvider;\n\tname: string;\n\tavailable: boolean;\n}\n"]}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/oauth/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,aAAa,GACtB,WAAW,GACX,gBAAgB,GAChB,mBAAmB,GACnB,oBAAoB,GACpB,cAAc,CAAC;AAElB,MAAM,MAAM,WAAW,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,iBAAiB;IACjC,EAAE,EAAE,aAAa,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACnB","sourcesContent":["export type OAuthCredentials = {\n\trefresh: string;\n\taccess: string;\n\texpires: number;\n\tenterpriseUrl?: string;\n\tprojectId?: string;\n\temail?: string;\n\taccountId?: string;\n};\n\nexport type OAuthProvider =\n\t| \"anthropic\"\n\t| \"github-copilot\"\n\t| \"google-gemini-cli\"\n\t| \"google-antigravity\"\n\t| \"openai-codex\";\n\nexport type OAuthPrompt = {\n\tmessage: string;\n\tplaceholder?: string;\n\tallowEmpty?: boolean;\n};\n\nexport type OAuthAuthInfo = {\n\turl: string;\n\tinstructions?: string;\n};\n\nexport interface OAuthProviderInfo {\n\tid: OAuthProvider;\n\tname: string;\n\tavailable: boolean;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/utils/oauth/types.ts"],"names":[],"mappings":"","sourcesContent":["export type OAuthCredentials = {\n\trefresh: string;\n\taccess: string;\n\texpires: number;\n\tenterpriseUrl?: string;\n\tprojectId?: string;\n\temail?: string;\n\taccountId?: string;\n};\n\nexport type OAuthProvider = \"github-copilot\" | \"google-gemini-cli\" | \"google-antigravity\" | \"openai-codex\";\n\nexport type OAuthPrompt = {\n\tmessage: string;\n\tplaceholder?: string;\n\tallowEmpty?: boolean;\n};\n\nexport type OAuthAuthInfo = {\n\turl: string;\n\tinstructions?: string;\n};\n\nexport interface OAuthProviderInfo {\n\tid: OAuthProvider;\n\tname: string;\n\tavailable: boolean;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/utils/oauth/types.ts"],"names":[],"mappings":"","sourcesContent":["export type OAuthCredentials = {\n\trefresh: string;\n\taccess: string;\n\texpires: number;\n\tenterpriseUrl?: string;\n\tprojectId?: string;\n\temail?: string;\n\taccountId?: string;\n};\n\nexport type OAuthProvider =\n\t| \"anthropic\"\n\t| \"github-copilot\"\n\t| \"google-gemini-cli\"\n\t| \"google-antigravity\"\n\t| \"openai-codex\";\n\nexport type OAuthPrompt = {\n\tmessage: string;\n\tplaceholder?: string;\n\tallowEmpty?: boolean;\n};\n\nexport type OAuthAuthInfo = {\n\turl: string;\n\tinstructions?: string;\n};\n\nexport interface OAuthProviderInfo {\n\tid: OAuthProvider;\n\tname: string;\n\tavailable: boolean;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mariozechner/pi-ai",
3
- "version": "0.40.1",
3
+ "version": "0.42.0",
4
4
  "description": "Unified LLM API with automatic model discovery and provider configuration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",