diff --git a/packages/vercel-ai-provider/README.md b/packages/vercel-ai-provider/README.md index 4e7e4fe27..369ab1ab4 100644 --- a/packages/vercel-ai-provider/README.md +++ b/packages/vercel-ai-provider/README.md @@ -1,37 +1,40 @@ # Provider for the Vercel AI SDK -The provider for the [Vercel AI SDK](https://sdk.vercel.ai/docs) contains language model support for -the OpenAi, Mistral and Anthropic chat and completion APIs that implements EdgeDB RAG, and embedding model support for the OpenAI and Mistral embeddings API. +The provider for the [Vercel AI SDK](https://sdk.vercel.ai/docs) contains +language model support for the OpenAi, Mistral and Anthropic chat and completion +APIs that implements Gel RAG, and embedding model support for the OpenAI and +Mistral embeddings API. ## Setup -Provider is available in the `@edgedb/vercel-ai-provider` module. You can install it with: +Provider is available in the `@gel/vercel-ai-provider` module. You can install +it with: ```bash -npm i @edgedb/vercel-ai-provider +npm i @gel/vercel-ai-provider ``` ## Provider Instance -You can import the default provider instance `edgedb` from `@edgedb/vercel-ai-provider`: +You can import the default provider instance `gel` from `@gel/vercel-ai-provider`: ```ts -import { edgedb } from "@edgedb/vercel-ai-provider"; +import { gel } from "@gel/vercel-ai-provider"; ``` ## Example ```ts import { generateText } from "ai"; -import { createClient } from "edgedb"; -import { edgedb } from "@edgedb/vercel-ai-provider"; +import { createClient } from "gel"; +import { gel } from "@gel/vercel-ai-provider"; -const textModel = (await edgedb).languageModel("gpt-4-turbo-preview"); +const textModel = (await gel).languageModel("gpt-4-turbo-preview", { + context: { query: "your context" }, +}); const { text } = await generateText({ - model: textModel.withSettings({ - context: { query: "your context" }, - }), + model: textModel, prompt: "your prompt", }); @@ -40,4 +43,4 @@ console.log(text); ## Documentation -Please check out the **[EdgeDB provider documentation](https://docs.edgedb.com/ai/vercel-ai-provider)** for more information. +Please check out the **[Gel provider documentation](https://docs.gel.com/ai/vercel_ai_sdk_provider)** for more information. diff --git a/packages/vercel-ai-provider/package.json b/packages/vercel-ai-provider/package.json index fc8e07af5..29bb4692f 100644 --- a/packages/vercel-ai-provider/package.json +++ b/packages/vercel-ai-provider/package.json @@ -1,8 +1,13 @@ { - "name": "@edgedb/vercel-ai-provider", + "name": "@gel/vercel-ai-provider", "description": "Provider for the Vercel AI SDK", "version": "0.0.1", "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/gel/gel-js.git", + "directory": "packages/vercel-ai-provider" + }, "sideEffects": false, "main": "./dist/index.js", "module": "./dist/index.mjs", @@ -36,11 +41,11 @@ "tsup": "^8", "typescript": "5.5.4", "zod": "3.23.8", - "edgedb": "*" + "gel": "*" }, "peerDependencies": { "zod": "^3.0.0", - "edgedb": "^1.5.0" + "gel": "^1.5.0" }, "engines": { "node": ">=18" diff --git a/packages/vercel-ai-provider/src/convert-to-edgedb-messages.ts b/packages/vercel-ai-provider/src/convert-to-gel-messages.ts similarity index 93% rename from packages/vercel-ai-provider/src/convert-to-edgedb-messages.ts rename to packages/vercel-ai-provider/src/convert-to-gel-messages.ts index 3d7b9a897..5b0ee136c 100644 --- a/packages/vercel-ai-provider/src/convert-to-edgedb-messages.ts +++ b/packages/vercel-ai-provider/src/convert-to-gel-messages.ts @@ -1,10 +1,10 @@ import { type LanguageModelV1Prompt } from "@ai-sdk/provider"; -import type { EdgeDBMessage } from "./edgedb-chat-settings"; +import type { GelMessage } from "./gel-chat-settings"; -export function convertToEdgeDBMessages( +export function convertToGelMessages( prompt: LanguageModelV1Prompt, -): EdgeDBMessage[] { - const messages: EdgeDBMessage[] = []; +): GelMessage[] { + const messages: GelMessage[] = []; for (const { role, content } of prompt) { switch (role) { diff --git a/packages/vercel-ai-provider/src/edgedb-provider.ts b/packages/vercel-ai-provider/src/edgedb-provider.ts deleted file mode 100644 index d27f4f290..000000000 --- a/packages/vercel-ai-provider/src/edgedb-provider.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { type Client, createClient } from "edgedb"; -import { getHTTPSCRAMAuth } from "edgedb/dist/httpScram.js"; -import { cryptoUtils } from "edgedb/dist/browserCrypto.js"; -import { getAuthenticatedFetch } from "edgedb/dist/utils.js"; -import type { - EmbeddingModelV1, - LanguageModelV1, - ProviderV1, -} from "@ai-sdk/provider"; -import { EdgeDBChatLanguageModel } from "./edgedb-chat-language-model"; -import type { - EdgeDBChatModelId, - EdgeDBChatSettings, -} from "./edgedb-chat-settings"; -import { EdgeDBEmbeddingModel } from "./edgedb-embedding-model"; -import type { - EdgeDBEmbeddingModelId, - EdgeDBEmbeddingSettings, -} from "./edgedb-embedding-settings"; - -const httpSCRAMAuth = getHTTPSCRAMAuth(cryptoUtils); - -export interface EdgeDBProvider extends ProviderV1 { - ( - modelId: EdgeDBChatModelId | EdgeDBEmbeddingModelId, - settings?: EdgeDBChatSettings, - ): LanguageModelV1; - - languageModel( - modelId: EdgeDBChatModelId, - settings?: EdgeDBChatSettings, - ): EdgeDBChatLanguageModel; - - textEmbeddingModel: ( - modelId: EdgeDBEmbeddingModelId, - settings?: EdgeDBEmbeddingSettings, - ) => EmbeddingModelV1; -} - -export interface EdgeDBProviderSettings { - /** -Use a different URL prefix for API calls, e.g. to use proxy servers. - */ - // baseURL?: string; - - /** -Custom headers to include in the requests. - */ - headers?: Record; -} - -export async function createEdgeDB( - client: Client, - options: EdgeDBProviderSettings = {}, -): Promise { - const connectConfig = await client.resolveConnectionParams(); - // const baseURL = withoutTrailingSlash(options.baseURL) ?? null; - - // In case we want to add more things to this in the future - const getHeaders = () => ({ - ...options.headers, - }); - - const fetch = await getAuthenticatedFetch( - connectConfig, - httpSCRAMAuth, - "ext/ai/", - ); - - const createChatModel = ( - modelId: EdgeDBChatModelId, - settings: EdgeDBChatSettings = {}, - ) => - new EdgeDBChatLanguageModel(modelId, settings, { - provider: "edgedb.chat", - fetch, - headers: getHeaders, - }); - - const createEmbeddingModel = ( - modelId: EdgeDBEmbeddingModelId, - settings: EdgeDBEmbeddingSettings = {}, - ) => { - return new EdgeDBEmbeddingModel(modelId, settings, { - provider: "edgedb.embedding", - fetch, - headers: getHeaders, - }); - }; - - const provider = function ( - modelId: EdgeDBChatModelId, - settings?: EdgeDBChatSettings, - ) { - if (new.target) { - throw new Error( - "The EdgeDB model function cannot be called with the new keyword.", - ); - } - - return createChatModel(modelId, settings); - }; - - provider.languageModel = createChatModel; - provider.textEmbeddingModel = createEmbeddingModel; - - return provider; -} - -/** -Default provider instance. - */ -export const edgedb = createEdgeDB(createClient()); diff --git a/packages/vercel-ai-provider/src/edgedb-chat-language-model.ts b/packages/vercel-ai-provider/src/gel-chat-language-model.ts similarity index 91% rename from packages/vercel-ai-provider/src/edgedb-chat-language-model.ts rename to packages/vercel-ai-provider/src/gel-chat-language-model.ts index a5dab469c..c5c551371 100644 --- a/packages/vercel-ai-provider/src/edgedb-chat-language-model.ts +++ b/packages/vercel-ai-provider/src/gel-chat-language-model.ts @@ -17,41 +17,41 @@ import { combineHeaders, } from "@ai-sdk/provider-utils"; import { - type EdgeDBChatModelId, - type EdgeDBChatSettings, - type EdgeDBMessage, + type GelChatModelId, + type GelChatSettings, + type GelMessage, isAnthropicModel, -} from "./edgedb-chat-settings"; -import { edgedbFailedResponseHandler } from "./edgedb-error"; +} from "./gel-chat-settings"; +import { gelFailedResponseHandler } from "./gel-error"; import { - mapEdgedbStopReason, + mapGelStopReason, getResponseMetadata, mapOpenAICompletionLogProbs, } from "./utils"; -import { convertToEdgeDBMessages } from "./convert-to-edgedb-messages"; -import { prepareTools } from "./edgedb-prepare-tools"; +import { convertToGelMessages } from "./convert-to-gel-messages"; +import { prepareTools } from "./gel-prepare-tools"; -export interface EdgeDBChatConfig { +export interface GelChatConfig { provider: string; fetch: FetchFunction; // baseURL: string | null; headers: () => Record; } -export class EdgeDBChatLanguageModel implements LanguageModelV1 { +export class GelChatLanguageModel implements LanguageModelV1 { readonly specificationVersion = "v1"; readonly defaultObjectGenerationMode = "json"; readonly supportsImageUrls = false; - readonly modelId: EdgeDBChatModelId; - readonly settings: EdgeDBChatSettings; + readonly modelId: GelChatModelId; + readonly settings: GelChatSettings; - private readonly config: EdgeDBChatConfig; + private readonly config: GelChatConfig; constructor( - modelId: EdgeDBChatModelId, - settings: EdgeDBChatSettings, - config: EdgeDBChatConfig, + modelId: GelChatModelId, + settings: GelChatSettings, + config: GelChatConfig, ) { this.modelId = modelId; this.settings = settings; @@ -132,7 +132,7 @@ export class EdgeDBChatLanguageModel implements LanguageModelV1 { const baseArgs = { model: this.modelId, - messages: convertToEdgeDBMessages(prompt), + messages: convertToGelMessages(prompt), temperature, max_tokens: maxTokens, top_p: topP, @@ -188,7 +188,7 @@ export class EdgeDBChatLanguageModel implements LanguageModelV1 { } } - private buildPrompt(messages: EdgeDBMessage[]) { + private buildPrompt(messages: GelMessage[]) { const providedPromptId = this.settings.prompt && ("name" in this.settings.prompt || "id" in this.settings.prompt); @@ -207,7 +207,7 @@ export class EdgeDBChatLanguageModel implements LanguageModelV1 { }; } - private buildQuery(messages: EdgeDBMessage[]) { + private buildQuery(messages: GelMessage[]) { return [...messages].reverse().find((msg) => msg.role === "user")! .content[0].text; } @@ -229,10 +229,9 @@ export class EdgeDBChatLanguageModel implements LanguageModelV1 { query: this.buildQuery(messages), stream: false, }, - failedResponseHandler: edgedbFailedResponseHandler, - successfulResponseHandler: createJsonResponseHandler( - edgedbRagResponseSchema, - ), + failedResponseHandler: gelFailedResponseHandler, + successfulResponseHandler: + createJsonResponseHandler(gelRagResponseSchema), abortSignal: options.abortSignal, fetch: this.config.fetch, }); @@ -249,7 +248,7 @@ export class EdgeDBChatLanguageModel implements LanguageModelV1 { toolName: toolCall.name, args: JSON.stringify(toolCall.args), })), - finishReason: mapEdgedbStopReason(finish_reason), + finishReason: mapGelStopReason(finish_reason), logprobs: mapOpenAICompletionLogProbs(logprobs), usage: { promptTokens: usage.prompt_tokens, @@ -279,9 +278,9 @@ export class EdgeDBChatLanguageModel implements LanguageModelV1 { query: this.buildQuery(messages), stream: true, }, - failedResponseHandler: edgedbFailedResponseHandler, + failedResponseHandler: gelFailedResponseHandler, successfulResponseHandler: - createEventSourceResponseHandler(edgedbRagChunkSchema), + createEventSourceResponseHandler(gelRagChunkSchema), abortSignal: options.abortSignal, fetch: this.config.fetch, }); @@ -310,7 +309,7 @@ export class EdgeDBChatLanguageModel implements LanguageModelV1 { return { stream: response.pipeThrough( new TransformStream< - ParseResult>, + ParseResult>, LanguageModelV1StreamPart >({ transform(chunk, controller) { @@ -428,7 +427,7 @@ export class EdgeDBChatLanguageModel implements LanguageModelV1 { } case "message_delta": { - finishReason = mapEdgedbStopReason(value.delta.stop_reason); + finishReason = mapGelStopReason(value.delta.stop_reason); if (value.usage) { usage.completionTokens = value.usage.completion_tokens; } @@ -467,7 +466,7 @@ export class EdgeDBChatLanguageModel implements LanguageModelV1 { } } -const edgedbRagResponseSchema = z.object({ +const gelRagResponseSchema = z.object({ id: z.string().nullish(), model: z.string().nullish(), created: z.number().nullish(), @@ -496,7 +495,7 @@ const edgedbRagResponseSchema = z.object({ .nullish(), }); -const edgedbRagChunkSchema = z.discriminatedUnion("type", [ +const gelRagChunkSchema = z.discriminatedUnion("type", [ z.object({ type: z.literal("message_start"), message: z.object({ diff --git a/packages/vercel-ai-provider/src/edgedb-chat-settings.ts b/packages/vercel-ai-provider/src/gel-chat-settings.ts similarity index 85% rename from packages/vercel-ai-provider/src/edgedb-chat-settings.ts rename to packages/vercel-ai-provider/src/gel-chat-settings.ts index 227fd6b0e..a52501f1e 100644 --- a/packages/vercel-ai-provider/src/edgedb-chat-settings.ts +++ b/packages/vercel-ai-provider/src/gel-chat-settings.ts @@ -26,13 +26,13 @@ export type AnthropicModelId = | "claude-3-sonnet-20240229" | "claude-3-haiku-20240307"; -export type EdgeDBChatModelId = +export type GelChatModelId = | OpenAIModelId | MistralModelId | AnthropicModelId | (string & {}); -export function isAnthropicModel(model: EdgeDBChatModelId): boolean { +export function isAnthropicModel(model: GelChatModelId): boolean { return ( model === "claude-3-5-sonnet-latest" || model === "claude-3-5-haiku-latest" || @@ -42,7 +42,7 @@ export function isAnthropicModel(model: EdgeDBChatModelId): boolean { ); } -export function isOpenAIModel(model: EdgeDBChatModelId): boolean { +export function isOpenAIModel(model: GelChatModelId): boolean { return ( model === "gpt-4o" || model === "gpt-4o-mini" || @@ -54,9 +54,9 @@ export function isOpenAIModel(model: EdgeDBChatModelId): boolean { } export type Prompt = - | { name: string; custom?: EdgeDBMessage[] } - | { id: string; custom?: EdgeDBMessage[] } - | { custom: EdgeDBMessage[] }; + | { name: string; custom?: GelMessage[] } + | { id: string; custom?: GelMessage[] } + | { custom: GelMessage[] }; export interface QueryContext { query: string; @@ -65,7 +65,7 @@ export interface QueryContext { max_object_count?: number; } -export interface EdgeDBChatSettings { +export interface GelChatSettings { context?: QueryContext; prompt?: Prompt; @@ -126,23 +126,23 @@ monitor and detect abuse. Learn more. // cacheControl?: boolean; } -export type EdgeDBMessage = - | EdgeDBSystemMessage - | EdgeDBUserMessage - | EdgeDBAssistantMessage - | EdgeDBToolMessage; +export type GelMessage = + | GelSystemMessage + | GelUserMessage + | GelAssistantMessage + | GelToolMessage; -export interface EdgeDBSystemMessage { +export interface GelSystemMessage { role: "system"; content: string; } -export interface EdgeDBUserMessage { +export interface GelUserMessage { role: "user"; content: { type: "text"; text: string }[]; } -export interface EdgeDBAssistantMessage { +export interface GelAssistantMessage { role: "assistant"; content: string; tool_calls?: { @@ -152,7 +152,7 @@ export interface EdgeDBAssistantMessage { }[]; } -export interface EdgeDBToolMessage { +export interface GelToolMessage { role: "tool"; content: string; tool_call_id: string; diff --git a/packages/vercel-ai-provider/src/edgedb-embedding-model.ts b/packages/vercel-ai-provider/src/gel-embedding-model.ts similarity index 78% rename from packages/vercel-ai-provider/src/edgedb-embedding-model.ts rename to packages/vercel-ai-provider/src/gel-embedding-model.ts index 7f5fa004c..9bf8b5994 100644 --- a/packages/vercel-ai-provider/src/edgedb-embedding-model.ts +++ b/packages/vercel-ai-provider/src/gel-embedding-model.ts @@ -11,29 +11,29 @@ import { import { z } from "zod"; import { isMistralEmbeddingModel, - type EdgeDBEmbeddingModelId, - type EdgeDBEmbeddingSettings, -} from "./edgedb-embedding-settings"; -import { edgedbFailedResponseHandler } from "./edgedb-error"; + type GelEmbeddingModelId, + type GelEmbeddingSettings, +} from "./gel-embedding-settings"; +import { gelFailedResponseHandler } from "./gel-error"; -interface EdgeDBEmbeddingConfig { +interface GelEmbeddingConfig { provider: string; fetch?: FetchFunction; // baseURL: string | null; headers: () => Record; } -export class EdgeDBEmbeddingModel implements EmbeddingModelV1 { +export class GelEmbeddingModel implements EmbeddingModelV1 { readonly specificationVersion = "v1"; - readonly modelId: EdgeDBEmbeddingModelId; + readonly modelId: GelEmbeddingModelId; - private readonly config: EdgeDBEmbeddingConfig; - private readonly settings: EdgeDBEmbeddingSettings; + private readonly config: GelEmbeddingConfig; + private readonly settings: GelEmbeddingSettings; constructor( - modelId: EdgeDBEmbeddingModelId, - settings: EdgeDBEmbeddingSettings, - config: EdgeDBEmbeddingConfig, + modelId: GelEmbeddingModelId, + settings: GelEmbeddingSettings, + config: GelEmbeddingConfig, ) { this.modelId = modelId; this.settings = settings; @@ -87,9 +87,9 @@ export class EdgeDBEmbeddingModel implements EmbeddingModelV1 { dimensions: this.settings.dimensions, user: this.settings.user, }, - failedResponseHandler: edgedbFailedResponseHandler, + failedResponseHandler: gelFailedResponseHandler, successfulResponseHandler: createJsonResponseHandler( - EdgeDBTextEmbeddingResponseSchema, + GelTextEmbeddingResponseSchema, ), abortSignal, fetch: this.config.fetch, @@ -105,7 +105,7 @@ export class EdgeDBEmbeddingModel implements EmbeddingModelV1 { } } -const EdgeDBTextEmbeddingResponseSchema = z.object({ +const GelTextEmbeddingResponseSchema = z.object({ data: z.array(z.object({ embedding: z.array(z.number()) })), usage: z.object({ prompt_tokens: z.number() }).nullish(), }); diff --git a/packages/vercel-ai-provider/src/edgedb-embedding-settings.ts b/packages/vercel-ai-provider/src/gel-embedding-settings.ts similarity index 79% rename from packages/vercel-ai-provider/src/edgedb-embedding-settings.ts rename to packages/vercel-ai-provider/src/gel-embedding-settings.ts index 794bba9bc..ab7ed437c 100644 --- a/packages/vercel-ai-provider/src/edgedb-embedding-settings.ts +++ b/packages/vercel-ai-provider/src/gel-embedding-settings.ts @@ -1,17 +1,15 @@ -export type EdgeDBEmbeddingModelId = +export type GelEmbeddingModelId = | "text-embedding-ada-002" | "text-embedding-3-small" | "text-embedding-3-large" | "mistral-embed" | (string & {}); -export function isMistralEmbeddingModel( - model: EdgeDBEmbeddingModelId, -): boolean { +export function isMistralEmbeddingModel(model: GelEmbeddingModelId): boolean { return model === "mistral-embed"; } -export interface EdgeDBEmbeddingSettings { +export interface GelEmbeddingSettings { /** Override the maximum number of embeddings per call. */ diff --git a/packages/vercel-ai-provider/src/edgedb-error.ts b/packages/vercel-ai-provider/src/gel-error.ts similarity index 64% rename from packages/vercel-ai-provider/src/edgedb-error.ts rename to packages/vercel-ai-provider/src/gel-error.ts index b8a253cc1..0f2dc2f0c 100644 --- a/packages/vercel-ai-provider/src/edgedb-error.ts +++ b/packages/vercel-ai-provider/src/gel-error.ts @@ -1,7 +1,7 @@ import { createJsonErrorResponseHandler } from "@ai-sdk/provider-utils"; import { z } from "zod"; -const edgedbErrorDataSchema = z.object({ +const gelErrorDataSchema = z.object({ object: z.literal("error"), message: z.string(), type: z.string(), @@ -9,11 +9,11 @@ const edgedbErrorDataSchema = z.object({ code: z.string().nullable(), }); -export type EdgedDBErrorData = z.infer; +export type EdgedDBErrorData = z.infer; -export const edgedbFailedResponseHandler: ReturnType< +export const gelFailedResponseHandler: ReturnType< typeof createJsonErrorResponseHandler > = createJsonErrorResponseHandler({ - errorSchema: edgedbErrorDataSchema, + errorSchema: gelErrorDataSchema, errorToMessage: (data) => data.message, }); diff --git a/packages/vercel-ai-provider/src/edgedb-prepare-tools.ts b/packages/vercel-ai-provider/src/gel-prepare-tools.ts similarity index 83% rename from packages/vercel-ai-provider/src/edgedb-prepare-tools.ts rename to packages/vercel-ai-provider/src/gel-prepare-tools.ts index b823eede5..72b3a7dc3 100644 --- a/packages/vercel-ai-provider/src/edgedb-prepare-tools.ts +++ b/packages/vercel-ai-provider/src/gel-prepare-tools.ts @@ -5,10 +5,10 @@ import { UnsupportedFunctionalityError, } from "@ai-sdk/provider"; import { - type EdgeDBChatModelId, + type GelChatModelId, isAnthropicModel, isOpenAIModel, -} from "./edgedb-chat-settings"; +} from "./gel-chat-settings"; interface OpenAILikeTool { type: "function"; @@ -29,7 +29,7 @@ export function prepareTools( mode: Parameters[0]["mode"] & { type: "regular"; }, - model: EdgeDBChatModelId, + model: GelChatModelId, ) { const isOpenAI = isOpenAIModel(model); const isAnthropic = isAnthropicModel(model); @@ -42,20 +42,20 @@ export function prepareTools( return { toolWarnings }; } - const edgedbOpenAILikeTools: OpenAILikeTool[] = []; - const edgedbAnthropicTools: AnthropicTool[] = []; + const gelOpenAILikeTools: OpenAILikeTool[] = []; + const gelAnthropicTools: AnthropicTool[] = []; for (const tool of tools) { switch (tool.type) { case "function": if (isAnthropic) { - edgedbAnthropicTools.push({ + gelAnthropicTools.push({ name: tool.name, description: tool.description, input_schema: tool.parameters, }); } else { - edgedbOpenAILikeTools.push({ + gelOpenAILikeTools.push({ type: "function", function: { name: tool.name, @@ -78,13 +78,11 @@ export function prepareTools( } const toolChoice = mode.toolChoice; - const edgedbTools = isAnthropic - ? edgedbAnthropicTools - : edgedbOpenAILikeTools; + const gelTools = isAnthropic ? gelAnthropicTools : gelOpenAILikeTools; if (toolChoice == null) { return { - tools: edgedbTools, + tools: gelTools, toolWarnings, }; } @@ -94,7 +92,7 @@ export function prepareTools( switch (type) { case "auto": return { - tools: edgedbTools, + tools: gelTools, tool_choice: isAnthropic ? { type: "auto" } : "auto", toolWarnings, // add betas to Anthropic in all cases @@ -102,10 +100,10 @@ export function prepareTools( case "none": return isAnthropic ? { toolWarnings } - : { tools: edgedbTools, tool_choice: type, toolWarnings }; + : { tools: gelTools, tool_choice: type, toolWarnings }; case "required": return { - tools: edgedbTools, + tools: gelTools, tool_choice: isAnthropic ? { type: "any" } : isOpenAI @@ -119,7 +117,7 @@ export function prepareTools( case "tool": return isAnthropic ? { - tools: edgedbTools, + tools: gelTools, tool_choice: { type: "tool", name: toolChoice.toolName, @@ -128,7 +126,7 @@ export function prepareTools( } : isOpenAI ? { - tools: edgedbTools, + tools: gelTools, tool_choice: { type: "function", function: { @@ -138,7 +136,7 @@ export function prepareTools( toolWarnings, } : { - tools: (edgedbTools as OpenAILikeTool[]).filter( + tools: (gelTools as OpenAILikeTool[]).filter( (tool) => tool.function!.name === toolChoice.toolName, ), tool_choice: "any", diff --git a/packages/vercel-ai-provider/src/gel-provider.ts b/packages/vercel-ai-provider/src/gel-provider.ts new file mode 100644 index 000000000..5d6dfd1d9 --- /dev/null +++ b/packages/vercel-ai-provider/src/gel-provider.ts @@ -0,0 +1,110 @@ +import { type Client, createClient } from "gel"; +import { getHTTPSCRAMAuth } from "gel/dist/httpScram.js"; +import { cryptoUtils } from "gel/dist/browserCrypto.js"; +import { getAuthenticatedFetch } from "gel/dist/utils.js"; +import type { + EmbeddingModelV1, + LanguageModelV1, + ProviderV1, +} from "@ai-sdk/provider"; +import { GelChatLanguageModel } from "./gel-chat-language-model"; +import type { GelChatModelId, GelChatSettings } from "./gel-chat-settings"; +import { GelEmbeddingModel } from "./gel-embedding-model"; +import type { + GelEmbeddingModelId, + GelEmbeddingSettings, +} from "./gel-embedding-settings"; + +const httpSCRAMAuth = getHTTPSCRAMAuth(cryptoUtils); + +export interface GelProvider extends ProviderV1 { + ( + modelId: GelChatModelId | GelEmbeddingModelId, + settings?: GelChatSettings, + ): LanguageModelV1; + + languageModel( + modelId: GelChatModelId, + settings?: GelChatSettings, + ): GelChatLanguageModel; + + textEmbeddingModel: ( + modelId: GelEmbeddingModelId, + settings?: GelEmbeddingSettings, + ) => EmbeddingModelV1; +} + +export interface GelProviderSettings { + /** +Use a different URL prefix for API calls, e.g. to use proxy servers. + */ + // baseURL?: string; + + /** +Custom headers to include in the requests. + */ + headers?: Record; +} + +export async function createGel( + client: Client, + options: GelProviderSettings = {}, +): Promise { + const connectConfig = await client.resolveConnectionParams(); + // const baseURL = withoutTrailingSlash(options.baseURL) ?? null; + + // In case we want to add more things to this in the future + const getHeaders = () => ({ + ...options.headers, + }); + + const fetch = await getAuthenticatedFetch( + connectConfig, + httpSCRAMAuth, + "ext/ai/", + ); + + const createChatModel = ( + modelId: GelChatModelId, + settings: GelChatSettings = {}, + ) => + new GelChatLanguageModel(modelId, settings, { + provider: "gel.chat", + fetch, + headers: getHeaders, + }); + + const createEmbeddingModel = ( + modelId: GelEmbeddingModelId, + settings: GelEmbeddingSettings = {}, + ) => { + return new GelEmbeddingModel(modelId, settings, { + provider: "gel.embedding", + fetch, + headers: getHeaders, + }); + }; + + const provider = function ( + modelId: GelChatModelId, + settings?: GelChatSettings, + ) { + if (new.target) { + throw new Error( + "The Gel model function cannot be called with the new keyword.", + ); + } + + return createChatModel(modelId, settings); + }; + + provider.languageModel = createChatModel; + provider.textEmbeddingModel = createEmbeddingModel; + + return provider; +} + +/** +Default provider instance. + */ +export const gel = createGel(createClient()); diff --git a/packages/vercel-ai-provider/src/index.ts b/packages/vercel-ai-provider/src/index.ts index ee8cdb6e5..25a54c29b 100644 --- a/packages/vercel-ai-provider/src/index.ts +++ b/packages/vercel-ai-provider/src/index.ts @@ -1,2 +1,2 @@ -export { createEdgeDB, edgedb } from "./edgedb-provider"; -export type { EdgeDBProvider } from "./edgedb-provider"; +export { createGel, gel } from "./gel-provider"; +export type { GelProvider } from "./gel-provider"; diff --git a/packages/vercel-ai-provider/src/utils.ts b/packages/vercel-ai-provider/src/utils.ts index ae9b2f8b3..5142bf2ea 100644 --- a/packages/vercel-ai-provider/src/utils.ts +++ b/packages/vercel-ai-provider/src/utils.ts @@ -1,7 +1,7 @@ import type { LanguageModelV1FinishReason } from "@ai-sdk/provider"; import type { LanguageModelV1LogProbs } from "@ai-sdk/provider"; -export function mapEdgedbStopReason( +export function mapGelStopReason( finishReason: string | null | undefined, ): LanguageModelV1FinishReason { switch (finishReason) {