Skip to content

Commit

Permalink
Remove exposed api-key settings in lieu of headers.
Browse files Browse the repository at this point in the history
  • Loading branch information
shaper committed Nov 22, 2024
1 parent 7eebb0a commit b7c31ea
Show file tree
Hide file tree
Showing 15 changed files with 231 additions and 324 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import { embedMany } from 'ai';

async function main() {
const togetherai = createOpenAICompatible({
apiKeyEnvVarName: 'TOGETHER_AI_API_KEY',
baseURL: 'https://api.together.xyz/v1',
name: 'togetherai',
headers: {
Authorization: `Bearer ${process.env.TOGETHER_AI_API_KEY}`,
},
});
const model = togetherai.textEmbeddingModel('BAAI/bge-large-en-v1.5');
const { embeddings, usage } = await embedMany({
Expand Down
4 changes: 3 additions & 1 deletion examples/ai-core/src/embed/openai-compatible-togetherai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import { embed } from 'ai';

async function main() {
const togetherai = createOpenAICompatible({
apiKeyEnvVarName: 'TOGETHER_AI_API_KEY',
baseURL: 'https://api.together.xyz/v1',
name: 'togetherai',
headers: {
Authorization: `Bearer ${process.env.TOGETHER_AI_API_KEY}`,
},
});
const model = togetherai.textEmbeddingModel('BAAI/bge-large-en-v1.5');
const { embedding, usage } = await embed({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import { z } from 'zod';

async function main() {
const togetherai = createOpenAICompatible({
apiKeyEnvVarName: 'TOGETHER_AI_API_KEY',
baseURL: 'https://api.together.xyz/v1',
name: 'togetherai',
headers: {
Authorization: `Bearer ${process.env.TOGETHER_AI_API_KEY}`,
},
});
const model = togetherai.chatModel('mistralai/Mistral-7B-Instruct-v0.1');
const result = await generateObject({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import fs from 'node:fs';

async function main() {
const openai = createOpenAICompatible({
apiKeyEnvVarName: 'OPENAI_API_KEY',
baseURL: 'https://api.openai.com/v1',
name: 'openai',
headers: {
Authorization: `Bearer ${process.env.TOGETHER_AI_API_KEY}`,
},
});
const model = openai.chatModel('gpt-4o-mini');
const result = await generateText({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import { weatherTool } from '../tools/weather-tool';

async function main() {
const togetherai = createOpenAICompatible({
apiKeyEnvVarName: 'TOGETHER_AI_API_KEY',
baseURL: 'https://api.together.xyz/v1',
name: 'togetherai',
headers: {
Authorization: `Bearer ${process.env.TOGETHER_AI_API_KEY}`,
},
});
const model = togetherai.chatModel(
'meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import { generateText } from 'ai';

async function main() {
const togetherai = createOpenAICompatible({
apiKeyEnvVarName: 'TOGETHER_AI_API_KEY',
baseURL: 'https://api.together.xyz/v1',
name: 'togetherai',
headers: {
Authorization: `Bearer ${process.env.TOGETHER_AI_API_KEY}`,
},
});
const model = togetherai.chatModel('meta-llama/Llama-3-70b-chat-hf');
const result = await generateText({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import { z } from 'zod';

async function main() {
const togetherai = createOpenAICompatible({
apiKeyEnvVarName: 'TOGETHER_AI_API_KEY',
baseURL: 'https://api.together.xyz/v1',
name: 'togetherai',
headers: {
Authorization: `Bearer ${process.env.TOGETHER_AI_API_KEY}`,
},
});
const model = togetherai.chatModel('mistralai/Mistral-7B-Instruct-v0.1');
const result = streamObject({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ async function main() {
let toolResponseAvailable = false;

const togetherai = createOpenAICompatible({
apiKeyEnvVarName: 'TOGETHER_AI_API_KEY',
baseURL: 'https://api.together.xyz/v1',
name: 'togetherai',
headers: {
Authorization: `Bearer ${process.env.TOGETHER_AI_API_KEY}`,
},
});
const model = togetherai.chatModel(
'meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import { streamText } from 'ai';

async function main() {
const togetherai = createOpenAICompatible({
apiKeyEnvVarName: 'TOGETHER_AI_API_KEY',
baseURL: 'https://api.together.xyz/v1',
name: 'togetherai',
headers: {
Authorization: `Bearer ${process.env.TOGETHER_AI_API_KEY}`,
},
});
const model = togetherai.chatModel(
'meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo',
Expand Down
12 changes: 8 additions & 4 deletions packages/openai-compatible/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ import { generateText } from 'ai';

const { text } = await generateText({
model: createOpenAICompatible({
apiKeyEnvVarName: 'EXAMPLE_API_KEY',
baseURL: 'https://api.example.com/v1',
name: 'example',
headers: {
Authorization: `Bearer ${process.env.MY_API_KEY}`,
},
}).chatModel('meta-llama/Llama-3-70b-chat-hf'),
prompt: 'Write a vegetarian lasagna recipe for 4 people.',
});
Expand Down Expand Up @@ -62,14 +64,16 @@ const model = createOpenAICompatible<
ExampleCompletionModelIds,
ExampleEmbeddingModelIds
>({
apiKeyEnvVarName: 'EXAMPLE_API_KEY',
baseURL: 'https://api.example.com/v1',
name: 'example',
headers: {
Authorization: `Bearer ${process.env.MY_API_KEY}`,
},
});

// Subsequent calls to e.g. `model.chatModel` will auto-complete the model id
// from the list of `ExampleChatModelIds` (while still allowing free-form
// strings as well).
// from the list of `ExampleChatModelIds` while still allowing free-form
// strings as well.

const { text } = await generateText({
model: model.chatModel('meta-llama/Llama-3-70b-chat-hf'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ const TEST_PROMPT: LanguageModelV1Prompt = [
];

const provider = createOpenAICompatible({
apiKey: 'test-api-key',
baseURL: 'https://my.api.com/v1/',
name: 'test-provider',
headers: {
Authorization: `Bearer test-api-key`,
},
});

const model = provider('grok-beta');
Expand Down Expand Up @@ -308,10 +310,10 @@ describe('doGenerate', () => {
prepareJsonResponse({ content: '' });

const provider = createOpenAICompatible({
apiKey: 'test-api-key',
baseURL: 'https://my.api.com/v1/',
name: 'test-provider',
headers: {
Authorization: `Bearer test-api-key`,
'Custom-Provider-Header': 'provider-header-value',
},
});
Expand Down Expand Up @@ -882,10 +884,10 @@ describe('doStream', () => {
prepareStreamResponse({ content: [] });

const provider = createOpenAICompatible({
apiKey: 'test-api-key',
baseURL: 'https://my.api.com/v1',
name: 'test-provider',
headers: {
Authorization: `Bearer test-api-key`,
'Custom-Provider-Header': 'provider-header-value',
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ const TEST_PROMPT: LanguageModelV1Prompt = [
];

const provider = createOpenAICompatible({
apiKey: 'test-api-key',
baseURL: 'https://my.api.com/v1/',
name: 'test-provider',
headers: {
Authorization: `Bearer test-api-key`,
},
});

const model = provider.completionModel('gpt-3.5-turbo-instruct');
Expand Down Expand Up @@ -202,13 +204,10 @@ describe('doGenerate', () => {
prepareJsonResponse({ content: '' });

const provider = createOpenAICompatible({
apiKey: 'test-api-key',
baseURL: 'https://my.api.com/v1/',
name: 'test-provider',
// TODO(shaper): Do we need these?
// organization: 'test-organization',
// project: 'test-project',
headers: {
Authorization: `Bearer test-api-key`,
'Custom-Provider-Header': 'provider-header-value',
},
});
Expand Down Expand Up @@ -432,10 +431,10 @@ describe('doStream', () => {
prepareStreamResponse({ content: [] });

const provider = createOpenAICompatible({
apiKey: 'test-api-key',
baseURL: 'https://my.api.com/v1/',
name: 'test-provider',
headers: {
Authorization: `Bearer test-api-key`,
'Custom-Provider-Header': 'provider-header-value',
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ const dummyEmbeddings = [
const testValues = ['sunny day at the beach', 'rainy day in the city'];

const provider = createOpenAICompatible({
apiKey: 'test-api-key',
baseURL: 'https://my.api.com/v1/',
name: 'test-provider',
headers: {
Authorization: `Bearer test-api-key`,
},
});
const model = provider.textEmbeddingModel('text-embedding-3-large');

Expand Down Expand Up @@ -107,10 +109,10 @@ describe('doEmbed', () => {
prepareJsonResponse();

const provider = createOpenAICompatible({
apiKey: 'test-api-key',
baseURL: 'https://my.api.com/v1/',
name: 'test-provider',
headers: {
Authorization: `Bearer test-api-key`,
'Custom-Provider-Header': 'provider-header-value',
},
});
Expand Down
48 changes: 10 additions & 38 deletions packages/openai-compatible/src/openai-compatible-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@ import {
LanguageModelV1,
ProviderV1,
} from '@ai-sdk/provider';
import {
FetchFunction,
loadApiKey,
withoutTrailingSlash,
} from '@ai-sdk/provider-utils';
import { FetchFunction, withoutTrailingSlash } from '@ai-sdk/provider-utils';
import { OpenAICompatibleChatLanguageModel } from './openai-compatible-chat-language-model';
import { OpenAICompatibleChatSettings } from './openai-compatible-chat-settings';
import { OpenAICompatibleCompletionLanguageModel } from './openai-compatible-completion-language-model';
Expand Down Expand Up @@ -48,38 +44,23 @@ export interface OpenAICompatibleProvider<

export interface OpenAICompatibleProviderSettings {
/**
Base URL for the API calls.
*/
Base URL for the API calls.
*/
baseURL?: string;

/**
API key for authenticating requests.
*/
apiKey?: string;

/**
Custom headers to include in the requests.
*/
headers?: Record<string, string>;

/**
Custom fetch implementation. You can use it as a middleware to intercept requests,
or to provide a custom fetch implementation for e.g. testing.
*/
fetch?: FetchFunction;

/**
The name of the environment variable from which to load the API key (if a key isn't explicitly provided).
Custom headers to include in the requests.
*/
apiKeyEnvVarName?: string;
headers?: Record<string, string>;

/**
Description of the API key environment variable (for use in error messages).
Custom fetch implementation. You can use it as a middleware to intercept requests,
or to provide a custom fetch implementation for e.g. testing.
*/
apiKeyEnvVarDescription?: string;
fetch?: FetchFunction;

/**
Provider name.
Provider name.
*/
name?: string;
}
Expand Down Expand Up @@ -108,15 +89,6 @@ export function createOpenAICompatible<
}
const providerName = options.name;

const getHeaders = () => ({
Authorization: `Bearer ${loadApiKey({
apiKey: options.apiKey,
environmentVariableName: options.apiKeyEnvVarName ?? '',
description: options.apiKeyEnvVarDescription ?? '',
})}`,
...options.headers,
});

interface CommonModelConfig {
provider: string;
url: ({ path }: { path: string }) => string;
Expand All @@ -127,7 +99,7 @@ export function createOpenAICompatible<
const getCommonModelConfig = (modelType: string): CommonModelConfig => ({
provider: `${providerName}.${modelType}`,
url: ({ path }) => `${baseURL}${path}`,
headers: getHeaders,
headers: () => options.headers ?? {},
fetch: options.fetch,
});

Expand Down
Loading

0 comments on commit b7c31ea

Please sign in to comment.