@tanstack/ai-llmgateway 0.1.12 → 0.2.1

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,5 +1,5 @@
1
1
  import { default as OpenAI } from 'openai';
2
- import { OpenAIBaseChatCompletionsTextAdapter } from '@tanstack/openai-base';
2
+ import { OpenAIBaseChatCompletionsTextAdapter, OpenAIBaseTextAdapterOptions } from '@tanstack/openai-base';
3
3
  import { Modality } from '@tanstack/ai';
4
4
  import { LLMGatewayChatModelToolCapabilitiesByName, LLMGatewayModelId, ResolveInputModalities, ResolveProviderOptions } from '../model-meta.js';
5
5
  import { LLMGatewayMessageMetadataByModality } from '../message-types.js';
@@ -8,7 +8,7 @@ type ResolveToolCapabilities<TModel extends string> = TModel extends keyof LLMGa
8
8
  /**
9
9
  * Configuration for LLM Gateway text adapter
10
10
  */
11
- export interface LLMGatewayTextConfig extends LLMGatewayClientConfig {
11
+ export interface LLMGatewayTextConfig extends LLMGatewayClientConfig, OpenAIBaseTextAdapterOptions {
12
12
  }
13
13
  /**
14
14
  * Re-export of the public provider options type
@@ -20,7 +20,7 @@ var LLMGatewayTextAdapter = class extends OpenAIBaseChatCompletionsTextAdapter {
20
20
  kind = "text";
21
21
  name = "llmgateway";
22
22
  constructor(config, model) {
23
- super(model, "llmgateway", new OpenAI(withLLMGatewayDefaults(config)));
23
+ super(model, "llmgateway", new OpenAI(withLLMGatewayDefaults(config)), config);
24
24
  }
25
25
  /**
26
26
  * Surfaces reasoning deltas during streaming. LLM Gateway normalizes
@@ -1 +1 @@
1
- {"version":3,"file":"text.js","names":[],"sources":["../../../src/adapters/text.ts"],"sourcesContent":["import OpenAI from 'openai'\nimport { OpenAIBaseChatCompletionsTextAdapter } from '@tanstack/openai-base'\nimport {\n getLLMGatewayApiKeyFromEnv,\n withLLMGatewayDefaults,\n} from '../utils/client'\nimport type { Modality } from '@tanstack/ai'\nimport type {\n LLMGatewayChatModelToolCapabilitiesByName,\n LLMGatewayModelId,\n ResolveInputModalities,\n ResolveProviderOptions,\n} from '../model-meta'\nimport type { LLMGatewayMessageMetadataByModality } from '../message-types'\nimport type { LLMGatewayClientConfig } from '../utils/client'\n\ntype ResolveToolCapabilities<TModel extends string> =\n TModel extends keyof LLMGatewayChatModelToolCapabilitiesByName\n ? NonNullable<LLMGatewayChatModelToolCapabilitiesByName[TModel]>\n : readonly []\n\n/**\n * Configuration for LLM Gateway text adapter\n */\nexport interface LLMGatewayTextConfig extends LLMGatewayClientConfig {}\n\n/**\n * Re-export of the public provider options type\n */\nexport type { ExternalTextProviderOptions as LLMGatewayTextProviderOptions } from '../text/text-provider-options'\n\n/**\n * LLM Gateway Text (Chat) Adapter\n *\n * Tree-shakeable adapter for LLM Gateway chat/text completion. LLM Gateway\n * exposes one OpenAI-compatible Chat Completions endpoint that routes to\n * hundreds of models across many providers, so the adapter drives it with\n * the OpenAI SDK via a `baseURL` override (the same pattern as `ai-grok`\n * and `ai-groq`).\n *\n * Model ids are open-ended: curated ids get per-model type metadata, and\n * any other id from https://llmgateway.io/models works with text-only\n * defaults. A `provider/model` id (e.g. `openai/gpt-5.5`) pins routing to\n * that provider; a bare id lets the gateway pick.\n */\nexport class LLMGatewayTextAdapter<\n TModel extends LLMGatewayModelId,\n TProviderOptions extends Record<string, any> = ResolveProviderOptions<TModel>,\n TInputModalities extends ReadonlyArray<Modality> =\n ResolveInputModalities<TModel>,\n TToolCapabilities extends ReadonlyArray<string> =\n ResolveToolCapabilities<TModel>,\n> extends OpenAIBaseChatCompletionsTextAdapter<\n TModel,\n TProviderOptions,\n TInputModalities,\n LLMGatewayMessageMetadataByModality,\n TToolCapabilities\n> {\n override readonly kind = 'text' as const\n override readonly name = 'llmgateway' as const\n\n constructor(config: LLMGatewayTextConfig, model: TModel) {\n super(model, 'llmgateway', new OpenAI(withLLMGatewayDefaults(config)))\n }\n\n /**\n * Surfaces reasoning deltas during streaming. LLM Gateway normalizes\n * upstream reasoning output to `delta.reasoning_content` on the OpenAI\n * Chat Completions wire format (the DeepSeek-style field most\n * OpenAI-compatible providers emit); some routed providers emit\n * `delta.reasoning` instead, so both are read.\n */\n protected override extractReasoning(\n chunk: OpenAI.Chat.Completions.ChatCompletionChunk,\n ): { text: string } | undefined {\n const delta = chunk.choices[0]?.delta as\n | { reasoning?: unknown; reasoning_content?: unknown }\n | undefined\n const raw = delta?.reasoning_content ?? delta?.reasoning\n if (typeof raw === 'string' && raw.length > 0) {\n return { text: raw }\n }\n return undefined\n }\n}\n\n/**\n * Creates an LLM Gateway text adapter with explicit API key.\n *\n * @example\n * ```typescript\n * const adapter = createLLMGatewayText('gpt-5.6-terra', \"llmgtwy_...\");\n * ```\n */\nexport function createLLMGatewayText<TModel extends LLMGatewayModelId>(\n model: TModel,\n apiKey: string,\n config?: Omit<LLMGatewayTextConfig, 'apiKey'>,\n): LLMGatewayTextAdapter<TModel> {\n return new LLMGatewayTextAdapter({ apiKey, ...config }, model)\n}\n\n/**\n * Creates an LLM Gateway text adapter with API key from\n * `LLM_GATEWAY_API_KEY`.\n *\n * @example\n * ```typescript\n * const adapter = llmGatewayText('gpt-5.6-terra');\n * ```\n */\nexport function llmGatewayText<TModel extends LLMGatewayModelId>(\n model: TModel,\n config?: Omit<LLMGatewayTextConfig, 'apiKey'>,\n): LLMGatewayTextAdapter<TModel> {\n const apiKey = getLLMGatewayApiKeyFromEnv()\n return createLLMGatewayText(model, apiKey, config)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AA6CA,IAAa,wBAAb,cAOU,qCAMR;CACA,OAAyB;CACzB,OAAyB;CAEzB,YAAY,QAA8B,OAAe;EACvD,MAAM,OAAO,cAAc,IAAI,OAAO,uBAAuB,MAAM,CAAC,CAAC;CACvE;;;;;;;;CASA,iBACE,OAC8B;EAC9B,MAAM,QAAQ,MAAM,QAAQ,EAAE,EAAE;EAGhC,MAAM,MAAM,OAAO,qBAAqB,OAAO;EAC/C,IAAI,OAAO,QAAQ,YAAY,IAAI,SAAS,GAC1C,OAAO,EAAE,MAAM,IAAI;CAGvB;AACF;;;;;;;;;AAUA,SAAgB,qBACd,OACA,QACA,QAC+B;CAC/B,OAAO,IAAI,sBAAsB;EAAE;EAAQ,GAAG;CAAO,GAAG,KAAK;AAC/D;;;;;;;;;;AAWA,SAAgB,eACd,OACA,QAC+B;CAE/B,OAAO,qBAAqB,OADb,2BACoB,GAAQ,MAAM;AACnD"}
1
+ {"version":3,"file":"text.js","names":[],"sources":["../../../src/adapters/text.ts"],"sourcesContent":["import OpenAI from 'openai'\nimport { OpenAIBaseChatCompletionsTextAdapter } from '@tanstack/openai-base'\nimport {\n getLLMGatewayApiKeyFromEnv,\n withLLMGatewayDefaults,\n} from '../utils/client'\nimport type { Modality } from '@tanstack/ai'\nimport type {\n LLMGatewayChatModelToolCapabilitiesByName,\n LLMGatewayModelId,\n ResolveInputModalities,\n ResolveProviderOptions,\n} from '../model-meta'\nimport type { LLMGatewayMessageMetadataByModality } from '../message-types'\nimport type { LLMGatewayClientConfig } from '../utils/client'\nimport type { OpenAIBaseTextAdapterOptions } from '@tanstack/openai-base'\n\ntype ResolveToolCapabilities<TModel extends string> =\n TModel extends keyof LLMGatewayChatModelToolCapabilitiesByName\n ? NonNullable<LLMGatewayChatModelToolCapabilitiesByName[TModel]>\n : readonly []\n\n/**\n * Configuration for LLM Gateway text adapter\n */\nexport interface LLMGatewayTextConfig\n extends LLMGatewayClientConfig, OpenAIBaseTextAdapterOptions {}\n\n/**\n * Re-export of the public provider options type\n */\nexport type { ExternalTextProviderOptions as LLMGatewayTextProviderOptions } from '../text/text-provider-options'\n\n/**\n * LLM Gateway Text (Chat) Adapter\n *\n * Tree-shakeable adapter for LLM Gateway chat/text completion. LLM Gateway\n * exposes one OpenAI-compatible Chat Completions endpoint that routes to\n * hundreds of models across many providers, so the adapter drives it with\n * the OpenAI SDK via a `baseURL` override (the same pattern as `ai-grok`\n * and `ai-groq`).\n *\n * Model ids are open-ended: curated ids get per-model type metadata, and\n * any other id from https://llmgateway.io/models works with text-only\n * defaults. A `provider/model` id (e.g. `openai/gpt-5.5`) pins routing to\n * that provider; a bare id lets the gateway pick.\n */\nexport class LLMGatewayTextAdapter<\n TModel extends LLMGatewayModelId,\n TProviderOptions extends Record<string, any> = ResolveProviderOptions<TModel>,\n TInputModalities extends ReadonlyArray<Modality> =\n ResolveInputModalities<TModel>,\n TToolCapabilities extends ReadonlyArray<string> =\n ResolveToolCapabilities<TModel>,\n> extends OpenAIBaseChatCompletionsTextAdapter<\n TModel,\n TProviderOptions,\n TInputModalities,\n LLMGatewayMessageMetadataByModality,\n TToolCapabilities\n> {\n override readonly kind = 'text' as const\n override readonly name = 'llmgateway' as const\n\n constructor(config: LLMGatewayTextConfig, model: TModel) {\n super(\n model,\n 'llmgateway',\n new OpenAI(withLLMGatewayDefaults(config)),\n config,\n )\n }\n\n /**\n * Surfaces reasoning deltas during streaming. LLM Gateway normalizes\n * upstream reasoning output to `delta.reasoning_content` on the OpenAI\n * Chat Completions wire format (the DeepSeek-style field most\n * OpenAI-compatible providers emit); some routed providers emit\n * `delta.reasoning` instead, so both are read.\n */\n protected override extractReasoning(\n chunk: OpenAI.Chat.Completions.ChatCompletionChunk,\n ): { text: string } | undefined {\n const delta = chunk.choices[0]?.delta as\n | { reasoning?: unknown; reasoning_content?: unknown }\n | undefined\n const raw = delta?.reasoning_content ?? delta?.reasoning\n if (typeof raw === 'string' && raw.length > 0) {\n return { text: raw }\n }\n return undefined\n }\n}\n\n/**\n * Creates an LLM Gateway text adapter with explicit API key.\n *\n * @example\n * ```typescript\n * const adapter = createLLMGatewayText('gpt-5.6-terra', \"llmgtwy_...\");\n * ```\n */\nexport function createLLMGatewayText<TModel extends LLMGatewayModelId>(\n model: TModel,\n apiKey: string,\n config?: Omit<LLMGatewayTextConfig, 'apiKey'>,\n): LLMGatewayTextAdapter<TModel> {\n return new LLMGatewayTextAdapter({ apiKey, ...config }, model)\n}\n\n/**\n * Creates an LLM Gateway text adapter with API key from\n * `LLM_GATEWAY_API_KEY`.\n *\n * @example\n * ```typescript\n * const adapter = llmGatewayText('gpt-5.6-terra');\n * ```\n */\nexport function llmGatewayText<TModel extends LLMGatewayModelId>(\n model: TModel,\n config?: Omit<LLMGatewayTextConfig, 'apiKey'>,\n): LLMGatewayTextAdapter<TModel> {\n const apiKey = getLLMGatewayApiKeyFromEnv()\n return createLLMGatewayText(model, apiKey, config)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AA+CA,IAAa,wBAAb,cAOU,qCAMR;CACA,OAAyB;CACzB,OAAyB;CAEzB,YAAY,QAA8B,OAAe;EACvD,MACE,OACA,cACA,IAAI,OAAO,uBAAuB,MAAM,CAAC,GACzC,MACF;CACF;;;;;;;;CASA,iBACE,OAC8B;EAC9B,MAAM,QAAQ,MAAM,QAAQ,EAAE,EAAE;EAGhC,MAAM,MAAM,OAAO,qBAAqB,OAAO;EAC/C,IAAI,OAAO,QAAQ,YAAY,IAAI,SAAS,GAC1C,OAAO,EAAE,MAAM,IAAI;CAGvB;AACF;;;;;;;;;AAUA,SAAgB,qBACd,OACA,QACA,QAC+B;CAC/B,OAAO,IAAI,sBAAsB;EAAE;EAAQ,GAAG;CAAO,GAAG,KAAK;AAC/D;;;;;;;;;;AAWA,SAAgB,eACd,OACA,QAC+B;CAE/B,OAAO,qBAAqB,OADb,2BACoB,GAAQ,MAAM;AACnD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/ai-llmgateway",
3
- "version": "0.1.12",
3
+ "version": "0.2.1",
4
4
  "description": "LLM Gateway adapter for TanStack AI — one OpenAI-compatible endpoint for chat, tool calling, and structured outputs across many providers and models.",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -49,15 +49,15 @@
49
49
  "dependencies": {
50
50
  "openai": "^6.41.0",
51
51
  "@tanstack/ai-utils": "^0.4.1",
52
- "@tanstack/openai-base": "^0.10.16"
52
+ "@tanstack/openai-base": "^0.12.1"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@vitest/coverage-v8": "4.1.10",
56
56
  "vite": "^8.2.1",
57
- "@tanstack/ai": "0.59.0"
57
+ "@tanstack/ai": "0.63.0"
58
58
  },
59
59
  "peerDependencies": {
60
- "@tanstack/ai": "^0.59.0"
60
+ "@tanstack/ai": "^0.63.0"
61
61
  },
62
62
  "scripts": {
63
63
  "build": "vite build",
@@ -65,6 +65,7 @@
65
65
  "lint:fix": "oxlint src --type-aware --fix",
66
66
  "test:build": "publint --strict",
67
67
  "test:oxlint": "oxlint src --type-aware",
68
+ "test:coverage": "vitest run --coverage --coverage.include='src/**' --coverage.reporter=text-summary --coverage.reporter=json-summary",
68
69
  "test:lib": "vitest run",
69
70
  "test:lib:dev": "pnpm test:lib --watch",
70
71
  "test:types": "tsc"
@@ -13,6 +13,7 @@ import type {
13
13
  } from '../model-meta'
14
14
  import type { LLMGatewayMessageMetadataByModality } from '../message-types'
15
15
  import type { LLMGatewayClientConfig } from '../utils/client'
16
+ import type { OpenAIBaseTextAdapterOptions } from '@tanstack/openai-base'
16
17
 
17
18
  type ResolveToolCapabilities<TModel extends string> =
18
19
  TModel extends keyof LLMGatewayChatModelToolCapabilitiesByName
@@ -22,7 +23,8 @@ type ResolveToolCapabilities<TModel extends string> =
22
23
  /**
23
24
  * Configuration for LLM Gateway text adapter
24
25
  */
25
- export interface LLMGatewayTextConfig extends LLMGatewayClientConfig {}
26
+ export interface LLMGatewayTextConfig
27
+ extends LLMGatewayClientConfig, OpenAIBaseTextAdapterOptions {}
26
28
 
27
29
  /**
28
30
  * Re-export of the public provider options type
@@ -61,7 +63,12 @@ export class LLMGatewayTextAdapter<
61
63
  override readonly name = 'llmgateway' as const
62
64
 
63
65
  constructor(config: LLMGatewayTextConfig, model: TModel) {
64
- super(model, 'llmgateway', new OpenAI(withLLMGatewayDefaults(config)))
66
+ super(
67
+ model,
68
+ 'llmgateway',
69
+ new OpenAI(withLLMGatewayDefaults(config)),
70
+ config,
71
+ )
65
72
  }
66
73
 
67
74
  /**