chore(x): migrate to AI SDK 7

Bump apps/x from AI SDK v5 to v7 (single hop through the 6-0 and 7-0
migration guides). All deps upgraded via pnpm --filter:
ai@7, @ai-sdk/{anthropic@4,google@4,openai@4,openai-compatible@3,provider@4},
@openrouter/ai-sdk-provider@3, ollama-ai-provider-v2@4.

Changes (per the official migration guides):
- Provider spec bumped V2->V4: ProviderV2 -> ProviderV4 (models.ts, gateway.ts)
- streamText: result.fullStream -> result.stream (+ StreamTextInvoker seam,
  test fakes); stepCountIs -> isStepCount
- system -> instructions on SDK generateText/streamText/generateObject calls
  (left our own generateObjectSafe.system param untouched)
- allowSystemInMessages: true on calls passing stored messages (v7 rejects
  system-role messages in the array by default; convertFromMessages emits them)
- image content part {type:'image'} -> {type:'file'} (message-encoding.ts)
- tool() no longer accepts a `name` key (removed; tools keyed by ToolSet key)
- usage token relocation: cachedInputTokens -> inputTokenDetails.cacheReadTokens,
  reasoningTokens -> outputTokenDetails.reasoningTokens (mapUsage rewrite);
  renderer decoupled from LanguageModelUsage to a local flat UsageSummary
- providerMetadata relay cast to shared ProviderOptions (spec loosened)

No persisted-data changes: @x/shared is AI-SDK-free, so old chats
list/view/continue unchanged. Full typecheck clean; 637 tests pass
(shared 107, core 447, renderer 83); main.cjs bundles ESM-only ai into CJS.

Pending live check (needs creds): OpenAI strictJsonSchema now defaults true
in v7 and may reject zod schemas for openai-family flavors at runtime.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ramnique Singh 2026-07-13 16:22:36 +05:30
parent 10525c58b8
commit cc2daf1874
16 changed files with 210 additions and 207 deletions

View file

@ -49,7 +49,7 @@
"@x/shared": "workspace:*", "@x/shared": "workspace:*",
"@xterm/addon-fit": "^0.11.0", "@xterm/addon-fit": "^0.11.0",
"@xterm/xterm": "^6.0.0", "@xterm/xterm": "^6.0.0",
"ai": "^5.0.117", "ai": "^7.0.22",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"cmdk": "^1.1.1", "cmdk": "^1.1.1",

View file

@ -2,7 +2,7 @@ import * as React from 'react'
import { useCallback, useEffect, useLayoutEffect, useState, useRef } from 'react' import { useCallback, useEffect, useLayoutEffect, useState, useRef } from 'react'
import { workspace } from '@x/shared'; import { workspace } from '@x/shared';
import { RunEvent } from '@x/shared/src/runs.js'; import { RunEvent } from '@x/shared/src/runs.js';
import type { LanguageModelUsage, ToolUIPart } from 'ai'; import type { ToolUIPart } from 'ai';
import './App.css' import './App.css'
import z from 'zod'; import z from 'zod';
import { CheckIcon, LoaderIcon, PanelLeftIcon, ArrowLeft, ArrowRight, MessageSquare, ChevronLeftIcon, ChevronRightIcon, Plus, HistoryIcon } from 'lucide-react'; import { CheckIcon, LoaderIcon, PanelLeftIcon, ArrowLeft, ArrowRight, MessageSquare, ChevronLeftIcon, ChevronRightIcon, Plus, HistoryIcon } from 'lucide-react';
@ -458,7 +458,17 @@ const buildBgTaskSetupPrompt = (description: string) =>
const buildBgTaskEditPrompt = (slug: string) => const buildBgTaskEditPrompt = (slug: string) =>
`Let's tweak the background task \`${slug}\`. Please load the \`background-task\` skill first, read the task's current \`bg-tasks/${slug}/task.yaml\`, then ask me what I want to change.` `Let's tweak the background task \`${slug}\`. Please load the \`background-task\` skill first, read the task's current \`bg-tasks/${slug}/task.yaml\`, then ask me what I want to change.`
const normalizeUsage = (usage?: Partial<LanguageModelUsage> | null): LanguageModelUsage | null => { // The renderer displays our internal (flat) usage shape that arrives over IPC,
// not the AI SDK's restructured LanguageModelUsage (nested token details).
type UsageSummary = {
inputTokens?: number
outputTokens?: number
totalTokens?: number
reasoningTokens?: number
cachedInputTokens?: number
}
const normalizeUsage = (usage?: UsageSummary | null): UsageSummary | null => {
if (!usage) return null if (!usage) return null
const hasNumbers = Object.values(usage).some((value) => typeof value === 'number') const hasNumbers = Object.values(usage).some((value) => typeof value === 'number')
if (!hasNumbers) return null if (!hasNumbers) return null
@ -960,7 +970,7 @@ function App() {
return return
} }
}, [conversation]) }, [conversation])
const [, setModelUsage] = useState<LanguageModelUsage | null>(null) const [, setModelUsage] = useState<UsageSummary | null>(null)
const [runId, setRunId] = useState<string | null>(null) const [runId, setRunId] = useState<string | null>(null)
// New runtime: the active session's chat data + actions. All logic lives in // New runtime: the active session's chat data + actions. All logic lives in
// SessionChatStore (tested headlessly); the hook is a thin subscription. // SessionChatStore (tested headlessly); the hook is a thin subscription.

View file

@ -8,7 +8,6 @@ import {
} from "@/components/ui/hover-card"; } from "@/components/ui/hover-card";
import { Progress } from "@/components/ui/progress"; import { Progress } from "@/components/ui/progress";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import type { LanguageModelUsage } from "ai";
import { type ComponentProps, createContext, useContext } from "react"; import { type ComponentProps, createContext, useContext } from "react";
import { getUsage } from "tokenlens"; import { getUsage } from "tokenlens";
@ -20,10 +19,20 @@ const ICON_STROKE_WIDTH = 2;
type ModelId = string; type ModelId = string;
// Our internal (flat) usage shape received over IPC, not the AI SDK's
// restructured LanguageModelUsage (nested token details as of AI SDK 7).
type UsageSummary = {
inputTokens?: number;
outputTokens?: number;
totalTokens?: number;
reasoningTokens?: number;
cachedInputTokens?: number;
};
type ContextSchema = { type ContextSchema = {
usedTokens: number; usedTokens: number;
maxTokens: number; maxTokens: number;
usage?: LanguageModelUsage; usage?: UsageSummary;
modelId?: ModelId; modelId?: ModelId;
}; };

View file

