Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
fa47c77
chore: upgrade to ai sdk 5 to resolve security vulns
The-Best-Codes Nov 8, 2025
9ed9658
chore: changeset
The-Best-Codes Nov 8, 2025
61a405c
Merge branch 'main' into best/aisdk-provider-upgrades
The-Best-Codes Nov 10, 2025
8258291
Merge branch 'main' into best/aisdk-provider-upgrades
The-Best-Codes Nov 11, 2025
dbcc6d7
Merge branch 'main' into best/aisdk-provider-upgrades
The-Best-Codes Nov 11, 2025
9076098
Merge branch 'main' into best/aisdk-provider-upgrades
The-Best-Codes Nov 11, 2025
c7641ff
Merge branch 'main' into best/aisdk-provider-upgrades
The-Best-Codes Nov 12, 2025
1328537
Merge branch 'main' into best/aisdk-provider-upgrades
The-Best-Codes Nov 12, 2025
26ae8f2
Merge branch 'main' into best/aisdk-provider-upgrades
The-Best-Codes Nov 12, 2025
69dd05d
feat: upgrade to zod 4
The-Best-Codes Nov 15, 2025
4bc1c3d
chore: remove zod-to-json-schema from the codebase
The-Best-Codes Nov 15, 2025
1a35674
fix: use "Z" not "z"
The-Best-Codes Nov 15, 2025
afb46d3
fix: use error.issues
The-Best-Codes Nov 15, 2025
f30815a
fix: perform more zod 4 migrations
The-Best-Codes Nov 15, 2025
780ccc5
fix: resolve type errors in mcp.ts (used any, might manually verify
The-Best-Codes Nov 15, 2025
b637930
fix: remove defaults from optional fields in zod 4 (fixes failing tests)
The-Best-Codes Nov 15, 2025
7e504b5
chore: fmt
The-Best-Codes Nov 15, 2025
08bd9b7
Merge branch 'main' into best/aisdk-provider-upgrades
maxprilutskiy Nov 17, 2025
0317dde
Merge branch 'main' into best/aisdk-provider-upgrades
maxprilutskiy Nov 17, 2025
583331b
Merge branch 'main' into best/aisdk-provider-upgrades
The-Best-Codes Nov 17, 2025
d99721f
chore: remove unused zod-to-json-schema dep
The-Best-Codes Nov 17, 2025
ddc7a8b
fix: use prefault
The-Best-Codes Nov 17, 2025
785b526
fix: revert
The-Best-Codes Nov 17, 2025
f3257cb
Merge branch 'main' into best/aisdk-provider-upgrades
The-Best-Codes Nov 19, 2025
4fde09a
fix: upgrade new deps
The-Best-Codes Nov 19, 2025
ac8d6ac
Merge branch 'main' into best/aisdk-provider-upgrades
The-Best-Codes Nov 20, 2025
166e6e1
Merge branch 'main' into best/aisdk-provider-upgrades
The-Best-Codes Nov 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/pink-lemons-buy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@lingo.dev/_compiler": minor
"lingo.dev": minor
---

Upgrade Compiler and CLI to AI SDK v5.
16 changes: 8 additions & 8 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,10 @@
"author": "",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/anthropic": "^1.2.11",
"@ai-sdk/google": "^1.2.19",
"@ai-sdk/mistral": "^1.2.8",
"@ai-sdk/openai": "^1.3.22",
"@ai-sdk/anthropic": "^2.0.42",
"@ai-sdk/google": "^2.0.29",
"@ai-sdk/mistral": "^2.0.23",
"@ai-sdk/openai": "^2.0.64",
"@babel/generator": "^7.27.1",
"@babel/parser": "^7.27.1",
"@babel/traverse": "^7.27.4",
Expand All @@ -143,10 +143,10 @@
"@lingo.dev/_spec": "workspace:*",
"@markdoc/markdoc": "^0.5.4",
"@modelcontextprotocol/sdk": "^1.5.0",
"@openrouter/ai-sdk-provider": "^0.7.1",
"@openrouter/ai-sdk-provider": "^1.2.1",
"@paralleldrive/cuid2": "^2.2.2",
"@types/ejs": "^3.1.5",
"ai": "^4.3.15",
"ai": "^5.0.89",
"bitbucket": "^2.12.0",
"chalk": "^5.4.1",
"chokidar": "^4.0.3",
Expand Down Expand Up @@ -189,7 +189,7 @@
"node-webvtt": "^1.9.4",
"object-hash": "^3.0.0",
"octokit": "^4.0.2",
"ollama-ai-provider": "^1.2.0",
"ollama-ai-provider-v2": "^1.5.3",
"open": "^10.2.0",
"ora": "^8.1.1",
"p-limit": "^6.2.0",
Expand All @@ -216,7 +216,7 @@
"xml2js": "^0.6.2",
"xpath": "^0.0.34",
"yaml": "^2.7.0",
"zod": "^3.25.76"
"zod": "^4.1.12"
},
"devDependencies": {
"@types/babel__generator": "^7.27.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/cli/cmd/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -637,8 +637,8 @@ function parseFlags(options: any) {
strict: Z.boolean().optional(),
key: Z.string().optional(),
file: Z.array(Z.string()).optional(),
interactive: Z.boolean().default(false),
debug: Z.boolean().default(false),
interactive: Z.boolean().prefault(false),
debug: Z.boolean().prefault(false),
}).parse(options);
}

Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/cli/cmd/lockfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,5 @@ export default new Command()
});

