Skip to content

@genkit-ai/vercel-ai: peerDependenciesMeta lists only @ai-sdk/react, but GenkitChatTransport is binding-agnostic (Vue/Svelte/Angular) #5616

Description

@chrisraygill

Summary

@genkit-ai/vercel-ai declares @ai-sdk/react as its only UI binding peer (optional). GenkitChatTransport (from @genkit-ai/vercel-ai/client) implements the framework agnostic ChatTransport from the ai core package, so it works with any of the Vercel AI SDK UI bindings, not just React. The package metadata implies React only support and does not reflect that.

Current metadata

js/plugins/vercel-ai/package.json:

"peerDependencies": {
  "@ai-sdk/react": "^3.0.0",
  "ai": "^6.0.0",
  "genkit": "workspace:^"
},
"peerDependenciesMeta": {
  "@ai-sdk/react": {
    "optional": true
  }
}

Why it is binding agnostic

GenkitChatTransport imports its types from ai (core), not from @ai-sdk/react:

// js/plugins/vercel-ai/src/client.ts
import type { ChatTransport, UIMessage, UIMessageChunk } from 'ai';

@ai-sdk/react, @ai-sdk/vue, @ai-sdk/svelte, and @ai-sdk/angular all consume a ChatTransport, so the same GenkitChatTransport drives all of them.

Verification (Angular)

I confirmed the Angular binding end to end against a real genkit agent. An Angular app using @ai-sdk/angular's Chat:

import { Chat } from '@ai-sdk/angular';
import { GenkitChatTransport } from '@genkit-ai/vercel-ai/client';

const chat = new Chat({
  id: crypto.randomUUID(),
  transport: new GenkitChatTransport({ url: '/api/myAgent' }),
  onData: (part) => {
    if (part.type === 'data-custom') { /* agent custom state */ }
  },
});

drives the agent's /api/myAgent route and streams assistant text, tool calls (tool-<name> parts), and the agent's custom state (the transient data-custom part) with no server side changes. Versions used: @ai-sdk/angular 2.0.x, ai 6.0.x, @genkit-ai/vercel-ai 0.2.0-rc.0.

Suggested change

Either list the other bindings as optional peers so the metadata matches reality:

"peerDependenciesMeta": {
  "@ai-sdk/react":   { "optional": true },
  "@ai-sdk/vue":     { "optional": true },
  "@ai-sdk/svelte":  { "optional": true },
  "@ai-sdk/angular": { "optional": true }
}

(with matching entries in peerDependencies), or drop the React specific peer entirely, since the only hard requirement is ai, and state in the README that the transport works with any AI SDK UI binding. The README and any package level docs would benefit from naming Vue, Svelte, and Angular alongside React.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions