From b7ac7caab4a2a6f9b71840aa21c31c9a15ad51a8 Mon Sep 17 00:00:00 2001 From: DarkSky <25152247+darkskygit@users.noreply.github.com> Date: Wed, 29 Oct 2025 17:48:15 +0800 Subject: [PATCH] chore(server): improve transcript stability (#13821) ## Summary by CodeRabbit * **New Features** * Enhanced audio/video detection for MP4 files to better distinguish audio-only vs. video. * **Dependencies** * Added MP4 parsing dependency and updated AI provider libraries (Anthropic, Google, OpenAI, etc.). * **Bug Fixes** * Tightened authentication state validation for magic-link/OTP flows. * Stricter space-join validation to reject invalid client types/versions. * Improved transcript entry deduplication and data handling. * **API** * Transcript submit payload now requires infos and removes deprecated url/mimeType fields. --- Cargo.lock | 42 +++++ Cargo.toml | 1 + packages/backend/native/Cargo.toml | 1 + packages/backend/native/src/file_type.rs | 31 +++- packages/backend/server/package.json | 14 +- .../server/src/core/auth/controller.ts | 12 +- .../backend/server/src/core/sync/gateway.ts | 14 +- .../copilot/providers/gemini/generative.ts | 4 +- .../src/plugins/copilot/transcript/service.ts | 26 +-- .../src/plugins/copilot/transcript/types.ts | 6 +- yarn.lock | 151 +++++++++--------- 11 files changed, 176 insertions(+), 126 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4b8949e94b..3a57ff1b72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -163,6 +163,7 @@ dependencies = [ "file-format", "infer", "mimalloc", + "mp4parse", "napi", "napi-build", "napi-derive", @@ -574,6 +575,15 @@ dependencies = [ "serde", ] +[[package]] +name = "bitreader" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "886559b1e163d56c765bc3a985febb4eee8009f625244511d8ee3c432e08c066" +dependencies = [ + "cfg-if", +] + [[package]] name = "bitvec" version = "1.0.1" @@ -1483,6 +1493,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af9673d8203fcb076b19dfd17e38b3d4ae9f44959416ea532ce72415a6020365" +[[package]] +name = "fallible_collections" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a88c69768c0a15262df21899142bc6df9b9b823546d4b4b9a7bc2d6c448ec6fd" +dependencies = [ + "hashbrown 0.13.2", +] + [[package]] name = "fancy-regex" version = "0.13.0" @@ -1801,6 +1820,15 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -2494,6 +2522,20 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "mp4parse" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63a35203d3c6ce92d5251c77520acb2e57108c88728695aa883f70023624c570" +dependencies = [ + "bitreader", + "byteorder", + "fallible_collections", + "log", + "num-traits", + "static_assertions", +] + [[package]] name = "nanoid" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index 56dfa586ff..f457d0fc7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,7 @@ libc = "0.2" log = "0.4" loom = { version = "0.7", features = ["checkpoint"] } mimalloc = "0.1" +mp4parse = "0.17" nanoid = "0.4" napi = { version = "3.0.0-beta.3", features = ["async", "chrono_date", "error_anyhow", "napi9", "serde"] } napi-build = { version = "2" } diff --git a/packages/backend/native/Cargo.toml b/packages/backend/native/Cargo.toml index 77ff7bdb5e..b0eb4d03f2 100644 --- a/packages/backend/native/Cargo.toml +++ b/packages/backend/native/Cargo.toml @@ -11,6 +11,7 @@ affine_common = { workspace = true, features = ["doc-loader"] } chrono = { workspace = true } file-format = { workspace = true } infer = { workspace = true } +mp4parse = { workspace = true } napi = { workspace = true, features = ["async"] } napi-derive = { workspace = true } rand = { workspace = true } diff --git a/packages/backend/native/src/file_type.rs b/packages/backend/native/src/file_type.rs index 9bd3d688ed..2aeecf9c55 100644 --- a/packages/backend/native/src/file_type.rs +++ b/packages/backend/native/src/file_type.rs @@ -1,12 +1,41 @@ +use mp4parse::{read_mp4, TrackType}; use napi_derive::napi; #[napi] pub fn get_mime(input: &[u8]) -> String { - if let Some(kind) = infer::get(&input[..4096.min(input.len())]) { + let mimetype = if let Some(kind) = infer::get(&input[..4096.min(input.len())]) { kind.mime_type().to_string() } else { file_format::FileFormat::from_bytes(input) .media_type() .to_string() + }; + if mimetype == "video/mp4" { + detect_mp4_flavor(input) + } else { + mimetype + } +} + +fn detect_mp4_flavor(input: &[u8]) -> String { + let mut cursor = std::io::Cursor::new(input); + match read_mp4(&mut cursor) { + Ok(ctx) => { + let mut has_video = false; + let mut has_audio = false; + for track in ctx.tracks.iter() { + match track.track_type { + TrackType::Video | TrackType::AuxiliaryVideo | TrackType::Picture => has_video = true, + TrackType::Audio => has_audio = true, + _ => {} + } + } + if !has_video && has_audio { + "audio/m4a".to_string() + } else { + "video/mp4".to_string() + } + } + Err(_) => "video/mp4".to_string(), } } diff --git a/packages/backend/server/package.json b/packages/backend/server/package.json index 86d4f1efe2..ef83de997b 100644 --- a/packages/backend/server/package.json +++ b/packages/backend/server/package.json @@ -28,12 +28,12 @@ "dependencies": { "@affine/reader": "workspace:*", "@affine/server-native": "workspace:*", - "@ai-sdk/anthropic": "^2.0.1", - "@ai-sdk/google": "^2.0.4", - "@ai-sdk/google-vertex": "^3.0.5", - "@ai-sdk/openai": "^2.0.10", - "@ai-sdk/openai-compatible": "^1.0.5", - "@ai-sdk/perplexity": "^2.0.1", + "@ai-sdk/anthropic": "^2.0.38", + "@ai-sdk/google": "^2.0.24", + "@ai-sdk/google-vertex": "^3.0.54", + "@ai-sdk/openai": "^2.0.56", + "@ai-sdk/openai-compatible": "^1.0.23", + "@ai-sdk/perplexity": "^2.0.14", "@apollo/server": "^4.11.3", "@aws-sdk/client-s3": "^3.779.0", "@aws-sdk/s3-request-presigner": "^3.779.0", @@ -75,7 +75,7 @@ "@prisma/instrumentation": "^6.7.0", "@react-email/components": "0.0.38", "@socket.io/redis-adapter": "^8.3.0", - "ai": "^5.0.10", + "ai": "^5.0.81", "bullmq": "^5.40.2", "cookie-parser": "^1.4.7", "cross-env": "^7.0.3", diff --git a/packages/backend/server/src/core/auth/controller.ts b/packages/backend/server/src/core/auth/controller.ts index 809d0b3dc2..0df276c9ab 100644 --- a/packages/backend/server/src/core/auth/controller.ts +++ b/packages/backend/server/src/core/auth/controller.ts @@ -270,14 +270,12 @@ export class AuthController { validators.assertValidEmail(email); const cacheKey = OTP_CACHE_KEY(otp); - const cachedToken = await this.cache.get< - { token: string; clientNonce: string } | string - >(cacheKey); + const cachedToken = await this.cache.get<{ + token: string; + clientNonce: string; + }>(cacheKey); let token: string | undefined; - // TODO(@fengmk2): this is a temporary compatible with cache token is string value, should be removed in 0.22 - if (typeof cachedToken === 'string') { - token = cachedToken; - } else if (cachedToken) { + if (cachedToken && typeof cachedToken === 'object') { token = cachedToken.token; if (cachedToken.clientNonce && cachedToken.clientNonce !== clientNonce) { throw new InvalidAuthState(); diff --git a/packages/backend/server/src/core/sync/gateway.ts b/packages/backend/server/src/core/sync/gateway.ts index 99b4637cd9..9c15517c88 100644 --- a/packages/backend/server/src/core/sync/gateway.ts +++ b/packages/backend/server/src/core/sync/gateway.ts @@ -194,14 +194,12 @@ export class SpaceSyncGateway @ConnectedSocket() client: Socket, @MessageBody() { spaceType, spaceId, clientVersion }: JoinSpaceMessage - ): Promise> { - // TODO(@forehalo): remove this after 0.19 goes out of life - // simple match 0.19.x - if (/^0.19.[\d]$/.test(clientVersion)) { - const room = Room(spaceId, 'sync-019'); - if (!client.rooms.has(room)) { - await client.join(room); - } + ): Promise> { + if ( + ![SpaceType.Userspace, SpaceType.Workspace].includes(spaceType) || + /^0.1/.test(clientVersion) + ) { + return { data: { clientId: client.id, success: false } }; } else { if (spaceType === SpaceType.Workspace) { this.event.emit('workspace.embedding', { workspaceId: spaceId }); diff --git a/packages/backend/server/src/plugins/copilot/providers/gemini/generative.ts b/packages/backend/server/src/plugins/copilot/providers/gemini/generative.ts index da8c8d3cff..66eb289528 100644 --- a/packages/backend/server/src/plugins/copilot/providers/gemini/generative.ts +++ b/packages/backend/server/src/plugins/copilot/providers/gemini/generative.ts @@ -112,9 +112,7 @@ export class GeminiGenerativeProvider extends GeminiProvider r.json()) - .then( - r => (console.log(JSON.stringify(r)), ModelListSchema.parse(r)) - ); + .then(r => ModelListSchema.parse(r)); this.onlineModelList = models.map(model => model.name.replace('models/', '') ); diff --git a/packages/backend/server/src/plugins/copilot/transcript/service.ts b/packages/backend/server/src/plugins/copilot/transcript/service.ts index 4b3c4c8f42..11fa30d905 100644 --- a/packages/backend/server/src/plugins/copilot/transcript/service.ts +++ b/packages/backend/server/src/plugins/copilot/transcript/service.ts @@ -171,11 +171,11 @@ export class CopilotTranscriptionService { if (payload.success) { let { url, mimeType, infos } = payload.data; infos = infos || []; - if (url && mimeType) { + if (url && mimeType && !infos.find(i => i.url === url)) { infos.push({ url, mimeType }); } - ret.infos = this.mergeInfos(infos, url, mimeType); + ret.infos = infos; if (job.status === AiJobStatus.claimed) { ret.transcription = payload.data; } @@ -239,22 +239,6 @@ export class CopilotTranscriptionService { } } - // TODO(@darkskygit): remove after old server down - private mergeInfos( - infos?: AudioBlobInfos | null, - url?: string | null, - mimeType?: string | null - ) { - if (url && mimeType) { - if (infos) { - infos.push({ url, mimeType }); - } else { - infos = [{ url, mimeType }]; - } - } - return infos || []; - } - private convertTime(time: number, offset = 0) { time = time + offset; const minutes = Math.floor(time / 60); @@ -298,14 +282,10 @@ export class CopilotTranscriptionService { jobId, infos, modelId, - // @deprecated - url, - mimeType, }: Jobs['copilot.transcript.submit']) { try { - const blobInfos = this.mergeInfos(infos, url, mimeType); const transcriptions = await Promise.all( - Array.from(blobInfos.entries()).map(([idx, { url, mimeType }]) => + Array.from(infos.entries()).map(([idx, { url, mimeType }]) => this.callTranscript(url, mimeType, idx * 10 * 60, modelId) ) ); diff --git a/packages/backend/server/src/plugins/copilot/transcript/types.ts b/packages/backend/server/src/plugins/copilot/transcript/types.ts index b8ef63f82a..084a73bae9 100644 --- a/packages/backend/server/src/plugins/copilot/transcript/types.ts +++ b/packages/backend/server/src/plugins/copilot/transcript/types.ts @@ -55,12 +55,8 @@ declare global { interface Jobs { 'copilot.transcript.submit': { jobId: string; - infos?: AudioBlobInfos; + infos: AudioBlobInfos; modelId?: string; - /// @deprecated use `infos` instead - url?: string; - /// @deprecated use `infos` instead - mimeType?: string; }; 'copilot.transcript.summary.submit': { jobId: string; diff --git a/yarn.lock b/yarn.lock index 3876eb9413..453fa87626 100644 --- a/yarn.lock +++ b/yarn.lock @@ -921,12 +921,12 @@ __metadata: "@affine/graphql": "workspace:*" "@affine/reader": "workspace:*" "@affine/server-native": "workspace:*" - "@ai-sdk/anthropic": "npm:^2.0.1" - "@ai-sdk/google": "npm:^2.0.4" - "@ai-sdk/google-vertex": "npm:^3.0.5" - "@ai-sdk/openai": "npm:^2.0.10" - "@ai-sdk/openai-compatible": "npm:^1.0.5" - "@ai-sdk/perplexity": "npm:^2.0.1" + "@ai-sdk/anthropic": "npm:^2.0.38" + "@ai-sdk/google": "npm:^2.0.24" + "@ai-sdk/google-vertex": "npm:^3.0.54" + "@ai-sdk/openai": "npm:^2.0.56" + "@ai-sdk/openai-compatible": "npm:^1.0.23" + "@ai-sdk/perplexity": "npm:^2.0.14" "@apollo/server": "npm:^4.11.3" "@aws-sdk/client-s3": "npm:^3.779.0" "@aws-sdk/s3-request-presigner": "npm:^3.779.0" @@ -988,7 +988,7 @@ __metadata: "@types/semver": "npm:^7.5.8" "@types/sinon": "npm:^17.0.3" "@types/supertest": "npm:^6.0.2" - ai: "npm:^5.0.10" + ai: "npm:^5.0.81" ava: "npm:^6.2.0" bullmq: "npm:^5.40.2" c8: "npm:^10.1.3" @@ -1092,104 +1092,104 @@ __metadata: languageName: unknown linkType: soft -"@ai-sdk/anthropic@npm:2.0.1, @ai-sdk/anthropic@npm:^2.0.1": - version: 2.0.1 - resolution: "@ai-sdk/anthropic@npm:2.0.1" +"@ai-sdk/anthropic@npm:2.0.38, @ai-sdk/anthropic@npm:^2.0.38": + version: 2.0.38 + resolution: "@ai-sdk/anthropic@npm:2.0.38" dependencies: "@ai-sdk/provider": "npm:2.0.0" - "@ai-sdk/provider-utils": "npm:3.0.1" + "@ai-sdk/provider-utils": "npm:3.0.13" peerDependencies: - zod: ^3.25.76 || ^4 - checksum: 10/aa6fc0be49775e061412c4644b11b33ccf07a983a1353a1960ed3a8dc4236586003f46080b2890ed345c9bdc00f55628719ad8b0246528d8a40e066638840b53 + zod: ^3.25.76 || ^4.1.8 + checksum: 10/6e3e7084dbb8470b3e2dd56541e7ad71b5784f18a3afe3e8ec079d7c337a94072b8da939af6d6c2f7a5458f5ab670d34057079881e0f67f9d2b5b1525e043641 languageName: node linkType: hard -"@ai-sdk/gateway@npm:1.0.4": - version: 1.0.4 - resolution: "@ai-sdk/gateway@npm:1.0.4" +"@ai-sdk/gateway@npm:2.0.2": + version: 2.0.2 + resolution: "@ai-sdk/gateway@npm:2.0.2" dependencies: "@ai-sdk/provider": "npm:2.0.0" - "@ai-sdk/provider-utils": "npm:3.0.1" + "@ai-sdk/provider-utils": "npm:3.0.13" + "@vercel/oidc": "npm:3.0.3" peerDependencies: - zod: ^3.25.76 || ^4 - checksum: 10/11b0322a619a922e74ae782ddff5577825f99b34f02889ffefc31652109a644110f6a4413caac047b8760635a880798e99d04a3bd042057013c772435dc4d172 + zod: ^3.25.76 || ^4.1.8 + checksum: 10/6f4058e26e275aaa59fc474f966604a1198863ad33a82570ac167dffd588dd21bb9ae476c2f9dc607374715a1d6840bcd9ff5e074961ee49cfef64eb44013bac languageName: node linkType: hard -"@ai-sdk/google-vertex@npm:^3.0.5": - version: 3.0.5 - resolution: "@ai-sdk/google-vertex@npm:3.0.5" +"@ai-sdk/google-vertex@npm:^3.0.54": + version: 3.0.54 + resolution: "@ai-sdk/google-vertex@npm:3.0.54" dependencies: - "@ai-sdk/anthropic": "npm:2.0.1" - "@ai-sdk/google": "npm:2.0.4" + "@ai-sdk/anthropic": "npm:2.0.38" + "@ai-sdk/google": "npm:2.0.24" "@ai-sdk/provider": "npm:2.0.0" - "@ai-sdk/provider-utils": "npm:3.0.1" + "@ai-sdk/provider-utils": "npm:3.0.13" google-auth-library: "npm:^9.15.0" peerDependencies: - zod: ^3.25.76 || ^4 - checksum: 10/8f6cdba400e9443548e07940b6f753964d29981a43ab95d2d13e96883bf638c94e3a9a3aba2ce9a59ae4a771ab7ec6f2dac17c3610817f6b2819fbe7d2c296c5 + zod: ^3.25.76 || ^4.1.8 + checksum: 10/a2198cddb24b09cc548fc36028189008b11fac19fa439938856a94197359fe3bf737faf6b64d1426b6c4f004b2113d9fb7af5458c52e925c81fd729ee7943387 languageName: node linkType: hard -"@ai-sdk/google@npm:2.0.4, @ai-sdk/google@npm:^2.0.4": - version: 2.0.4 - resolution: "@ai-sdk/google@npm:2.0.4" +"@ai-sdk/google@npm:2.0.24, @ai-sdk/google@npm:^2.0.24": + version: 2.0.24 + resolution: "@ai-sdk/google@npm:2.0.24" dependencies: "@ai-sdk/provider": "npm:2.0.0" - "@ai-sdk/provider-utils": "npm:3.0.1" + "@ai-sdk/provider-utils": "npm:3.0.13" peerDependencies: - zod: ^3.25.76 || ^4 - checksum: 10/f8d778804cc7e6674aa4ff3931e2cecbc95fdd6484669dcb25398f6461cb033372de1c8b0667fa96604fbe59a8cf37b9d1461b66e6a995f82a6ecf3917d589f1 + zod: ^3.25.76 || ^4.1.8 + checksum: 10/37fffa5272af9b1a3d415546b6c73c1f24ef87f2ba16ede96f3c26c33ac33a824b9c7bdb5e10edcb9d59e37aba84465d0635570261b719a932e921dcd84c5e45 languageName: node linkType: hard -"@ai-sdk/openai-compatible@npm:^1.0.5": - version: 1.0.5 - resolution: "@ai-sdk/openai-compatible@npm:1.0.5" +"@ai-sdk/openai-compatible@npm:^1.0.23": + version: 1.0.23 + resolution: "@ai-sdk/openai-compatible@npm:1.0.23" dependencies: "@ai-sdk/provider": "npm:2.0.0" - "@ai-sdk/provider-utils": "npm:3.0.1" + "@ai-sdk/provider-utils": "npm:3.0.13" peerDependencies: - zod: ^3.25.76 || ^4 - checksum: 10/52437a335a64c3c9993aedad4e85cbfa7876fe073b3dfc543a7478d6d4f63ec5eba0b1c67de317732a70c682a1cbb903c36b2e623e25c15baf7450d677592fff + zod: ^3.25.76 || ^4.1.8 + checksum: 10/f5a1fdc1fb55b166bad38bfa2fe746162aaff2a6dbcf9e958ff21615421cb1694c53e6a743db9184faf84eb870cf2785c04f7aa95e324b9a0e60fdf383563c1f languageName: node linkType: hard -"@ai-sdk/openai@npm:^2.0.10": - version: 2.0.10 - resolution: "@ai-sdk/openai@npm:2.0.10" +"@ai-sdk/openai@npm:^2.0.56": + version: 2.0.56 + resolution: "@ai-sdk/openai@npm:2.0.56" dependencies: "@ai-sdk/provider": "npm:2.0.0" - "@ai-sdk/provider-utils": "npm:3.0.1" + "@ai-sdk/provider-utils": "npm:3.0.13" peerDependencies: - zod: ^3.25.76 || ^4 - checksum: 10/5e07f9ed0f9a5459c6c6c7cc89e4efd6656b0db065b03f2e6ccacac567d84aa11ddd301ee076f4e438ee8819a0eeead45acc2a6ade82877e8445c862af464aa2 + zod: ^3.25.76 || ^4.1.8 + checksum: 10/bd075ba597243a4cb8dd1ae53e10dfdcb3cb66647228c264a96ce407f5a6a3cb931967bd7e6ab9d22ea299ab82c45633db3bec717e9eed947afaa2e8c6daf714 languageName: node linkType: hard -"@ai-sdk/perplexity@npm:^2.0.1": - version: 2.0.1 - resolution: "@ai-sdk/perplexity@npm:2.0.1" +"@ai-sdk/perplexity@npm:^2.0.14": + version: 2.0.14 + resolution: "@ai-sdk/perplexity@npm:2.0.14" dependencies: "@ai-sdk/provider": "npm:2.0.0" - "@ai-sdk/provider-utils": "npm:3.0.1" + "@ai-sdk/provider-utils": "npm:3.0.13" peerDependencies: - zod: ^3.25.76 || ^4 - checksum: 10/7fe19ce52c8c7031d8f567d7c40c8b2c563838cd283baf4f2e278430d9dbddba0fa41184024d1818cb230143bdc1e5ec065d27dad240974bec16417d896482e2 + zod: ^3.25.76 || ^4.1.8 + checksum: 10/a3cddfa4fc6bda355e0783c8a735b0468fbc9ec54967d41a2d5c705ae295529d70b9c2143b882a4fc3986577a1404ae22c686522d4c002ff965180424bb08096 languageName: node linkType: hard -"@ai-sdk/provider-utils@npm:3.0.1": - version: 3.0.1 - resolution: "@ai-sdk/provider-utils@npm:3.0.1" +"@ai-sdk/provider-utils@npm:3.0.13": + version: 3.0.13 + resolution: "@ai-sdk/provider-utils@npm:3.0.13" dependencies: "@ai-sdk/provider": "npm:2.0.0" "@standard-schema/spec": "npm:^1.0.0" - eventsource-parser: "npm:^3.0.3" - zod-to-json-schema: "npm:^3.24.1" + eventsource-parser: "npm:^3.0.5" peerDependencies: - zod: ^3.25.76 || ^4 - checksum: 10/23f841ff876dcdd3a507acad82e50501784eaa5635364ecc63790c518748309ab5a6b9a18f605ae471778335258917e372de4ad8f45ee94ffa690b7d2ae7ea99 + zod: ^3.25.76 || ^4.1.8 + checksum: 10/9dfc26323d31e4e06d4a854cdadd0e2f5952f117d0fc298ad100c48c8b77ece769c8e53338e570cadac814454550896991b9105168624de86e7d7662edea3bf7 languageName: node linkType: hard @@ -16520,6 +16520,13 @@ __metadata: languageName: node linkType: hard +"@vercel/oidc@npm:3.0.3": + version: 3.0.3 + resolution: "@vercel/oidc@npm:3.0.3" + checksum: 10/2713aba666a8dd45c099f22936a25f1ab5cba357f41239fcec5ad1b65b57db2d47f322f136937c29428d8c0c9ec745aa25eafebed9fe45def94c5a4b75ca777f + languageName: node + linkType: hard + "@vitejs/plugin-react-swc@npm:^3.7.2": version: 3.9.0 resolution: "@vitejs/plugin-react-swc@npm:3.9.0" @@ -17181,17 +17188,17 @@ __metadata: languageName: node linkType: hard -"ai@npm:^5.0.10": - version: 5.0.10 - resolution: "ai@npm:5.0.10" +"ai@npm:^5.0.81": + version: 5.0.81 + resolution: "ai@npm:5.0.81" dependencies: - "@ai-sdk/gateway": "npm:1.0.4" + "@ai-sdk/gateway": "npm:2.0.2" "@ai-sdk/provider": "npm:2.0.0" - "@ai-sdk/provider-utils": "npm:3.0.1" + "@ai-sdk/provider-utils": "npm:3.0.13" "@opentelemetry/api": "npm:1.9.0" peerDependencies: - zod: ^3.25.76 || ^4 - checksum: 10/c424464f39cd9a875b7cbf1dac8046f9a8a164ac42f1cc25c0bb44597996656e9c2ab18bc518f8802ee3917624c666e26aa120ea8821282b7bd1cb8dc1eca518 + zod: ^3.25.76 || ^4.1.8 + checksum: 10/1b04184e6c35c0545ca988614cd6e67d748df86af474efc912348d89d7b79fcfad7bfbaec636fe5fafd0b0291b612175e18ba85e2800fd267b03ca3072c6702d languageName: node linkType: hard @@ -18544,9 +18551,9 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001579, caniuse-lite@npm:^1.0.30001702, caniuse-lite@npm:^1.0.30001716": - version: 1.0.30001717 - resolution: "caniuse-lite@npm:1.0.30001717" - checksum: 10/e47dfd8707ea305baa177f3d3d531df614f5a9ac6335363fc8f86f0be4caf79f5734f3f68b601fee4edd9d79f1e5ffc0931466bb894bf955ed6b1dd5a1c34b1d + version: 1.0.30001751 + resolution: "caniuse-lite@npm:1.0.30001751" + checksum: 10/608f7e1248b7023020382c7dbb0ef389693b3fc98193c3ccea2d44126306d6ac905a5061cf9e62bf640535a86e7a98e563b34c02f909296cfe228f41627a4dc7 languageName: node linkType: hard @@ -22187,10 +22194,10 @@ __metadata: languageName: node linkType: hard -"eventsource-parser@npm:^3.0.0, eventsource-parser@npm:^3.0.1, eventsource-parser@npm:^3.0.3": - version: 3.0.3 - resolution: "eventsource-parser@npm:3.0.3" - checksum: 10/b8f8e79333441ad0eb9299e3fa693ab506892ffc53f0cc1d23134090351cf2d71c8e405a2e879f6acfbd2e17f41d5a00dafba05ff25c82141fc07078ad992187 +"eventsource-parser@npm:^3.0.0, eventsource-parser@npm:^3.0.1, eventsource-parser@npm:^3.0.5": + version: 3.0.6 + resolution: "eventsource-parser@npm:3.0.6" + checksum: 10/febf7058b9c2168ecbb33e92711a1646e06bd1568f60b6eb6a01a8bf9f8fcd29cc8320d57247059cacf657a296280159f21306d2e3ff33309a9552b2ef889387 languageName: node linkType: hard