@ -17,19 +17,19 @@
"@agentclientprotocol/claude-agent-acp": "^0.55.0", "@agentclientprotocol/claude-agent-acp": "^0.55.0",
"@agentclientprotocol/codex-acp": "^1.1.0", "@agentclientprotocol/codex-acp": "^1.1.0",
"@agentclientprotocol/sdk": "^1.1.0", "@agentclientprotocol/sdk": "^1.1.0",
"@ai-sdk/anthropic": "^2.0.63", "@ai-sdk/anthropic": "^4.0.12",
"@ai-sdk/google": "^2.0.53", "@ai-sdk/google": "^4.0.12",
"@ai-sdk/openai": "^2.0.91", "@ai-sdk/openai": "^4.0.11",
"@ai-sdk/openai-compatible": "^1.0.33", "@ai-sdk/openai-compatible": "^3.0.7",
"@ai-sdk/provider": "^2.0.1", "@ai-sdk/provider": "^4.0.3",
"@composio/core": "^0.6.0", "@composio/core": "^0.6.0",
"@google-cloud/local-auth": "^3.0.1", "@google-cloud/local-auth": "^3.0.1",
"@modelcontextprotocol/sdk": "^1.25.1", "@modelcontextprotocol/sdk": "^1.25.1",
"@openrouter/ai-sdk-provider": "^1.2.6", "@openrouter/ai-sdk-provider": "^3.0.0",
"@react-pdf/renderer": "^4.3.2", "@react-pdf/renderer": "^4.3.2",
"@types/react": "^19.2.7", "@types/react": "^19.2.7",
"@x/shared": "workspace:*", "@x/shared": "workspace:*",
"ai": "^5.0.133", "ai": "^7.0.22",
"awilix": "^12.0.5", "awilix": "^12.0.5",
"baileys": "7.0.0-rc13", "baileys": "7.0.0-rc13",
"chokidar": "^4.0.3", "chokidar": "^4.0.3",
@ -42,7 +42,7 @@
"isomorphic-git": "^1.29.0", "isomorphic-git": "^1.29.0",
"mammoth": "^1.11.0", "mammoth": "^1.11.0",
"node-html-markdown": "^2.0.0", "node-html-markdown": "^2.0.0",
"ollama-ai-provider-v2": "^1.5.4", "ollama-ai-provider-v2": "^4.0.1",
"openid-client": "^6.8.1", "openid-client": "^6.8.1",
"papaparse": "^5.5.3", "papaparse": "^5.5.3",
"pdf-parse": "^2.4.5", "pdf-parse": "^2.4.5",

View file

