diff --git a/package-lock.json b/package-lock.json index bd437e4..42436d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "dyad", - "version": "0.20.0-beta.1", + "version": "0.20.0-beta.1", "license": "MIT", "dependencies": { "@ai-sdk/amazon-bedrock": "^3.0.15", @@ -17,6 +17,7 @@ "@ai-sdk/openai": "2.0.15", "@ai-sdk/openai-compatible": "^1.0.8", "@ai-sdk/provider-utils": "^3.0.3", + "@ai-sdk/xai": "^2.0.16", "@biomejs/biome": "^1.9.4", "@dyad-sh/supabase-management-js": "v1.0.0", "@lexical/react": "^0.33.1", @@ -353,13 +354,30 @@ } }, "node_modules/@ai-sdk/openai-compatible": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@ai-sdk/openai-compatible/-/openai-compatible-1.0.8.tgz", - "integrity": "sha512-vxJ7tUisGTS4IzxboU3NT6JYsaUqRiGjvugFvx/zW5cT7FaIUprDwQIMM4ZrmH5b9kJ48rOEXqNjpdtkvtXlVA==", + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@ai-sdk/openai-compatible/-/openai-compatible-1.0.15.tgz", + "integrity": "sha512-i4TzohCxuFzBSdRNPa9eNFW6AYDZ5itbxz+rJa2kpNTMYqHgqKPGzet3X6eLIUVntA10icrqhWT+hUhxXZIS9Q==", "license": "Apache-2.0", "dependencies": { "@ai-sdk/provider": "2.0.0", - "@ai-sdk/provider-utils": "3.0.3" + "@ai-sdk/provider-utils": "3.0.8" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4" + } + }, + "node_modules/@ai-sdk/openai-compatible/node_modules/@ai-sdk/provider-utils": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.8.tgz", + "integrity": "sha512-cDj1iigu7MW2tgAQeBzOiLhjHOUM9vENsgh4oAVitek0d//WdgfPCsKO3euP7m7LyO/j9a1vr/So+BGNdpFXYw==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "2.0.0", + "@standard-schema/spec": "^1.0.0", + "eventsource-parser": "^3.0.5" }, "engines": { "node": ">=18" @@ -398,6 +416,40 @@ "zod": "^3.25.76 || ^4" } }, + "node_modules/@ai-sdk/xai": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/@ai-sdk/xai/-/xai-2.0.16.tgz", + "integrity": "sha512-t/Ohnn5OExgXZe+yhlpqOFZoixIXpaSBycWnvWfJ7JrpiNdg4WZEjWH+298zUXvqAT5wZvM93h1Ba4TkoYSyZg==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/openai-compatible": "1.0.15", + "@ai-sdk/provider": "2.0.0", + "@ai-sdk/provider-utils": "3.0.8" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4" + } + }, + "node_modules/@ai-sdk/xai/node_modules/@ai-sdk/provider-utils": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.8.tgz", + "integrity": "sha512-cDj1iigu7MW2tgAQeBzOiLhjHOUM9vENsgh4oAVitek0d//WdgfPCsKO3euP7m7LyO/j9a1vr/So+BGNdpFXYw==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "2.0.0", + "@standard-schema/spec": "^1.0.0", + "eventsource-parser": "^3.0.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4" + } + }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", diff --git a/package.json b/package.json index 2391be9..519e5a5 100644 --- a/package.json +++ b/package.json @@ -93,6 +93,7 @@ "@ai-sdk/openai": "2.0.15", "@ai-sdk/openai-compatible": "^1.0.8", "@ai-sdk/provider-utils": "^3.0.3", + "@ai-sdk/xai": "^2.0.16", "@biomejs/biome": "^1.9.4", "@dyad-sh/supabase-management-js": "v1.0.0", "@lexical/react": "^0.33.1", diff --git a/src/ipc/shared/language_model_helpers.ts b/src/ipc/shared/language_model_helpers.ts index 9714fda..c676fb5 100644 --- a/src/ipc/shared/language_model_helpers.ts +++ b/src/ipc/shared/language_model_helpers.ts @@ -253,6 +253,36 @@ export const MODEL_OPTIONS: Record = { temperature: 0, }, ], + xai: [ + // https://docs.x.ai/docs/models + { + name: "grok-code-fast-1", + displayName: "Grok Code Fast", + description: "Fast coding model", + maxOutputTokens: 32_000, + contextWindow: 256_000, + temperature: 0, + dollarSigns: 1, + }, + { + name: "grok-4", + displayName: "Grok 4", + description: "Most capable coding model", + maxOutputTokens: 32_000, + contextWindow: 256_000, + temperature: 0, + dollarSigns: 4, + }, + { + name: "grok-3", + displayName: "Grok 3", + description: "Powerful coding model", + maxOutputTokens: 32_000, + contextWindow: 131_072, + temperature: 0, + dollarSigns: 4, + }. + ], bedrock: [ { name: "us.anthropic.claude-sonnet-4-20250514-v1:0", @@ -287,6 +317,7 @@ export const PROVIDER_TO_ENV_VAR: Record = { google: "GEMINI_API_KEY", openrouter: "OPENROUTER_API_KEY", azure: "AZURE_API_KEY", + xai: "XAI_API_KEY", bedrock: "AWS_BEARER_TOKEN_BEDROCK", }; @@ -344,6 +375,13 @@ export const CLOUD_PROVIDERS: Record< gatewayPrefix: "", secondary: true, }, + xai: { + displayName: "xAI", + hasFreeTier: false, + websiteUrl: "https://console.x.ai/", + gatewayPrefix: "xai/", + secondary: true, + }, bedrock: { displayName: "AWS Bedrock", hasFreeTier: false, diff --git a/src/ipc/utils/get_model_client.ts b/src/ipc/utils/get_model_client.ts index f3c7355..e42492c 100644 --- a/src/ipc/utils/get_model_client.ts +++ b/src/ipc/utils/get_model_client.ts @@ -1,6 +1,7 @@ import { createOpenAI } from "@ai-sdk/openai"; import { createGoogleGenerativeAI as createGoogle } from "@ai-sdk/google"; import { createAnthropic } from "@ai-sdk/anthropic"; +import { createXai } from "@ai-sdk/xai"; import { createVertex as createGoogleVertex } from "@ai-sdk/google-vertex"; import { azure } from "@ai-sdk/azure"; import { createOpenRouter } from "@openrouter/ai-sdk-provider"; @@ -212,6 +213,16 @@ function getRegularModelClient( backupModelClients: [], }; } + case "xai": { + const provider = createXai({ apiKey }); + return { + modelClient: { + model: provider(model.name), + builtinProviderId: providerId, + }, + backupModelClients: [], + }; + } case "google": { const provider = createGoogle({ apiKey }); return { diff --git a/src/lib/schemas.ts b/src/lib/schemas.ts index 09fbeef..ff95654 100644 --- a/src/lib/schemas.ts +++ b/src/lib/schemas.ts @@ -36,6 +36,7 @@ const providers = [ "ollama", "lmstudio", "azure", + "xai", "bedrock", ] as const;