const flagsSchema = Z.object({
force: Z.boolean().default(false),
force: Z.boolean().prefault(false),
});
4 changes: 2 additions & 2 deletions packages/cli/src/cli/cmd/mcp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ export default new Command()
"translate",
"Detect language and translate text with Lingo.dev.",
{
text: Z.string(),
targetLocale: Z.string().regex(/^[a-z]{2}(-[A-Z]{2})?$/),
text: Z.string() as any,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to manually test the MCP server

targetLocale: Z.string().regex(/^[a-z]{2}(-[A-Z]{2})?$/) as any,
},
async ({ text, targetLocale }) => {
const sourceLocale = await replexicaEngine.recognizeLocale(text);
Expand Down
10 changes: 5 additions & 5 deletions packages/cli/src/cli/cmd/run/_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ export const flagsSchema = z.object({
frozen: z.boolean().optional(),
verbose: z.boolean().optional(),
strict: z.boolean().optional(),
interactive: z.boolean().default(false),
concurrency: z.number().positive().default(10),
debug: z.boolean().default(false),
interactive: z.boolean().prefault(false),
concurrency: z.number().positive().prefault(10),
debug: z.boolean().prefault(false),
sourceLocale: z.string().optional(),
targetLocale: z.array(z.string()).optional(),
watch: z.boolean().default(false),
debounce: z.number().positive().default(5000), // 5 seconds default
watch: z.boolean().prefault(false),
debounce: z.number().positive().prefault(5000), // 5 seconds default
sound: z.boolean().optional(),
});
export type CmdRunFlags = z.infer<typeof flagsSchema>;
6 changes: 3 additions & 3 deletions packages/cli/src/cli/localizer/explicit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import { I18nConfig } from "@lingo.dev/_spec";
import chalk from "chalk";
import dedent from "dedent";
import { ILocalizer, LocalizerData } from "./_types";
import { LanguageModel, Message, generateText } from "ai";
import { LanguageModel, ModelMessage, generateText } from "ai";
import { colors } from "../constants";
import { jsonrepair } from "jsonrepair";
import { createOllama } from "ollama-ai-provider";
import { createOllama } from "ollama-ai-provider-v2";

export default function createExplicitLocalizer(
provider: NonNullable<I18nConfig["provider"]>,
Expand Down Expand Up @@ -207,7 +207,7 @@ function createAiSdkLocalizer(params: {
[
{ role: "user", content: JSON.stringify(userShot) },
{ role: "assistant", content: JSON.stringify(assistantShot) },
] as Message[],
] as ModelMessage[],
),
{ role: "user", content: JSON.stringify(payload) },
],
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/cli/processor/basic.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { generateText, LanguageModelV1 } from "ai";
import { generateText, LanguageModel } from "ai";
import { LocalizerInput, LocalizerProgressFn } from "./_base";
import _ from "lodash";

Expand All @@ -7,7 +7,7 @@ type ModelSettings = {
};

export function createBasicTranslator(
model: LanguageModelV1,
model: LanguageModel,
systemPrompt: string,
settings: ModelSettings = {},
) {
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/cli/processor/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { createAnthropic } from "@ai-sdk/anthropic";
import { createGoogleGenerativeAI } from "@ai-sdk/google";
import { createOpenRouter } from "@openrouter/ai-sdk-provider";
import { createMistral } from "@ai-sdk/mistral";
import { createOllama } from "ollama-ai-provider";
import { createOllama } from "ollama-ai-provider-v2";

export default function createProcessor(
provider: I18nConfig["provider"],
Expand Down
6 changes: 3 additions & 3 deletions packages/cli/src/cli/utils/delta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as path from "path";
import YAML from "yaml";

const LockSchema = z.object({
version: z.literal(1).default(1),
version: z.literal(1).prefault(1),
checksums: z
.record(
z.string(), // localizable files' keys
Expand All @@ -18,9 +18,9 @@ const LockSchema = z.object({
// checksum of the key's value in the source locale
z.string(),
)
.default({}),
.prefault({}),
)
.default({}),
.prefault({}),
});
export type LockData = z.infer<typeof LockSchema>;

Expand Down
16 changes: 8 additions & 8 deletions packages/cli/src/cli/utils/exec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,20 @@ export async function execWithRetry(
// Helpers

const ExecAsyncSchema = Z.object({
delay: Z.number().nonnegative().default(1000),
concurrency: Z.number().positive().default(1),
onProgress: Z.function(
Z.tuple([
delay: Z.number().nonnegative().prefault(1000),
concurrency: Z.number().positive().prefault(1),
onProgress: Z.function({
input: Z.tuple([
Z.number().positive(), // completed count
Z.number().positive(), // total count
]),
Z.void(),
).optional(),
output: Z.void(),
}).optional(),
});

const ExecWithRetrySchema = Z.object({
delay: Z.number().nonnegative().default(0),
attempts: Z.number().positive().default(3),
delay: Z.number().nonnegative().prefault(0),
attempts: Z.number().positive().prefault(3),
});

function delay(ms: number) {
Expand Down
6 changes: 3 additions & 3 deletions packages/cli/src/cli/utils/lockfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,13 @@ export function createLockfileHelper() {
}

const LockfileSchema = Z.object({
version: Z.literal(1).default(1),
version: Z.literal(1).prefault(1),
checksums: Z.record(
Z.string(), // localizable files' keys
Z.record(
// checksums hashmap
Z.string(), // key
Z.string(), // checksum of the key's value in the source locale
).default({}),
).default({}),
).prefault({}),
).prefault({}),
});
16 changes: 6 additions & 10 deletions packages/cli/src/cli/utils/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ function _loadDefaults(): CliSettings {
}

function _loadEnv() {
return Z.object({
return Z.looseObject({
LINGODOTDEV_API_KEY: Z.string().optional(),
LINGODOTDEV_API_URL: Z.string().optional(),
LINGODOTDEV_WEB_URL: Z.string().optional(),
Expand All @@ -106,9 +106,7 @@ function _loadEnv() {
GOOGLE_API_KEY: Z.string().optional(),
OPENROUTER_API_KEY: Z.string().optional(),
MISTRAL_API_KEY: Z.string().optional(),
})
.passthrough()
.parse(process.env);
}).parse(process.env);
}

function _loadSystemFile() {
Expand All @@ -118,23 +116,21 @@ function _loadSystemFile() {
: "";
const data = Ini.parse(content);

return Z.object({
auth: Z.object({
return Z.looseObject({
auth: Z.looseObject({
apiKey: Z.string().optional(),
apiUrl: Z.string().optional(),
webUrl: Z.string().optional(),
}).optional(),
llm: Z.object({
llm: Z.looseObject({
openaiApiKey: Z.string().optional(),
anthropicApiKey: Z.string().optional(),
groqApiKey: Z.string().optional(),
googleApiKey: Z.string().optional(),
openrouterApiKey: Z.string().optional(),
mistralApiKey: Z.string().optional(),
}).optional(),
})
.passthrough()
.parse(data);
}).parse(data);
}

function _saveSystemFile(settings: CliSettings) {
Expand Down
24 changes: 13 additions & 11 deletions packages/compiler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,30 +45,32 @@
"vitest": "^2.1.4"
},
"dependencies": {
"@ai-sdk/anthropic": "^1.0.11",
"@ai-sdk/google": "^1.2.19",
"@ai-sdk/groq": "^1.2.3",
"@ai-sdk/mistral": "^1.2.8",
"@ai-sdk/openai": "^1.3.22",
"@ai-sdk/anthropic": "^2.0.45",
"@ai-sdk/google": "^2.0.29",
"@ai-sdk/groq": "^2.0.28",
"@ai-sdk/mistral": "^2.0.23",
"@ai-sdk/openai": "^2.0.68",
"@babel/generator": "^7.26.5",
"@babel/parser": "^7.26.7",
"@babel/traverse": "^7.27.4",
"@babel/types": "^7.26.7",
"@lingo.dev/_sdk": "workspace:*",
"@lingo.dev/_spec": "workspace:*",
"@openrouter/ai-sdk-provider": "^0.7.1",
"ai": "^4.2.10",
"@openrouter/ai-sdk-provider": "^1.2.1",
"@prettier/sync": "^0.6.1",
"ai": "^5.0.89",
"dedent": "^1.6.0",
"dotenv": "^16.4.5",
"fast-xml-parser": "^5.0.8",
"ini": "^5.0.0",
"lodash": "^4.17.21",
"node-machine-id": "^1.1.12",
"object-hash": "^3.0.0",
"ollama-ai-provider": "^1.2.0",
"unplugin": "^2.1.2",
"zod": "^3.25.76",
"ollama-ai-provider-v2": "^1.5.3",
"posthog-node": "^5.5.1",
"node-machine-id": "^1.1.12"
"prettier": "^3.4.2",
"unplugin": "^2.1.2",
"zod": "^4.1.12"
},
"packageManager": "[email protected]"
}
2 changes: 1 addition & 1 deletion packages/compiler/src/lib/lcp/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createGroq } from "@ai-sdk/groq";
import { createGoogleGenerativeAI } from "@ai-sdk/google";
import { createOpenRouter } from "@openrouter/ai-sdk-provider";
import { createOllama } from "ollama-ai-provider";
import { createOllama } from "ollama-ai-provider-v2";
import { createMistral } from "@ai-sdk/mistral";
import { createOpenAI } from "@ai-sdk/openai";
import { createAnthropic } from "@ai-sdk/anthropic";
Expand Down
6 changes: 3 additions & 3 deletions packages/compiler/src/lib/lcp/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const lcpFile = z.object({
export type LCPFile = z.infer<typeof lcpFile>;

export const lcpSchema = z.object({
version: z.number().default(0.1),
version: z.number().prefault(0.1),
files: z.record(z.string(), lcpFile).optional(),
});

Expand All @@ -35,7 +35,7 @@ export const dictionaryFile = z.object({
export type DictionaryFile = z.infer<typeof dictionaryFile>;

export const dictionarySchema = z.object({
version: z.number().default(0.1),
version: z.number().prefault(0.1),
locale: z.string(),
files: z.record(z.string(), dictionaryFile),
});
Expand All @@ -55,7 +55,7 @@ export const dictionaryCacheFile = z.object({
});

export const dictionaryCacheSchema = z.object({
version: z.number().default(0.1),
version: z.number().prefault(0.1),
files: z.record(z.string(), dictionaryCacheFile),
});

Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"@lingo.dev/_spec": "workspace:*",
"@paralleldrive/cuid2": "^2.2.2",
"jsdom": "^25.0.1",
"zod": "^3.25.76"
"zod": "^4.1.12"
},
"devDependencies": {
"@types/jsdom": "^21.1.7",
Expand Down
3 changes: 1 addition & 2 deletions packages/spec/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@
"license": "Apache-2.0",
"dependencies": {
"@lingo.dev/_locales": "workspace:*",
"zod": "^3.25.76",
"zod-to-json-schema": "^3.24.5"
"zod": "^4.1.12"
},
"devDependencies": {
"@types/node": "^22.13.5",
Expand Down
Loading