@ -304,8 +304,8 @@ async function handleLlmGenerate(
const model = createProvider(providerConfig).languageModel(resolved.model); const model = createProvider(providerConfig).languageModel(resolved.model);
const result = await withUseCase({ useCase: 'app_llm_generate', subUseCase: slug }, () => generateText({ const result = await withUseCase({ useCase: 'app_llm_generate', subUseCase: slug }, () => generateText({
model, model,
...(system ? { system } : {}), ...(system ? { instructions: system } : {}),
...(rawMessages ? { messages: rawMessages as ModelMessage[] } : { prompt: prompt as string }), ...(rawMessages ? { messages: rawMessages as ModelMessage[], allowSystemInMessages: true } : { prompt: prompt as string }),
...(temperature !== undefined ? { temperature } : {}), ...(temperature !== undefined ? { temperature } : {}),
maxOutputTokens, maxOutputTokens,
})); }));

View file

@ -653,7 +653,7 @@ Respond with ONLY valid JSON: either a schedule object or null. No other text.`;
try { try {
const result = await withUseCase({ useCase: 'knowledge_sync', subUseCase: 'inline_task_classify' }, () => generateText({ const result = await withUseCase({ useCase: 'knowledge_sync', subUseCase: 'inline_task_classify' }, () => generateText({
model, model,
system: systemPrompt, instructions: systemPrompt,
prompt: instruction, prompt: instruction,
})); }));

View file

@ -181,7 +181,7 @@ async function generateBrief(event: CalendarEvent, ctx: Awaited<ReturnType<typeo
const result = await withUseCase({ useCase: 'meeting_prep' }, () => generateText({ const result = await withUseCase({ useCase: 'meeting_prep' }, () => generateText({
model, model,
system: BRIEF_SYSTEM, instructions: BRIEF_SYSTEM,
prompt: parts.join('\n\n'), prompt: parts.join('\n\n'),
})); }));
captureLlmUsage({ useCase: 'meeting_prep', model: modelId, provider: providerName, usage: result.usage }); captureLlmUsage({ useCase: 'meeting_prep', model: modelId, provider: providerName, usage: result.usage });

View file

@ -154,7 +154,7 @@ export async function summarizeMeeting(transcript: string, meetingStartTime?: st
const result = await withUseCase({ useCase: 'meeting_note' }, () => generateText({ const result = await withUseCase({ useCase: 'meeting_note' }, () => generateText({
model, model,
system: SYSTEM_PROMPT, instructions: SYSTEM_PROMPT,
prompt, prompt,
})); }));

View file

@ -1,4 +1,4 @@
import { ProviderV2 } from '@ai-sdk/provider'; import { ProviderV4 } from '@ai-sdk/provider';
import { createOpenRouter } from '@openrouter/ai-sdk-provider'; import { createOpenRouter } from '@openrouter/ai-sdk-provider';
import { getAccessToken } from '../auth/tokens.js'; import { getAccessToken } from '../auth/tokens.js';
import { getCurrentUseCase } from '../analytics/use_case.js'; import { getCurrentUseCase } from '../analytics/use_case.js';
@ -16,7 +16,7 @@ const authedFetch: typeof fetch = async (input, init) => {
return fetch(input, { ...init, headers }); return fetch(input, { ...init, headers });
}; };
export function getGatewayProvider(): ProviderV2 { export function getGatewayProvider(): ProviderV4 {
return createOpenRouter({ return createOpenRouter({
baseURL: `${API_URL}/v1/llm`, baseURL: `${API_URL}/v1/llm`,
apiKey: 'managed-by-rowboat', apiKey: 'managed-by-rowboat',

View file

@ -1,4 +1,4 @@
import { ProviderV2 } from "@ai-sdk/provider"; import { ProviderV4 } from "@ai-sdk/provider";
import { createGateway, generateText, type LanguageModel } from "ai"; import { createGateway, generateText, type LanguageModel } from "ai";
import { createOpenAI } from "@ai-sdk/openai"; import { createOpenAI } from "@ai-sdk/openai";
import { createGoogleGenerativeAI } from "@ai-sdk/google"; import { createGoogleGenerativeAI } from "@ai-sdk/google";
@ -22,7 +22,7 @@ import {
export const Provider = LlmProvider; export const Provider = LlmProvider;
export const ModelConfig = LlmModelConfig; export const ModelConfig = LlmModelConfig;
export function createProvider(config: z.infer<typeof Provider>): ProviderV2 { export function createProvider(config: z.infer<typeof Provider>): ProviderV4 {
const { apiKey, baseURL, headers } = config; const { apiKey, baseURL, headers } = config;
switch (config.flavor) { switch (config.flavor) {
case "openai": case "openai":
@ -78,7 +78,7 @@ export function createProvider(config: z.infer<typeof Provider>): ProviderV2 {
apiKey, apiKey,
baseURL, baseURL,
headers, headers,
}) as unknown as ProviderV2; }) as unknown as ProviderV4;
case "rowboat": case "rowboat":
return getGatewayProvider(); return getGatewayProvider();
default: default:
@ -342,7 +342,7 @@ export async function generateOneShot(opts: GenerateTextOptions): Promise<Genera
{ useCase: "copilot_chat", subUseCase: "email_compose" }, { useCase: "copilot_chat", subUseCase: "email_compose" },
() => generateText({ () => generateText({
model: languageModel, model: languageModel,
...(opts.system ? { system: opts.system } : {}), ...(opts.system ? { instructions: opts.system } : {}),
prompt: opts.prompt, prompt: opts.prompt,
}), }),
); );

View file

@ -44,7 +44,7 @@ export async function generateObjectSafe<T>(
try { try {
const result = await generateObject({ const result = await generateObject({
model: options.model, model: options.model,
...(options.system ? { system: options.system } : {}), ...(options.system ? { instructions: options.system } : {}),
prompt: options.prompt, prompt: options.prompt,
schema: options.schema, schema: options.schema,
}); });
@ -68,7 +68,7 @@ export async function generateObjectSafe<T>(
].join("\n\n").trim(); ].join("\n\n").trim();
const result = await generateObject({ const result = await generateObject({
model: options.model, model: options.model,
system, instructions: system,
prompt: options.prompt, prompt: options.prompt,
schema: options.schema, schema: options.schema,
}); });

View file

@ -101,7 +101,9 @@ export function convertFromMessages(messages: z.infer<typeof Message>[]): ModelM
// model knows which images show the user vs their screen. // model knows which images show the user vs their screen.
const textSegments: string[] = userMessageContextPrefix ? [userMessageContextPrefix] : []; const textSegments: string[] = userMessageContextPrefix ? [userMessageContextPrefix] : [];
const attachmentLines: string[] = []; const attachmentLines: string[] = [];
type EncodedImagePart = { type: "image"; image: string; mediaType: string }; // AI SDK 7 collapsed the `image` content part into `file`
// (data + mediaType); image parts are deprecated.
type EncodedImagePart = { type: "file"; data: string; mediaType: string };
const cameraParts: EncodedImagePart[] = []; const cameraParts: EncodedImagePart[] = [];
const screenParts: EncodedImagePart[] = []; const screenParts: EncodedImagePart[] = [];
const frameTimes: string[] = []; const frameTimes: string[] = [];
@ -113,7 +115,7 @@ export function convertFromMessages(messages: z.infer<typeof Message>[]): ModelM
attachmentLines.push(`- ${part.filename} (${part.mimeType}${sizeStr}) at ${part.path}${lineStr}`); attachmentLines.push(`- ${part.filename} (${part.mimeType}${sizeStr}) at ${part.path}${lineStr}`);
} else if (part.type === "image") { } else if (part.type === "image") {
const target = part.source === "screen" ? screenParts : cameraParts; const target = part.source === "screen" ? screenParts : cameraParts;
target.push({ type: "image", image: part.data, mediaType: part.mediaType }); target.push({ type: "file", data: part.data, mediaType: part.mediaType });
if (part.capturedAt) frameTimes.push(part.capturedAt); if (part.capturedAt) frameTimes.push(part.capturedAt);
} else { } else {
textSegments.push(part.text); textSegments.push(part.text);

View file

@ -1,7 +1,7 @@
import { jsonSchema } from "ai"; import { jsonSchema } from "ai";
import { Agent, ToolAttachment } from "@x/shared/dist/agent.js"; import { Agent, ToolAttachment } from "@x/shared/dist/agent.js";
import { AssistantContentPart, AssistantMessage, MessageList, ProviderOptions, ToolCallPart, ToolMessage, UserMessageContext } from "@x/shared/dist/message.js"; import { AssistantContentPart, AssistantMessage, MessageList, ProviderOptions, ToolCallPart, ToolMessage, UserMessageContext } from "@x/shared/dist/message.js";
import { LanguageModel, stepCountIs, streamText, tool, Tool, ToolSet } from "ai"; import { LanguageModel, isStepCount, streamText, tool, Tool, ToolSet } from "ai";
import { z } from "zod"; import { z } from "zod";
import { LlmStepStreamEvent } from "@x/shared/dist/llm-step-events.js"; import { LlmStepStreamEvent } from "@x/shared/dist/llm-step-events.js";
import { execTool } from "../tools/exec-tool.js"; import { execTool } from "../tools/exec-tool.js";
@ -255,7 +255,6 @@ async function mapAgentTool(t: z.infer<typeof ToolAttachment>): Promise<Tool> {
switch (t.type) { switch (t.type) {
case "mcp": case "mcp":
return tool({ return tool({
name: t.name,
description: t.description, description: t.description,
inputSchema: jsonSchema(t.inputSchema), inputSchema: jsonSchema(t.inputSchema),
}); });
@ -265,7 +264,6 @@ async function mapAgentTool(t: z.infer<typeof ToolAttachment>): Promise<Tool> {
throw new Error(`Agent ${t.name} not found`); throw new Error(`Agent ${t.name} not found`);
} }
return tool({ return tool({
name: t.name,
description: agent.description, description: agent.description,
inputSchema: z.object({ inputSchema: z.object({
message: z.string().describe("The message to send to the workflow"), message: z.string().describe("The message to send to the workflow"),
@ -1151,21 +1149,23 @@ async function* streamLlm(
}, () => streamText({ }, () => streamText({
model, model,
messages: converted, messages: converted,
system: instructions, instructions,
allowSystemInMessages: true,
tools, tools,
stopWhen: stepCountIs(1), stopWhen: isStepCount(1),
abortSignal: signal, abortSignal: signal,
})) }))
: streamText({ : streamText({
model, model,
messages: converted, messages: converted,
system: instructions, instructions,
allowSystemInMessages: true,
tools, tools,
stopWhen: stepCountIs(1), stopWhen: isStepCount(1),
abortSignal: signal, abortSignal: signal,
}); });
const { fullStream } = streamResult; const { stream } = streamResult;
for await (const event of fullStream) { for await (const event of stream) {
// Check abort on every chunk for responsiveness // Check abort on every chunk for responsiveness
signal?.throwIfAborted(); signal?.throwIfAborted();
console.log("-> \t\tstream event", JSON.stringify(event)); console.log("-> \t\tstream event", JSON.stringify(event));
@ -1179,39 +1179,39 @@ async function* streamLlm(
case "reasoning-start": case "reasoning-start":
yield { yield {
type: "reasoning-start", type: "reasoning-start",
providerOptions: event.providerMetadata, providerOptions: event.providerMetadata as z.infer<typeof ProviderOptions> | undefined,
}; };
break; break;
case "reasoning-delta": case "reasoning-delta":
yield { yield {
type: "reasoning-delta", type: "reasoning-delta",
delta: event.text, delta: event.text,
providerOptions: event.providerMetadata, providerOptions: event.providerMetadata as z.infer<typeof ProviderOptions> | undefined,
}; };
break; break;
case "reasoning-end": case "reasoning-end":
yield { yield {
type: "reasoning-end", type: "reasoning-end",
providerOptions: event.providerMetadata, providerOptions: event.providerMetadata as z.infer<typeof ProviderOptions> | undefined,
}; };
break; break;
case "text-start": case "text-start":
yield { yield {
type: "text-start", type: "text-start",
providerOptions: event.providerMetadata, providerOptions: event.providerMetadata as z.infer<typeof ProviderOptions> | undefined,
}; };
break; break;
case "text-end": case "text-end":
yield { yield {
type: "text-end", type: "text-end",
providerOptions: event.providerMetadata, providerOptions: event.providerMetadata as z.infer<typeof ProviderOptions> | undefined,
}; };
break; break;
case "text-delta": case "text-delta":
yield { yield {
type: "text-delta", type: "text-delta",
delta: event.text, delta: event.text,
providerOptions: event.providerMetadata, providerOptions: event.providerMetadata as z.infer<typeof ProviderOptions> | undefined,
}; };
break; break;
case "tool-call": case "tool-call":
@ -1220,7 +1220,7 @@ async function* streamLlm(
toolCallId: event.toolCallId, toolCallId: event.toolCallId,
toolName: event.toolName, toolName: event.toolName,
input: event.input, input: event.input,
providerOptions: event.providerMetadata, providerOptions: event.providerMetadata as z.infer<typeof ProviderOptions> | undefined,
}; };
break; break;
case "finish-step": case "finish-step":
@ -1238,7 +1238,7 @@ async function* streamLlm(
type: "finish-step", type: "finish-step",
usage: event.usage, usage: event.usage,
finishReason: event.finishReason, finishReason: event.finishReason,
providerOptions: event.providerMetadata, providerOptions: event.providerMetadata as z.infer<typeof ProviderOptions> | undefined,
}; };
break; break;
default: default:

View file

@ -15,7 +15,7 @@ function makeRegistry(parts: Array<Record<string, unknown>>, capture: InvokerOpt
invoke: (options) => { invoke: (options) => {
capture.push(options); capture.push(options);
return { return {
fullStream: (async function* () { stream: (async function* () {
yield* parts; yield* parts;
})(), })(),
}; };
@ -378,7 +378,7 @@ describe("RealModelRegistry", () => {
invoke: (options) => { invoke: (options) => {
capture.push(options); capture.push(options);
return { return {
fullStream: (async function* () { stream: (async function* () {
yield { type: "finish-step", finishReason: "stop", usage: {} }; yield { type: "finish-step", finishReason: "stop", usage: {} };
})(), })(),
}; };
@ -528,7 +528,7 @@ describe("RealModelRegistry", () => {
invoke: (options) => { invoke: (options) => {
capture.push(options); capture.push(options);
return { return {
fullStream: (async function* () { stream: (async function* () {
yield { type: "finish-step", finishReason: "stop", usage: {} }; yield { type: "finish-step", finishReason: "stop", usage: {} };
})(), })(),
}; };

View file

@ -1,6 +1,6 @@
import { import {
jsonSchema, jsonSchema,
stepCountIs, isStepCount,
streamText, streamText,
tool, tool,
type LanguageModel, type LanguageModel,
@ -39,10 +39,18 @@ export type StreamTextInvoker = (options: {
topP?: number; topP?: number;
maxOutputTokens?: number; maxOutputTokens?: number;
providerOptions?: Record<string, Record<string, JsonValue>>; providerOptions?: Record<string, Record<string, JsonValue>>;
}) => { fullStream: AsyncIterable<unknown> }; }) => { stream: AsyncIterable<unknown> };
const defaultInvoker: StreamTextInvoker = (options) => const defaultInvoker: StreamTextInvoker = ({ system, ...options }) =>
streamText({ ...options, stopWhen: stepCountIs(1) }); // Our seam keeps a `system` field; the SDK's top-level option is now
// `instructions`. `allowSystemInMessages` opts into system-role messages
// in the array (v7 rejects them by default) — persisted chats rely on it.
streamText({
...options,
instructions: system,
allowSystemInMessages: true,
stopWhen: isStepCount(1),
});
export interface RealModelRegistryDeps { export interface RealModelRegistryDeps {
resolveProvider?: (name: string) => Promise<z.infer<typeof LlmProvider>>; resolveProvider?: (name: string) => Promise<z.infer<typeof LlmProvider>>;
@ -217,7 +225,7 @@ export class RealModelRegistry implements IModelRegistry {
...generationParams, ...generationParams,
}); });
for await (const raw of result.fullStream) { for await (const raw of result.stream) {
request.signal.throwIfAborted(); request.signal.throwIfAborted();
const event = raw as { const event = raw as {
type: string; type: string;
@ -226,7 +234,13 @@ export class RealModelRegistry implements IModelRegistry {
toolName?: string; toolName?: string;
input?: unknown; input?: unknown;
finishReason?: string; finishReason?: string;
usage?: Record<string, number | undefined>; usage?: {
inputTokens?: number;
outputTokens?: number;
totalTokens?: number;
inputTokenDetails?: { cacheReadTokens?: number | undefined };
outputTokenDetails?: { reasoningTokens?: number | undefined };
};
providerMetadata?: unknown; providerMetadata?: unknown;
error?: unknown; error?: unknown;
}; };
@ -390,24 +404,33 @@ function mergeProviderOptions(
} }
function mapUsage( function mapUsage(
usage: Record<string, number | undefined> | undefined, usage:
| {
inputTokens?: number;
outputTokens?: number;
totalTokens?: number;
inputTokenDetails?: { cacheReadTokens?: number | undefined };
outputTokenDetails?: { reasoningTokens?: number | undefined };
}
| undefined,
): z.infer<typeof TurnUsage> { ): z.infer<typeof TurnUsage> {
const mapped: z.infer<typeof TurnUsage> = {}; const mapped: z.infer<typeof TurnUsage> = {};
if (!usage) { if (!usage) {
return mapped; return mapped;
} }
for (const key of [ // AI SDK 7 relocated cached/reasoning tokens into nested detail objects
"inputTokens", // (usage.inputTokenDetails.cacheReadTokens, usage.outputTokenDetails.reasoningTokens);
"outputTokens", // our persisted TurnUsage keeps the flat names.
"totalTokens", const put = (key: keyof z.infer<typeof TurnUsage>, value: number | undefined) => {
"reasoningTokens",
"cachedInputTokens",
] as const) {
const value = usage[key];
if (typeof value === "number" && Number.isFinite(value)) { if (typeof value === "number" && Number.isFinite(value)) {
mapped[key] = value; mapped[key] = value;
} }
} };
put("inputTokens", usage.inputTokens);
put("outputTokens", usage.outputTokens);
put("totalTokens", usage.totalTokens);
put("reasoningTokens", usage.outputTokenDetails?.reasoningTokens);
put("cachedInputTokens", usage.inputTokenDetails?.cacheReadTokens);
return mapped; return mapped;
} }

243
apps/x/pnpm-lock.yaml generated
View file

@ -170,7 +170,7 @@ importers:
version: 6.43.1 version: 6.43.1
'@eigenpal/docx-editor-react': '@eigenpal/docx-editor-react':
specifier: ^1.0.3 specifier: ^1.0.3
version: 1.0.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(ai@5.0.117(zod@4.2.1))(prosemirror-commands@1.7.1)(prosemirror-dropcursor@1.8.2)(prosemirror-history@1.5.0)(prosemirror-keymap@1.2.3)(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-tables@1.8.5)(prosemirror-transform@1.12.0)(prosemirror-view@1.41.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) version: 1.0.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(ai@7.0.22(zod@4.2.1))(prosemirror-commands@1.7.1)(prosemirror-dropcursor@1.8.2)(prosemirror-history@1.5.0)(prosemirror-keymap@1.2.3)(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-tables@1.8.5)(prosemirror-transform@1.12.0)(prosemirror-view@1.41.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@lezer/highlight': '@lezer/highlight':
specifier: ^1.2.3 specifier: ^1.2.3
version: 1.2.3 version: 1.2.3
@ -265,8 +265,8 @@ importers:
specifier: ^6.0.0 specifier: ^6.0.0
version: 6.0.0 version: 6.0.0
ai: ai:
specifier: ^5.0.117 specifier: ^7.0.22
version: 5.0.117(zod@4.2.1) version: 7.0.22(zod@4.2.1)
class-variance-authority: class-variance-authority:
specifier: ^0.7.1 specifier: ^0.7.1
version: 0.7.1 version: 0.7.1
@ -434,20 +434,20 @@ importers:
specifier: ^1.1.0 specifier: ^1.1.0
version: 1.1.0(zod@4.2.1) version: 1.1.0(zod@4.2.1)
'@ai-sdk/anthropic': '@ai-sdk/anthropic':
specifier: ^2.0.63 specifier: ^4.0.12
version: 2.0.70(zod@4.2.1) version: 4.0.12(zod@4.2.1)
'@ai-sdk/google': '@ai-sdk/google':
specifier: ^2.0.53 specifier: ^4.0.12
version: 2.0.61(zod@4.2.1) version: 4.0.12(zod@4.2.1)
'@ai-sdk/openai': '@ai-sdk/openai':
specifier: ^2.0.91 specifier: ^4.0.11
version: 2.0.99(zod@4.2.1) version: 4.0.11(zod@4.2.1)
'@ai-sdk/openai-compatible': '@ai-sdk/openai-compatible':
specifier: ^1.0.33 specifier: ^3.0.7
version: 1.0.34(zod@4.2.1) version: 3.0.7(zod@4.2.1)
'@ai-sdk/provider': '@ai-sdk/provider':
specifier: ^2.0.1 specifier: ^4.0.3
version: 2.0.1 version: 4.0.3
'@composio/core': '@composio/core':
specifier: ^0.6.0 specifier: ^0.6.0
version: 0.6.2(ws@8.21.0)(zod@4.2.1) version: 0.6.2(ws@8.21.0)(zod@4.2.1)
@ -458,8 +458,8 @@ importers:
specifier: ^1.25.1 specifier: ^1.25.1
version: 1.25.1(hono@4.11.3)(zod@4.2.1) version: 1.25.1(hono@4.11.3)(zod@4.2.1)
'@openrouter/ai-sdk-provider': '@openrouter/ai-sdk-provider':
specifier: ^1.2.6 specifier: ^3.0.0
version: 1.5.4(ai@5.0.151(zod@4.2.1))(zod@4.2.1) version: 3.0.0(ai@7.0.22(zod@4.2.1))(zod@4.2.1)
'@react-pdf/renderer': '@react-pdf/renderer':
specifier: ^4.3.2 specifier: ^4.3.2
version: 4.3.2(react@19.2.3) version: 4.3.2(react@19.2.3)
@ -470,8 +470,8 @@ importers:
specifier: workspace:* specifier: workspace:*
version: link:../shared version: link:../shared
ai: ai:
specifier: ^5.0.133 specifier: ^7.0.22
version: 5.0.151(zod@4.2.1) version: 7.0.22(zod@4.2.1)
awilix: awilix:
specifier: ^12.0.5 specifier: ^12.0.5
version: 12.0.5 version: 12.0.5
@ -509,8 +509,8 @@ importers:
specifier: ^2.0.0 specifier: ^2.0.0
version: 2.0.0 version: 2.0.0
ollama-ai-provider-v2: ollama-ai-provider-v2:
specifier: ^1.5.4 specifier: ^4.0.1
version: 1.5.5(zod@4.2.1) version: 4.0.1(ai@7.0.22(zod@4.2.1))(zod@4.2.1)
openid-client: openid-client:
specifier: ^6.8.1 specifier: ^6.8.1
version: 6.8.1 version: 6.8.1
@ -602,57 +602,45 @@ packages:
peerDependencies: peerDependencies:
zod: ^3.25.0 || ^4.0.0 zod: ^3.25.0 || ^4.0.0
'@ai-sdk/anthropic@2.0.70': '@ai-sdk/anthropic@4.0.12':
resolution: {integrity: sha512-W3WjQlb0Ho+CVAQUvb8Rtk3hGS3Jlgy79ihY2H0yj2k4yU8XuxpQw0Oz+7JQsB47j+jlHhk7nUXtxhAeRg3S3Q==} resolution: {integrity: sha512-IquWNkGRSF2ulYJ6YIIUqMsNAIDeZFB3/4W92aSOtCxH1TfuVoq3qw4M4TxTxIw4As9cnkeRLe7b9LDMzPDsnA==}
engines: {node: '>=18'} engines: {node: '>=22'}
peerDependencies: peerDependencies:
zod: ^3.25.76 || ^4.1.8 zod: ^3.25.76 || ^4.1.8
'@ai-sdk/gateway@2.0.24': '@ai-sdk/gateway@4.0.16':
resolution: {integrity: sha512-mflk80YF8hj8vrF9e1IHhovGKC1ubX+sY88pesSk3pUiXfH5VPO8dgzNnxjwsqsCZrnkHcztxS5cSl4TzSiEuA==} resolution: {integrity: sha512-9iYxdOLquoOFk5e+02P9qfBIA+EJU0FNJvyjGxi4iXJabt2+GlbaCg7TX0sTtxOsBVkdabkatqWM6+kvp53tBg==}
engines: {node: '>=18'} engines: {node: '>=22'}
peerDependencies: peerDependencies:
zod: ^3.25.76 || ^4.1.8 zod: ^3.25.76 || ^4.1.8
'@ai-sdk/gateway@2.0.56': '@ai-sdk/google@4.0.12':
resolution: {integrity: sha512-omvb2Bwpgqg8PKqOpYdIaW+fdEIWcfm2B/j3dx37DxzOIt6fr57VVcfw7pu/EaACcY0O+wsg50iFCPGcsI2Cbg==} resolution: {integrity: sha512-4Rw4viFwH2Wprx6OssZzhV/KgNWaA7qYr5Kg28AlZ7r3sEvyXH0kDZtZok7onPjr0RuFTg2EjCjTIeoCesg0Ww==}
engines: {node: '>=18'} engines: {node: '>=22'}
peerDependencies: peerDependencies:
zod: ^3.25.76 || ^4.1.8 zod: ^3.25.76 || ^4.1.8
'@ai-sdk/google@2.0.61': '@ai-sdk/openai-compatible@3.0.7':
resolution: {integrity: sha512-hIs7UvL8X5MBG3uxdciSotD4I27UcMa4/we9Qf98fM/RgMTwyk9zXcr7GM6k5yLBZ5S0QeZWkfqKwtdiDnUEEQ==} resolution: {integrity: sha512-y8RVpm8BZKNHDxlbNVt/GYmoBBqLx10m4d7bOzOnRD8V2aP3Cr6/g/bfubR4EkbW1ySrnPr62svZIeND2fdp3Q==}
engines: {node: '>=18'} engines: {node: '>=22'}
peerDependencies: peerDependencies:
zod: ^3.25.76 || ^4.1.8 zod: ^3.25.76 || ^4.1.8
'@ai-sdk/openai-compatible@1.0.34': '@ai-sdk/openai@4.0.11':
resolution: {integrity: sha512-AnGoxVNZ/E3EU4lW12rrufI6riqL2cEv4jk3OrjJ/i54XwR0CJU1V26jXAwxb+Pc+uZmYG++HM+gzXxPQZkMNQ==} resolution: {integrity: sha512-2PLnVPBsdJusgquPVYgPWd3ox4lbUFkp7DVUSmM0lQ4VISQoNxdgo6TvFAHgwQn9wJ/ckVYVRLU7+BvHc7T8ww==}
engines: {node: '>=18'} engines: {node: '>=22'}
peerDependencies: peerDependencies:
zod: ^3.25.76 || ^4.1.8 zod: ^3.25.76 || ^4.1.8
'@ai-sdk/openai@2.0.99': '@ai-sdk/provider-utils@5.0.7':
resolution: {integrity: sha512-wwa1/DuO9XThaA+sAi0d3+xfkbEx9nRhZ1USV6kktndmEs8aQRR0DJK/Iec+mwNu06IhfDGd5vMscR1U1q155g==} resolution: {integrity: sha512-OSm5/5kdrHa11WIOo5LYgDKnxYWp5aB/wx5EXRHi0jpUGduMDeB6oht9U6p+UNNWIP3F/EqPpV8d7vdP/iRnqg==}
engines: {node: '>=18'} engines: {node: '>=22'}
peerDependencies: peerDependencies:
zod: ^3.25.76 || ^4.1.8 zod: ^3.25.76 || ^4.1.8
'@ai-sdk/provider-utils@3.0.20': '@ai-sdk/provider@4.0.3':
resolution: {integrity: sha512-iXHVe0apM2zUEzauqJwqmpC37A5rihrStAih5Ks+JE32iTe4LZ58y17UGBjpQQTCRw9YxMeo2UFLxLpBluyvLQ==} resolution: {integrity: sha512-e0CpNWJUY7OxAFAnCZkw+ri9QOHWwTs1tXP42782KFGCU07qt8NiXCrCVowyCB5dP2r5/Uls+g2oPd8kOJn9dw==}
engines: {node: '>=18'} engines: {node: '>=22'}
peerDependencies:
zod: ^3.25.76 || ^4.1.8
'@ai-sdk/provider-utils@3.0.22':
resolution: {integrity: sha512-fFT1KfUUKktfAFm5mClJhS1oux9tP2qgzmEZVl5UdwltQ1LO/s8hd7znVrgKzivwv1s1FIPza0s9OpJaNB/vHw==}
engines: {node: '>=18'}
peerDependencies:
zod: ^3.25.76 || ^4.1.8
'@ai-sdk/provider@2.0.1':
resolution: {integrity: sha512-KCUwswvsC5VsW2PWFqF8eJgSCu5Ysj7m1TxiHTVA6g7k360bk0RNQENT8KTMAYEs+8fWPD3Uu4dEmzGHc+jGng==}
engines: {node: '>=18'}
'@antfu/install-pkg@1.1.0': '@antfu/install-pkg@1.1.0':
resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==}
@ -2344,15 +2332,12 @@ packages:
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@openrouter/ai-sdk-provider@1.5.4': '@openrouter/ai-sdk-provider@3.0.0':
resolution: {integrity: sha512-xrSQPUIH8n9zuyYZR0XK7Ba0h2KsjJcMkxnwaYfmv13pKs3sDkjPzVPPhlhzqBGddHb5cFEwJ9VFuFeDcxCDSw==} resolution: {integrity: sha512-m9XTSWoODH2RM5OsZpaGiN7QRR8cdP5paBWq699Tu3JVmGPBKT8xF8XwV0ZBVVsjikD/JgWfak4VSsTR4wAVbg==}
engines: {node: '>=18'} engines: {node: '>=22'}
peerDependencies: peerDependencies:
ai: ^5.0.0 ai: ^7.0.0
zod: ^3.24.1 || ^v4 zod: ^3.25.76 || ^4.1.8
'@openrouter/sdk@0.1.27':
resolution: {integrity: sha512-RH//L10bSmc81q25zAZudiI4kNkLgxF2E+WU42vghp3N6TEvZ6F0jK7uT3tOxkEn91gzmMw9YVmDENy7SJsajQ==}
'@opentelemetry/api-logs@0.208.0': '@opentelemetry/api-logs@0.208.0':
resolution: {integrity: sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg==} resolution: {integrity: sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg==}
@ -4339,12 +4324,8 @@ packages:
'@upsetjs/venn.js@2.0.0': '@upsetjs/venn.js@2.0.0':
resolution: {integrity: sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==} resolution: {integrity: sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==}
'@vercel/oidc@3.0.5': '@vercel/oidc@3.2.0':
resolution: {integrity: sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw==} resolution: {integrity: sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==}
engines: {node: '>= 20'}
'@vercel/oidc@3.1.0':
resolution: {integrity: sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==}
engines: {node: '>= 20'} engines: {node: '>= 20'}
'@vitejs/plugin-react@5.1.2': '@vitejs/plugin-react@5.1.2':
@ -4430,6 +4411,9 @@ packages:
'@webassemblyjs/wast-printer@1.14.1': '@webassemblyjs/wast-printer@1.14.1':
resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==}
'@workflow/serde@4.1.0':
resolution: {integrity: sha512-pav4F2BoirECWR7Nf1TKt+2eETcBj7jj4cBefQ8VXQCA6NPkaKeLfj/zMgi+3zYV5ZIBT4GuUiphsj0/b9hPQQ==}
'@xmldom/xmldom@0.8.11': '@xmldom/xmldom@0.8.11':
resolution: {integrity: sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==} resolution: {integrity: sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==}
engines: {node: '>=10.0.0'} engines: {node: '>=10.0.0'}
@ -4506,15 +4490,9 @@ packages:
resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
engines: {node: '>=8'} engines: {node: '>=8'}
ai@5.0.117: ai@7.0.22:
resolution: {integrity: sha512-uE6HNkdSwxbeHGKP/YbvapwD8fMOpj87wyfT9Z00pbzOh2fpnw5acak/4kzU00SX2vtI9K0uuy+9Tf9ytw5RwA==} resolution: {integrity: sha512-iAXYwQtR18qN7GXwNmGVAQM4uSJOh2+nZ5RP9NtDXfH5d4tlYyYzAM133O3U+eVcyWrvNRzecN9yW58xpCdfMg==}
engines: {node: '>=18'} engines: {node: '>=22'}
peerDependencies:
zod: ^3.25.76 || ^4.1.8
ai@5.0.151:
resolution: {integrity: sha512-tsLIv+QN9wJ/xl/fnYgjRYoGSThdnOfU4d6+7QEUKX3EcwviWMEaL1gOE+zfdkcay/Tbc02ZBtTRHoulS6DYvQ==}
engines: {node: '>=18'}
peerDependencies: peerDependencies:
zod: ^3.25.76 || ^4.1.8 zod: ^3.25.76 || ^4.1.8
@ -5681,6 +5659,10 @@ packages:
resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==}
engines: {node: '>=18.0.0'} engines: {node: '>=18.0.0'}
eventsource-parser@3.1.0:
resolution: {integrity: sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==}
engines: {node: '>=18.0.0'}
eventsource@3.0.7: eventsource@3.0.7:
resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==}
engines: {node: '>=18.0.0'} engines: {node: '>=18.0.0'}
@ -7314,10 +7296,11 @@ packages:
obug@2.1.1: obug@2.1.1:
resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==}
ollama-ai-provider-v2@1.5.5: ollama-ai-provider-v2@4.0.1:
resolution: {integrity: sha512-1YwTFdPjhPNHny/DrOHO+s8oVGGIE5Jib61/KnnjPRNWQhVVimrJJdaAX3e6nNRRDXrY5zbb9cfm2+yVvgsrqw==} resolution: {integrity: sha512-JHw/Knt4kOTSwQ0oqorbdgzukK6iE73U3MPUyOuCEBpAQGAzm80CQDwyaXMwF80yFjY21RY9qfzkoLyPFFts/w==}
engines: {node: '>=18'} engines: {node: '>=22'}
peerDependencies: peerDependencies:
ai: ^7.0.0
zod: ^4.0.16 zod: ^4.0.16
on-exit-leak-free@2.1.2: on-exit-leak-free@2.1.2:
@ -9238,59 +9221,46 @@ snapshots:
dependencies: dependencies:
zod: 4.4.3 zod: 4.4.3
'@ai-sdk/anthropic@2.0.70(zod@4.2.1)': '@ai-sdk/anthropic@4.0.12(zod@4.2.1)':
dependencies: dependencies:
'@ai-sdk/provider': 2.0.1 '@ai-sdk/provider': 4.0.3
'@ai-sdk/provider-utils': 3.0.22(zod@4.2.1) '@ai-sdk/provider-utils': 5.0.7(zod@4.2.1)
zod: 4.2.1 zod: 4.2.1
'@ai-sdk/gateway@2.0.24(zod@4.2.1)': '@ai-sdk/gateway@4.0.16(zod@4.2.1)':
dependencies: dependencies:
'@ai-sdk/provider': 2.0.1 '@ai-sdk/provider': 4.0.3
'@ai-sdk/provider-utils': 3.0.20(zod@4.2.1) '@ai-sdk/provider-utils': 5.0.7(zod@4.2.1)
'@vercel/oidc': 3.0.5 '@vercel/oidc': 3.2.0
zod: 4.2.1 zod: 4.2.1
'@ai-sdk/gateway@2.0.56(zod@4.2.1)': '@ai-sdk/google@4.0.12(zod@4.2.1)':
dependencies: dependencies:
'@ai-sdk/provider': 2.0.1 '@ai-sdk/provider': 4.0.3
'@ai-sdk/provider-utils': 3.0.22(zod@4.2.1) '@ai-sdk/provider-utils': 5.0.7(zod@4.2.1)
'@vercel/oidc': 3.1.0
zod: 4.2.1 zod: 4.2.1
'@ai-sdk/google@2.0.61(zod@4.2.1)': '@ai-sdk/openai-compatible@3.0.7(zod@4.2.1)':
dependencies: dependencies:
'@ai-sdk/provider': 2.0.1 '@ai-sdk/provider': 4.0.3
'@ai-sdk/provider-utils': 3.0.22(zod@4.2.1) '@ai-sdk/provider-utils': 5.0.7(zod@4.2.1)
zod: 4.2.1 zod: 4.2.1
'@ai-sdk/openai-compatible@1.0.34(zod@4.2.1)': '@ai-sdk/openai@4.0.11(zod@4.2.1)':
dependencies: dependencies:
'@ai-sdk/provider': 2.0.1 '@ai-sdk/provider': 4.0.3
'@ai-sdk/provider-utils': 3.0.22(zod@4.2.1) '@ai-sdk/provider-utils': 5.0.7(zod@4.2.1)
zod: 4.2.1 zod: 4.2.1
'@ai-sdk/openai@2.0.99(zod@4.2.1)': '@ai-sdk/provider-utils@5.0.7(zod@4.2.1)':
dependencies: dependencies:
'@ai-sdk/provider': 2.0.1 '@ai-sdk/provider': 4.0.3
'@ai-sdk/provider-utils': 3.0.22(zod@4.2.1)
zod: 4.2.1
'@ai-sdk/provider-utils@3.0.20(zod@4.2.1)':
dependencies:
'@ai-sdk/provider': 2.0.1
'@standard-schema/spec': 1.1.0 '@standard-schema/spec': 1.1.0
eventsource-parser: 3.0.6 '@workflow/serde': 4.1.0
eventsource-parser: 3.1.0
zod: 4.2.1 zod: 4.2.1
'@ai-sdk/provider-utils@3.0.22(zod@4.2.1)': '@ai-sdk/provider@4.0.3':
dependencies:
'@ai-sdk/provider': 2.0.1
'@standard-schema/spec': 1.1.0
eventsource-parser: 3.0.6
zod: 4.2.1
'@ai-sdk/provider@2.0.1':
dependencies: dependencies:
json-schema: 0.4.0 json-schema: 0.4.0
@ -10319,14 +10289,14 @@ snapshots:
'@csstools/css-tokenizer@4.0.0': {} '@csstools/css-tokenizer@4.0.0': {}
'@eigenpal/docx-editor-agents@1.0.3(ai@5.0.117(zod@4.2.1))(react@19.2.3)': '@eigenpal/docx-editor-agents@1.0.3(ai@7.0.22(zod@4.2.1))(react@19.2.3)':
dependencies: dependencies:
docxtemplater: 3.68.7 docxtemplater: 3.68.7
jszip: 3.10.1 jszip: 3.10.1
pizzip: 3.2.0 pizzip: 3.2.0
xml-js: 1.6.11 xml-js: 1.6.11
optionalDependencies: optionalDependencies:
ai: 5.0.117(zod@4.2.1) ai: 7.0.22(zod@4.2.1)
react: 19.2.3 react: 19.2.3
'@eigenpal/docx-editor-core@1.0.3(prosemirror-commands@1.7.1)(prosemirror-dropcursor@1.8.2)(prosemirror-history@1.5.0)(prosemirror-keymap@1.2.3)(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-tables@1.8.5)(prosemirror-transform@1.12.0)(prosemirror-view@1.41.8)': '@eigenpal/docx-editor-core@1.0.3(prosemirror-commands@1.7.1)(prosemirror-dropcursor@1.8.2)(prosemirror-history@1.5.0)(prosemirror-keymap@1.2.3)(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-tables@1.8.5)(prosemirror-transform@1.12.0)(prosemirror-view@1.41.8)':
@ -10347,9 +10317,9 @@ snapshots:
'@eigenpal/docx-editor-i18n@1.0.3': {} '@eigenpal/docx-editor-i18n@1.0.3': {}
'@eigenpal/docx-editor-react@1.0.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(ai@5.0.117(zod@4.2.1))(prosemirror-commands@1.7.1)(prosemirror-dropcursor@1.8.2)(prosemirror-history@1.5.0)(prosemirror-keymap@1.2.3)(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-tables@1.8.5)(prosemirror-transform@1.12.0)(prosemirror-view@1.41.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': '@eigenpal/docx-editor-react@1.0.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(ai@7.0.22(zod@4.2.1))(prosemirror-commands@1.7.1)(prosemirror-dropcursor@1.8.2)(prosemirror-history@1.5.0)(prosemirror-keymap@1.2.3)(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-tables@1.8.5)(prosemirror-transform@1.12.0)(prosemirror-view@1.41.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
dependencies: dependencies:
'@eigenpal/docx-editor-agents': 1.0.3(ai@5.0.117(zod@4.2.1))(react@19.2.3) '@eigenpal/docx-editor-agents': 1.0.3(ai@7.0.22(zod@4.2.1))(react@19.2.3)
'@eigenpal/docx-editor-core': 1.0.3(prosemirror-commands@1.7.1)(prosemirror-dropcursor@1.8.2)(prosemirror-history@1.5.0)(prosemirror-keymap@1.2.3)(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-tables@1.8.5)(prosemirror-transform@1.12.0)(prosemirror-view@1.41.8) '@eigenpal/docx-editor-core': 1.0.3(prosemirror-commands@1.7.1)(prosemirror-dropcursor@1.8.2)(prosemirror-history@1.5.0)(prosemirror-keymap@1.2.3)(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-tables@1.8.5)(prosemirror-transform@1.12.0)(prosemirror-view@1.41.8)
'@eigenpal/docx-editor-i18n': 1.0.3 '@eigenpal/docx-editor-i18n': 1.0.3
'@radix-ui/react-select': 2.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@radix-ui/react-select': 2.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@ -11653,16 +11623,11 @@ snapshots:
'@openai/codex@0.142.5-win32-x64': '@openai/codex@0.142.5-win32-x64':
optional: true optional: true
'@openrouter/ai-sdk-provider@1.5.4(ai@5.0.151(zod@4.2.1))(zod@4.2.1)': '@openrouter/ai-sdk-provider@3.0.0(ai@7.0.22(zod@4.2.1))(zod@4.2.1)':
dependencies: dependencies:
'@openrouter/sdk': 0.1.27 ai: 7.0.22(zod@4.2.1)
ai: 5.0.151(zod@4.2.1)
zod: 4.2.1 zod: 4.2.1
'@openrouter/sdk@0.1.27':
dependencies:
zod: 4.4.3
'@opentelemetry/api-logs@0.208.0': '@opentelemetry/api-logs@0.208.0':
dependencies: dependencies:
'@opentelemetry/api': 1.9.0 '@opentelemetry/api': 1.9.0
@ -13932,9 +13897,7 @@ snapshots:
d3-selection: 3.0.0 d3-selection: 3.0.0
d3-transition: 3.0.1(d3-selection@3.0.0) d3-transition: 3.0.1(d3-selection@3.0.0)
'@vercel/oidc@3.0.5': {} '@vercel/oidc@3.2.0': {}
'@vercel/oidc@3.1.0': {}
'@vitejs/plugin-react@5.1.2(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))': '@vitejs/plugin-react@5.1.2(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))':
dependencies: dependencies:
@ -14075,6 +14038,8 @@ snapshots:
'@webassemblyjs/ast': 1.14.1 '@webassemblyjs/ast': 1.14.1
'@xtuc/long': 4.2.2 '@xtuc/long': 4.2.2
'@workflow/serde@4.1.0': {}
'@xmldom/xmldom@0.8.11': {} '@xmldom/xmldom@0.8.11': {}
'@xmldom/xmldom@0.9.10': {} '@xmldom/xmldom@0.9.10': {}
@ -14142,20 +14107,11 @@ snapshots:
clean-stack: 2.2.0 clean-stack: 2.2.0
indent-string: 4.0.0 indent-string: 4.0.0
ai@5.0.117(zod@4.2.1): ai@7.0.22(zod@4.2.1):
dependencies: dependencies:
'@ai-sdk/gateway': 2.0.24(zod@4.2.1) '@ai-sdk/gateway': 4.0.16(zod@4.2.1)
'@ai-sdk/provider': 2.0.1 '@ai-sdk/provider': 4.0.3
'@ai-sdk/provider-utils': 3.0.20(zod@4.2.1) '@ai-sdk/provider-utils': 5.0.7(zod@4.2.1)
'@opentelemetry/api': 1.9.0
zod: 4.2.1
ai@5.0.151(zod@4.2.1):
dependencies:
'@ai-sdk/gateway': 2.0.56(zod@4.2.1)
'@ai-sdk/provider': 2.0.1
'@ai-sdk/provider-utils': 3.0.22(zod@4.2.1)
'@opentelemetry/api': 1.9.0
zod: 4.2.1 zod: 4.2.1
ajv-formats@2.1.1(ajv@8.17.1): ajv-formats@2.1.1(ajv@8.17.1):
@ -15454,6 +15410,8 @@ snapshots:
eventsource-parser@3.0.6: {} eventsource-parser@3.0.6: {}
eventsource-parser@3.1.0: {}
eventsource@3.0.7: eventsource@3.0.7:
dependencies: dependencies:
eventsource-parser: 3.0.6 eventsource-parser: 3.0.6
@ -17544,10 +17502,11 @@ snapshots:
obug@2.1.1: {} obug@2.1.1: {}
ollama-ai-provider-v2@1.5.5(zod@4.2.1): ollama-ai-provider-v2@4.0.1(ai@7.0.22(zod@4.2.1))(zod@4.2.1):
dependencies: dependencies:
'@ai-sdk/provider': 2.0.1 '@ai-sdk/provider': 4.0.3
'@ai-sdk/provider-utils': 3.0.20(zod@4.2.1) '@ai-sdk/provider-utils': 5.0.7(zod@4.2.1)
ai: 7.0.22(zod@4.2.1)
zod: 4.2.1 zod: 4.2.1
on-exit-leak-free@2.1.2: {} on-exit-leak-free@2.1.2: {}