Skip to content

Commit 4299fe5

Browse files
committed
refactor: migrate ai-anthropic, ai-gemini, ai-fal, ai-elevenlabs to @tanstack/ai-utils
Replace duplicated generateId and getXxxApiKeyFromEnv implementations in ai-anthropic, ai-gemini, ai-fal, and ai-elevenlabs with imports from @tanstack/ai-utils. All provider-specific wrapper function names preserved for backwards compatibility.
1 parent e76122c commit 4299fe5

9 files changed

Lines changed: 38 additions & 86 deletions

File tree

packages/typescript/ai-anthropic/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,16 @@
4040
"test:types": "tsc"
4141
},
4242
"dependencies": {
43-
"@anthropic-ai/sdk": "^0.71.2"
43+
"@anthropic-ai/sdk": "^0.71.2",
44+
"@tanstack/ai-utils": "workspace:*"
4445
},
4546
"peerDependencies": {
4647
"@tanstack/ai": "workspace:^",
4748
"zod": "^4.0.0"
4849
},
4950
"devDependencies": {
5051
"@tanstack/ai": "workspace:*",
52+
"@tanstack/ai-utils": "workspace:*",
5153
"@vitest/coverage-v8": "4.0.14",
5254
"zod": "^4.2.0"
5355
}
Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Anthropic_SDK from '@anthropic-ai/sdk'
2+
import { generateId as _generateId, getApiKeyFromEnv } from '@tanstack/ai-utils'
23
import type { ClientOptions } from '@anthropic-ai/sdk'
34

45
export interface AnthropicClientConfig extends ClientOptions {
@@ -22,26 +23,12 @@ export function createAnthropicClient(
2223
* @throws Error if ANTHROPIC_API_KEY is not found
2324
*/
2425
export function getAnthropicApiKeyFromEnv(): string {
25-
const env =
26-
typeof globalThis !== 'undefined' && (globalThis as any).window?.env
27-
? (globalThis as any).window.env
28-
: typeof process !== 'undefined'
29-
? process.env
30-
: undefined
31-
const key = env?.ANTHROPIC_API_KEY
32-
33-
if (!key) {
34-
throw new Error(
35-
'ANTHROPIC_API_KEY is required. Please set it in your environment variables or use the factory function with an explicit API key.',
36-
)
37-
}
38-
39-
return key
26+
return getApiKeyFromEnv('ANTHROPIC_API_KEY')
4027
}
4128

4229
/**
4330
* Generates a unique ID with a prefix
4431
*/
4532
export function generateId(prefix: string): string {
46-
return `${prefix}-${Date.now()}-${Math.random().toString(36).substring(7)}`
33+
return _generateId(prefix)
4734
}

packages/typescript/ai-elevenlabs/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@
4141
"test:types": "tsc"
4242
},
4343
"dependencies": {
44-
"@11labs/client": "^0.2.0"
44+
"@11labs/client": "^0.2.0",
45+
"@tanstack/ai-utils": "workspace:*"
4546
},
4647
"peerDependencies": {
4748
"@tanstack/ai": "workspace:^",
@@ -50,6 +51,7 @@
5051
"devDependencies": {
5152
"@tanstack/ai": "workspace:*",
5253
"@tanstack/ai-client": "workspace:*",
54+
"@tanstack/ai-utils": "workspace:*",
5355
"@vitest/coverage-v8": "4.0.14"
5456
}
5557
}

packages/typescript/ai-elevenlabs/src/realtime/token.ts

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { getApiKeyFromEnv } from '@tanstack/ai-utils'
12
import type { RealtimeToken, RealtimeTokenAdapter } from '@tanstack/ai'
23
import type { ElevenLabsRealtimeTokenOptions } from './types'
34

@@ -7,25 +8,7 @@ const ELEVENLABS_API_URL = 'https://api.elevenlabs.io/v1'
78
* Get ElevenLabs API key from environment
89
*/
910
function getElevenLabsApiKey(): string {
10-
// Check process.env (Node.js)
11-
if (typeof process !== 'undefined' && process.env.ELEVENLABS_API_KEY) {
12-
return process.env.ELEVENLABS_API_KEY
13-
}
14-
15-
// Check window.env (Browser with injected env)
16-
if (
17-
typeof window !== 'undefined' &&
18-
(window as unknown as { env?: { ELEVENLABS_API_KEY?: string } }).env
19-
?.ELEVENLABS_API_KEY
20-
) {
21-
return (window as unknown as { env: { ELEVENLABS_API_KEY: string } }).env
22-
.ELEVENLABS_API_KEY
23-
}
24-
25-
throw new Error(
26-
'ELEVENLABS_API_KEY not found in environment variables. ' +
27-
'Please set ELEVENLABS_API_KEY in your environment.',
28-
)
11+
return getApiKeyFromEnv('ELEVENLABS_API_KEY')
2912
}
3013

3114
/**

packages/typescript/ai-fal/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@
4141
"video-generation"
4242
],
4343
"dependencies": {
44-
"@fal-ai/client": "^1.9.1"
44+
"@fal-ai/client": "^1.9.1",
45+
"@tanstack/ai-utils": "workspace:*"
4546
},
4647
"devDependencies": {
4748
"@tanstack/ai": "workspace:*",
49+
"@tanstack/ai-utils": "workspace:*",
4850
"@vitest/coverage-v8": "4.0.14",
4951
"vite": "^7.2.7"
5052
},
Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,13 @@
11
import { fal } from '@fal-ai/client'
2+
import { generateId as _generateId, getApiKeyFromEnv } from '@tanstack/ai-utils'
23

34
export interface FalClientConfig {
45
apiKey: string
56
proxyUrl?: string
67
}
78

8-
interface EnvObject {
9-
FAL_KEY?: string
10-
}
11-
12-
interface WindowWithEnv {
13-
env?: EnvObject
14-
}
15-
16-
function getEnvironment(): EnvObject | undefined {
17-
if (typeof globalThis !== 'undefined') {
18-
const win = (globalThis as { window?: WindowWithEnv }).window
19-
if (win?.env) {
20-
return win.env
21-
}
22-
}
23-
if (typeof process !== 'undefined') {
24-
return process.env as EnvObject
25-
}
26-
return undefined
27-
}
28-
299
export function getFalApiKeyFromEnv(): string {
30-
const env = getEnvironment()
31-
const key = env?.FAL_KEY
32-
33-
if (!key) {
34-
throw new Error(
35-
'FAL_KEY is required. Please set it in your environment variables or use the factory function with an explicit API key.',
36-
)
37-
}
38-
39-
return key
10+
return getApiKeyFromEnv('FAL_KEY')
4011
}
4112

4213
export function configureFalClient(config?: FalClientConfig): void {
@@ -56,5 +27,5 @@ export function configureFalClient(config?: FalClientConfig): void {
5627
}
5728

5829
export function generateId(prefix: string): string {
59-
return `${prefix}-${Date.now()}-${Math.random().toString(36).substring(7)}`
30+
return _generateId(prefix)
6031
}

packages/typescript/ai-gemini/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,15 @@
4040
"adapter"
4141
],
4242
"dependencies": {
43-
"@google/genai": "^1.43.0"
43+
"@google/genai": "^1.43.0",
44+
"@tanstack/ai-utils": "workspace:*"
4445
},
4546
"peerDependencies": {
4647
"@tanstack/ai": "workspace:^"
4748
},
4849
"devDependencies": {
4950
"@tanstack/ai": "workspace:*",
51+
"@tanstack/ai-utils": "workspace:*",
5052
"@vitest/coverage-v8": "4.0.14",
5153
"vite": "^7.2.7"
5254
}
Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { GoogleGenAI } from '@google/genai'
2+
import { generateId as _generateId, getApiKeyFromEnv } from '@tanstack/ai-utils'
23
import type { GoogleGenAIOptions } from '@google/genai'
34

45
export interface GeminiClientConfig extends GoogleGenAIOptions {
@@ -20,26 +21,16 @@ export function createGeminiClient(config: GeminiClientConfig): GoogleGenAI {
2021
* @throws Error if GOOGLE_API_KEY or GEMINI_API_KEY is not found
2122
*/
2223
export function getGeminiApiKeyFromEnv(): string {
23-
const env =
24-
typeof globalThis !== 'undefined' && (globalThis as any).window?.env
25-
? (globalThis as any).window.env
26-
: typeof process !== 'undefined'
27-
? process.env
28-
: undefined
29-
const key = env?.GOOGLE_API_KEY || env?.GEMINI_API_KEY
30-
31-
if (!key) {
32-
throw new Error(
33-
'GOOGLE_API_KEY or GEMINI_API_KEY is required. Please set it in your environment variables or use the factory function with an explicit API key.',
34-
)
24+
try {
25+
return getApiKeyFromEnv('GOOGLE_API_KEY')
26+
} catch {
27+
return getApiKeyFromEnv('GEMINI_API_KEY')
3528
}
36-
37-
return key
3829
}
3930

4031
/**
4132
* Generates a unique ID with a prefix
4233
*/
4334
export function generateId(prefix: string): string {
44-
return `${prefix}-${Date.now()}-${Math.random().toString(36).substring(7)}`
35+
return _generateId(prefix)
4536
}

pnpm-lock.yaml

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)