-
-
Notifications
You must be signed in to change notification settings - Fork 102
feat: Introduce OpenRouter adapter #123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
| Command | Status | Duration | Result |
|---|---|---|---|
nx affected --targets=test:sherif,test:knip,tes... |
❌ Failed | 11s | View ↗ |
nx run-many --targets=build --exclude=examples/** |
✅ Succeeded | 4s | View ↗ |
☁️ Nx Cloud last updated this comment at 2026-01-08 12:40:53 UTC
@tanstack/ai
@tanstack/ai-anthropic
@tanstack/ai-client
@tanstack/ai-devtools-core
@tanstack/ai-gemini
@tanstack/ai-grok
@tanstack/ai-ollama
@tanstack/ai-openai
@tanstack/ai-openrouter
@tanstack/ai-preact
@tanstack/ai-react
@tanstack/ai-react-ui
@tanstack/ai-solid
@tanstack/ai-solid-ui
@tanstack/ai-svelte
@tanstack/ai-vue
@tanstack/ai-vue-ui
@tanstack/preact-ai-devtools
@tanstack/react-ai-devtools
@tanstack/solid-ai-devtools
commit: |
|
would like to see this adapter for python 😄 |
Once the Typescript adapter is finalized and reviewed, I’ll definitely work on adding a Python version as well |
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the 📝 WalkthroughWalkthroughAdds a new OpenRouter TypeScript package (adapters, types, tool converters), unit + live tests, docs, build/config files, and new stream/schema utilities (toServerSentEventsResponse / toStreamResponse and Zod→JSONSchema conversion). Also introduces many unresolved documentation merge conflicts across docs. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Adapter as OpenRouterTextAdapter
participant API as OpenRouter API
participant Stream as SSE Stream
Client->>Adapter: chatStream(options, tools)
Adapter->>Adapter: mapTextOptionsToOpenRouter(), convertMessages(), convertTools()
Adapter->>API: POST /v1/chat/completions (stream: true, headers)
API-->>Stream: SSE chunks (delta / tool_call / done)
Stream->>Adapter: chunk
Adapter->>Adapter: parseSSE() → processChoice()
alt content delta
Adapter->>Client: yield StreamChunk(type: content, delta)
else tool call
Adapter->>Client: yield StreamChunk(type: tool_call, name, args)
else done
Adapter->>Client: yield StreamChunk(type: done, usage)
end
sequenceDiagram
participant Client
participant Summ as OpenRouterSummarizeAdapter
participant Text as OpenRouterTextAdapter
participant API as OpenRouter API
Client->>Summ: summarizeStream(text, style, focus)
Summ->>Summ: buildSummarizationPrompt()
Summ->>Text: chatStream(system_prompt + content)
Text->>API: POST (stream)
API-->>Text: SSE chunks
Text->>Summ: StreamChunk(s)
Summ->>Client: StreamChunk(s) (accumulate)
Summ->>Client: final SummarizationResult
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Hold off until adding changes, we have implemented huge breaking changes for adapters internally |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🧹 Nitpick comments (9)
packages/typescript/ai-openrouter/live-tests/package.json (1)
1-20: Nice separation for “live” tests; consider making env requirements explicit.These scripts likely require
OPENROUTER_API_KEY(and possibly other vars). Consider adding a short README inlive-tests/(or apretestscript) to fail fast with a clear error if env vars are missing.packages/typescript/ai-openrouter/src/tools/function-tool.ts (1)
13-26: Consider removing the redundant fallback.The
|| {}on Line 23 is redundant sincejsonSchemaalready defaults to{}on Line 16.Apply this diff:
return { type: 'function', function: { name: tool.name, description: tool.description, - parameters: jsonSchema || {}, + parameters: jsonSchema, }, }packages/typescript/ai-openrouter/live-tests/tool-test.ts (1)
7-16: Consider logging environment file errors.The empty catch block silently ignores all errors when reading
.env.local. While this allows the file to be optional, it could hide permission errors or other unexpected issues.Consider logging a debug message:
const envContent = readFileSync(join(__dirname, '.env.local'), 'utf-8') envContent.split('\n').forEach((line) => { const match = line.match(/^([^=]+)=(.*)$/) if (match) { process.env[match[1].trim()] = match[2].trim() } }) -} catch (e) {} +} catch (e) { + // .env.local is optional +}packages/typescript/ai-openrouter/live-tests/web-search-test.ts (1)
6-15: Consider adding a comment for the empty catch block.Similar to tool-test.ts, the empty catch block silently ignores errors. Consider adding a comment to clarify this is intentional.
} }) -} catch {} +} catch { + // .env.local is optional +}packages/typescript/ai-openrouter/live-tests/image-test.ts (1)
6-15: Consider adding a comment for the empty catch block.Consistent with other live tests, consider clarifying the intentional empty catch block.
} }) -} catch {} +} catch { + // .env.local is optional +}packages/typescript/ai-openrouter/src/openrouter-adapter.ts (3)
162-167: Consider usingdeclarefor type-only properties instead of@ts-ignore.The
@ts-ignorecomments suppress TypeScript errors for unassigned properties used only for type inference. Usingdeclaremodifier would be more idiomatic:- // @ts-ignore - We never assign this at runtime and it's only used for types - _modelProviderOptionsByName: OpenRouterChatModelProviderOptionsByName - // @ts-ignore - We never assign this at runtime and it's only used for types - _modelInputModalitiesByName?: OpenRouterModelInputModalitiesByName - // @ts-ignore - We never assign this at runtime and it's only used for types - _messageMetadataByModality?: OpenRouterMessageMetadataByModality + declare _modelProviderOptionsByName: OpenRouterChatModelProviderOptionsByName + declare _modelInputModalitiesByName?: OpenRouterModelInputModalitiesByName + declare _messageMetadataByModality?: OpenRouterMessageMetadataByModality
256-287: Consider adding abort signal support for consistency withchatStream.The
chatStreammethod supportsoptions.request?.signalfor request cancellation, butsummarizedoes not accept any abort mechanism. For long-running summarization requests, users may want the ability to cancel.
376-380: Silent JSON parse failure could hide malformed SSE data.The
catchblock silently continues when JSON parsing fails. While this provides resilience against malformed data, consider logging a warning in debug mode to help diagnose issues.packages/typescript/ai-openrouter/src/text/text-provider-options.ts (1)
309-321: Duplicatetool_choicedefinition.The
tool_choiceproperty is defined identically in bothOpenRouterBaseOptions(lines 245-254) andInternalTextProviderOptions(lines 312-321). SinceInternalTextProviderOptionsextendsExternalTextProviderOptions(which aliasesOpenRouterBaseOptions), this redefinition is redundant.Remove the duplicate definition:
tools?: Array<{ type: 'function' function: { name: string description?: string parameters: Record<string, unknown> } }> - /** - * Controls which (if any) tool the model should use. - */ - tool_choice?: - | 'none' - | 'auto' - | 'required' - | { - type: 'function' - function: { - name: string - } - } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (19)
docs/adapters/openrouter.md(1 hunks)docs/config.json(1 hunks)packages/typescript/ai-openrouter/README.md(2 hunks)packages/typescript/ai-openrouter/live-tests/image-test.ts(1 hunks)packages/typescript/ai-openrouter/live-tests/package.json(1 hunks)packages/typescript/ai-openrouter/live-tests/tool-test.ts(1 hunks)packages/typescript/ai-openrouter/live-tests/web-search-test.ts(1 hunks)packages/typescript/ai-openrouter/package.json(1 hunks)packages/typescript/ai-openrouter/src/index.ts(1 hunks)packages/typescript/ai-openrouter/src/message-types.ts(1 hunks)packages/typescript/ai-openrouter/src/model-meta.ts(1 hunks)packages/typescript/ai-openrouter/src/openrouter-adapter.ts(1 hunks)packages/typescript/ai-openrouter/src/text/text-provider-options.ts(1 hunks)packages/typescript/ai-openrouter/src/tools/function-tool.ts(1 hunks)packages/typescript/ai-openrouter/src/tools/index.ts(1 hunks)packages/typescript/ai-openrouter/src/tools/tool-converter.ts(1 hunks)packages/typescript/ai-openrouter/tests/openrouter-adapter.test.ts(1 hunks)packages/typescript/ai-openrouter/tsconfig.json(1 hunks)packages/typescript/ai-openrouter/vite.config.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (6)
packages/typescript/ai-openrouter/src/message-types.ts (1)
packages/typescript/ai-openrouter/src/index.ts (6)
OpenRouterTextMetadata(12-12)OpenRouterImageMetadata(13-13)OpenRouterAudioMetadata(14-14)OpenRouterVideoMetadata(15-15)OpenRouterDocumentMetadata(16-16)OpenRouterMessageMetadataByModality(17-17)
packages/typescript/ai-openrouter/src/text/text-provider-options.ts (1)
packages/typescript/ai-openrouter/src/index.ts (5)
WebPlugin(20-20)ProviderPreferences(21-21)ReasoningOptions(22-22)StreamOptions(23-23)ImageConfig(24-24)
packages/typescript/ai-openrouter/live-tests/image-test.ts (3)
packages/typescript/ai/src/stream/processor.ts (1)
process(390-413)packages/typescript/ai-openrouter/src/index.ts (1)
createOpenRouter(3-3)packages/typescript/ai-openrouter/src/openrouter-adapter.ts (1)
createOpenRouter(674-679)
packages/typescript/ai-openrouter/live-tests/tool-test.ts (3)
packages/typescript/ai/src/stream/processor.ts (1)
process(390-413)packages/typescript/ai-openrouter/src/index.ts (1)
createOpenRouter(3-3)packages/typescript/ai-openrouter/src/openrouter-adapter.ts (1)
createOpenRouter(674-679)
packages/typescript/ai-openrouter/src/openrouter-adapter.ts (4)
packages/typescript/ai-openrouter/src/text/text-provider-options.ts (2)
ExternalTextProviderOptions(271-271)InternalTextProviderOptions(273-322)packages/typescript/ai-openrouter/src/tools/tool-converter.ts (2)
OpenRouterTool(5-5)convertToolsToProviderFormat(7-11)packages/typescript/ai-openrouter/src/model-meta.ts (2)
OpenRouterChatModelProviderOptionsByName(5-7)OpenRouterModelInputModalitiesByName(9-11)packages/typescript/ai-openrouter/src/message-types.ts (2)
OpenRouterMessageMetadataByModality(13-19)OpenRouterImageMetadata(3-5)
packages/typescript/ai-openrouter/src/model-meta.ts (2)
packages/typescript/ai-openrouter/src/index.ts (2)
OpenRouterChatModelProviderOptionsByName(8-8)OpenRouterModelInputModalitiesByName(9-9)packages/typescript/ai-openrouter/src/text/text-provider-options.ts (1)
OpenRouterBaseOptions(110-269)
🪛 Biome (2.1.2)
packages/typescript/ai-openrouter/src/message-types.ts
[error] 1-1: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 7-7: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 9-9: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 11-11: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
🪛 markdownlint-cli2 (0.18.1)
packages/typescript/ai-openrouter/README.md
47-47: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
🔇 Additional comments (31)
docs/config.json (1)
97-120: Confirm docs route matches the OpenRouter doc page id/slug.
to: "adapters/openrouter"assumes the OpenRouter docs page resolves to that route, butdocs/adapters/openrouter.mdusesid: openrouter-adapter(which some doc systems treat as the slug). Please verify the link works in the built docs and align either thetoor the doc frontmatter id if needed.packages/typescript/ai-openrouter/README.md (1)
40-46: Copy update looks fine.docs/adapters/openrouter.md (1)
1-57: Doc slug/id vs sidebar route + model examples need verification.
- Frontmatter
id: openrouter-adaptermay not match the sidebar route (adapters/openrouter). If your doc system usesidas the slug, consider changing it toopenrouter(or update the sidebar).- The “Available Models” examples look like illustrative model names; please verify they’re valid on OpenRouter (or label them clearly as examples).
packages/typescript/ai-openrouter/vite.config.ts (1)
1-36: Looks reasonable; please verify JSON import works in your Node/Vite setup.
import packageJson from './package.json'can be sensitive to Node ESM + TS + tooling config (JSON modules / import assertions). Since this is config-time code, please confirmpnpm -C packages/typescript/ai-openrouter test:libworks in CI and locally.packages/typescript/ai-openrouter/tsconfig.json (1)
1-9: LGTM for a package-local tsconfig.packages/typescript/ai-openrouter/src/tools/index.ts (1)
1-5: LGTM!The barrel exports are clean and follow standard TypeScript module patterns.
packages/typescript/ai-openrouter/tests/openrouter-adapter.test.ts (7)
1-14: LGTM!Test setup and imports are well-structured.
16-35: LGTM!The SSE mock helper correctly simulates the streaming response format.
42-141: LGTM!Comprehensive test coverage for API payload mapping. The test validates all critical fields including provider-specific options like plugins.
143-223: LGTM!Excellent test for streaming behavior, validating incremental content delivery and usage reporting.
225-311: LGTM!Well-designed test for streaming tool calls with proper validation of incremental argument accumulation.
313-366: LGTM!Multimodal test properly validates the transformation of text and image content parts.
368-397: LGTM!Error handling test correctly validates error chunk generation on HTTP errors.
packages/typescript/ai-openrouter/src/tools/tool-converter.ts (1)
1-11: LGTM!Clean converter implementation with good semantic naming via the type alias.
packages/typescript/ai-openrouter/src/tools/function-tool.ts (1)
1-11: LGTM!The FunctionTool interface properly models the OpenRouter function tool format.
packages/typescript/ai-openrouter/src/model-meta.ts (1)
1-11: LGTM!The intentionally empty model array aligns with the PR's approach to avoid maintaining a static model list due to OpenRouter's frequent model additions. The type definitions provide good flexibility for model-specific configuration.
packages/typescript/ai-openrouter/live-tests/tool-test.ts (3)
18-70: LGTM!API key validation and tool definition are well-structured. The extensive argument validation in the execute function is appropriate for a test focused on verifying tool argument passing.
72-142: LGTM!The streaming and tool execution logic is well-implemented with proper error handling for JSON parsing and tool execution.
144-183: LGTM!Comprehensive test validation with clear success/failure criteria and helpful error messages.
packages/typescript/ai-openrouter/live-tests/web-search-test.ts (2)
17-77: LGTM!Clean implementation of web search plugin testing with proper chunk handling for content, done, and error types.
79-100: LGTM!Clear test validation with appropriate success/failure conditions.
packages/typescript/ai-openrouter/live-tests/image-test.ts (4)
17-32: LGTM!API key validation and image URL extraction helper are well-implemented.
34-131: LGTM!Comprehensive test for Gemini image generation with excellent result formatting and validation.
133-228: LGTM!Good coverage for Flux image generation. While there's some duplication with the Gemini test, this is acceptable for test code and improves readability.
230-265: LGTM!Excellent test orchestration with clear result aggregation and reporting.
packages/typescript/ai-openrouter/src/index.ts (1)
1-26: LGTM!The barrel export file is well-organized, correctly using
typefor type-only exports and grouping exports logically by their source modules. The public API surface is clean and appropriately scoped.packages/typescript/ai-openrouter/src/openrouter-adapter.ts (4)
201-203: Throwing inside async generator will be caught correctly.The
throwhere will be caught by the surroundingtry-catchblock (line 247), converting it to an error chunk. This is the expected behavior.
289-299: LGTM!Clear error message explaining the limitation and directing users to appropriate alternatives.
706-717: Environment detection logic is well-structured.The
getEnvironmentfunction properly handles both browser (with injectedwindow.env) and Node.js environments. The fallback chain is appropriate.
444-458: Tool call buffering skip-if-no-id logic is overly defensive but unlikely to cause data loss in practice.The OpenRouter API contract guarantees that
idandfunction.nameare typically present on the first chunk for each tool call;function.argumentsare delivered incrementally across subsequent chunks. The code skips a tool call delta if noidis present and no existing buffer exists (line 451), which means the first chunk must include anidto be buffered. Given the API contract, this edge case—where the first chunk lacks anid—should rarely or never occur. However, if it does happen, the subsequent chunks with theidwill fail to find an existing buffer entry, causing data loss. Consider either: (1) removing theidcheck and buffering bytc.indexalone, since the API guarantees id presence on first chunk anyway, or (2) adding a fallback to buffer incomplete tool calls and merge them when id arrives.packages/typescript/ai-openrouter/src/text/text-provider-options.ts (1)
1-108: Well-documented type definitions.The interfaces are comprehensively documented with JSDoc comments, including default values, value ranges, and links to OpenRouter documentation. This significantly improves developer experience.
| ```typescript | ||
| import { createOpenRouter, type OpenRouterConfig } from "@tanstack/ai-openrouter"; | ||
|
|
||
| const config: OpenRouterConfig = { | ||
| apiKey: process.env.OPENROUTER_API_KEY!, | ||
| baseURL: "https://openrouter.ai/api/v1", // Optional | ||
| httpReferer: "https://your-app.com", // Optional, for rankings | ||
| xTitle: "Your App Name", // Optional, for rankings | ||
| }; | ||
|
|
||
| const adapter = createOpenRouter(config.apiKey, config); | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find the createOpenRouter function definition and exports
find packages/typescript/ai-openrouter -name "*.ts" -o -name "*.tsx" | head -20Repository: TanStack/ai
Length of output: 809
🏁 Script executed:
#!/bin/bash
# Search for createOpenRouter function definition
rg -n "export.*createOpenRouter|function createOpenRouter" packages/typescript/ai-openrouter -A 5Repository: TanStack/ai
Length of output: 600
🏁 Script executed:
#!/bin/bash
# Search for createOpenRouter usage in the codebase
rg -n "createOpenRouter\(" --type=ts -B 2 -A 2 | head -100Repository: TanStack/ai
Length of output: 3031
Fix the createOpenRouter call in the example—remove apiKey from the config object.
The function signature is createOpenRouter(apiKey: string, config?: Omit<OpenRouterConfig, 'apiKey'>). The second parameter must exclude apiKey, so either:
- Pass config without
apiKey:createOpenRouter(config.apiKey, { baseURL: "...", httpReferer: "...", xTitle: "..." }) - Or simplify to:
createOpenRouter(process.env.OPENROUTER_API_KEY!, { baseURL: "...", httpReferer: "...", xTitle: "..." })
The current example passes the full config (with apiKey), which violates the type signature.
🤖 Prompt for AI Agents
In docs/adapters/openrouter.md around lines 31 to 42, the example calls
createOpenRouter with a config object that still contains apiKey which violates
the function signature; update the call to pass the API key as the first
argument and pass a config object that omits apiKey (e.g. call
createOpenRouter(process.env.OPENROUTER_API_KEY!, { baseURL: "...", httpReferer:
"...", xTitle: "..." }) or extract apiKey then call
createOpenRouter(config.apiKey, { baseURL: "...", httpReferer: "...", xTitle:
"..." })).
| ## Bonus: TanStack Start Integration | ||
|
|
||
| TanStack AI works with **any** framework (Next.js, Express, Remix, etc.). | ||
|
|
||
| **With TanStack Start**, you get a bonus: share implementations between AI tools and server functions with `createServerFnTool`: | ||
|
|
||
| ```typescript | ||
| import { createServerFnTool } from '@tanstack/ai-react' | ||
|
|
||
| // Define once, get AI tool AND server function (TanStack Start only) | ||
| const getProducts = createServerFnTool({ | ||
| name: 'getProducts', | ||
| inputSchema: z.object({ query: z.string() }), | ||
| execute: async ({ query }) => db.products.search(query), | ||
| }) | ||
|
|
||
| // Use in AI chat | ||
| chat({ tools: [getProducts.server] }) | ||
|
|
||
| // Call directly from components (no API endpoint needed!) | ||
| const products = await getProducts.serverFn({ query: 'laptop' }) | ||
| ``` | ||
|
|
||
| No duplicate logic, full type safety, automatic validation. The `serverFn` feature requires TanStack Start. See [docs](https://tanstack.com/ai) for details. | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix markdown heading level + code sample missing z import.
- Markdownlint is right: after
# TanStack AI, the next heading level should be##(or drop the heading styling for the “Read the docs” line). - The snippet uses
z.object(...)but doesn’t importz.
-### <a href="https://tanstack.com/ai">Read the docs →</b></a>
+## <a href="https://tanstack.com/ai">Read the docs →</b></a>
@@
```typescript
import { createServerFnTool } from '@tanstack/ai-react'
+import { z } from 'zod'🤖 Prompt for AI Agents
In packages/typescript/ai-openrouter/README.md around lines 49 to 73, adjust the
markdown heading to ensure it is a second-level heading (##) immediately after
the top-level "# TanStack AI" header (or remove heading styling for the “Read
the docs” line) and update the code example to include the missing zod import by
adding an import for z (import { z } from 'zod') alongside the existing
createServerFnTool import so the z.object usage resolves.
| export interface OpenRouterTextMetadata {} | ||
|
|
||
| export interface OpenRouterImageMetadata { | ||
| detail?: 'auto' | 'low' | 'high' | ||
| } | ||
|
|
||
| export interface OpenRouterAudioMetadata {} | ||
|
|
||
| export interface OpenRouterVideoMetadata {} | ||
|
|
||
| export interface OpenRouterDocumentMetadata {} | ||
|
|
||
| export interface OpenRouterMessageMetadataByModality { | ||
| text: OpenRouterTextMetadata | ||
| image: OpenRouterImageMetadata | ||
| audio: OpenRouterAudioMetadata | ||
| video: OpenRouterVideoMetadata | ||
| document: OpenRouterDocumentMetadata | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Biome “noEmptyInterface” errors: replace empty interfaces with type aliases.
These empty interfaces will fail Biome as configured. Suggested minimal change:
-export interface OpenRouterTextMetadata {}
+export type OpenRouterTextMetadata = Record<string, never>
@@
-export interface OpenRouterAudioMetadata {}
+export type OpenRouterAudioMetadata = Record<string, never>
@@
-export interface OpenRouterVideoMetadata {}
+export type OpenRouterVideoMetadata = Record<string, never>
@@
-export interface OpenRouterDocumentMetadata {}
+export type OpenRouterDocumentMetadata = Record<string, never>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export interface OpenRouterTextMetadata {} | |
| export interface OpenRouterImageMetadata { | |
| detail?: 'auto' | 'low' | 'high' | |
| } | |
| export interface OpenRouterAudioMetadata {} | |
| export interface OpenRouterVideoMetadata {} | |
| export interface OpenRouterDocumentMetadata {} | |
| export interface OpenRouterMessageMetadataByModality { | |
| text: OpenRouterTextMetadata | |
| image: OpenRouterImageMetadata | |
| audio: OpenRouterAudioMetadata | |
| video: OpenRouterVideoMetadata | |
| document: OpenRouterDocumentMetadata | |
| } | |
| export type OpenRouterTextMetadata = Record<string, never> | |
| export interface OpenRouterImageMetadata { | |
| detail?: 'auto' | 'low' | 'high' | |
| } | |
| export type OpenRouterAudioMetadata = Record<string, never> | |
| export type OpenRouterVideoMetadata = Record<string, never> | |
| export type OpenRouterDocumentMetadata = Record<string, never> | |
| export interface OpenRouterMessageMetadataByModality { | |
| text: OpenRouterTextMetadata | |
| image: OpenRouterImageMetadata | |
| audio: OpenRouterAudioMetadata | |
| video: OpenRouterVideoMetadata | |
| document: OpenRouterDocumentMetadata | |
| } |
🧰 Tools
🪛 Biome (2.1.2)
[error] 1-1: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 7-7: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 9-9: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 11-11: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
🤖 Prompt for AI Agents
In packages/typescript/ai-openrouter/src/message-types.ts lines 1-19, Biome's
noEmptyInterface linting fails because several interfaces are empty; replace
each empty interface with a type alias (e.g., `type OpenRouterTextMetadata =
Record<string, never>` and similarly for audio, video, document) and update
OpenRouterMessageMetadataByModality to reference those type aliases instead of
interfaces; keep OpenRouterImageMetadata as an interface (or convert to a type
if you prefer) and preserve the optional `detail` union.
| private mapOptions(options: ChatOptions): OpenRouterRequest { | ||
| const providerOptions = options.providerOptions as | ||
| | Omit<InternalTextProviderOptions, 'model' | 'messages' | 'tools'> | ||
| | undefined | ||
|
|
||
| const request: OpenRouterRequest = { | ||
| model: options.model, | ||
| messages: this.convertMessages(options.messages), | ||
| temperature: options.options?.temperature, | ||
| max_tokens: options.options?.maxTokens, | ||
| top_p: options.options?.topP, | ||
| ...providerOptions, | ||
| tools: options.tools | ||
| ? convertToolsToProviderFormat(options.tools) | ||
| : undefined, | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spread operator may allow providerOptions to override critical fields.
The spread ...providerOptions (line 575) occurs after setting model, messages, temperature, etc., which means any matching keys in providerOptions would override those values. While InternalTextProviderOptions excludes model | messages | tools, the runtime type assertion doesn't enforce this.
Consider explicitly excluding known keys or validating the spread doesn't contain restricted properties:
+ const { model: _m, messages: _msg, tools: _t, ...safeProviderOptions } = providerOptions || {}
+
const request: OpenRouterRequest = {
model: options.model,
messages: this.convertMessages(options.messages),
temperature: options.options?.temperature,
max_tokens: options.options?.maxTokens,
top_p: options.options?.topP,
- ...providerOptions,
+ ...safeProviderOptions,🤖 Prompt for AI Agents
In packages/typescript/ai-openrouter/src/openrouter-adapter.ts around lines 564
to 579, the current spread of providerOptions into the request can accidentally
override critical fields (model, messages, tools, temperature, max_tokens,
top_p) at runtime; instead, filter or pick only allowed keys from
providerOptions before spreading (or explicitly delete/omit any of the
restricted keys if present) so that model/messages/tools and other request
fields set earlier cannot be overridden by providerOptions; implement a short
runtime whitelist/omit step (or validate and throw) and then merge the sanitized
providerOptions into the request.
| * Force the model to respond in a specific format. | ||
| */ | ||
| response_format?: { type: 'json_object' } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
OpenRouter API response_format documentation json_object json_schema
💡 Result:
Short summary — how OpenRouter's response_format works (json_object / json_schema)
- Parameter: response_format — a map you pass in the request to force structured outputs. [1][2].
- json_object: set response_format = { "type": "json_object" } to require the model to return any valid JSON object (useful when you only need valid JSON, not a specific schema). Also pair with an explicit system/user instruction to produce JSON. [1][3].
- json_schema (aka structured outputs): set response_format = { "type": "json_schema", "json_schema": { ... } } where json_schema contains name, schema (a JSON Schema object), and optional flags like strict. The model’s output will be validated against that schema; streaming support and model compatibility vary by provider/model. [2][4].
- Behavior/opts: some docs mention a structured_outputs boolean/flag and provider/model compatibility; not all models support response_format or both response_format and tools simultaneously — check the model’s supported parameters. [1][2][4].
- Example shape (conceptual):
{
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "weather",
"strict": true,
"schema": { "type":"object", "properties": { "location": {"type":"string"}, "temperature":{"type":"number"} }, "required":["location","temperature"] }
}
}
}
(Model returns JSON matching that schema). [2]
Sources
- OpenRouter API parameters / response_format description. [1]
- OpenRouter structured outputs (json_schema) docs and example. [2]
- OpenRouter API reference / compatibility notes. [4]
References:
[1] https://openrouter-api.yestool.org/docs/api-reference/parameters
[2] https://openrouter.ai/docs/features/structured-outputs
[4] https://openrouter.ai/docs/api-reference/overview
🏁 Script executed:
# Check the actual type definition in the file
cat -n packages/typescript/ai-openrouter/src/text/text-provider-options.ts | sed -n '180,190p'Repository: TanStack/ai
Length of output: 467
🌐 Web query:
OpenAI API response_format json_schema structured outputs types
💡 Result:
Summary — OpenAI Structured Outputs (response_format: json_schema)
-
What it is: a response_format option that lets you supply a JSON Schema (or SDK types like Pydantic/Zod) so the model returns JSON that adheres to that schema. Use when you want the assistant’s reply itself to be structured (not a function/tool call). [1][2]
-
How to enable (overview):
- In Responses/Chat APIs set text.format / response_format to type: "json_schema" and include your schema; set strict: true to require schema adherence. SDKs convert Pydantic/Zod to the supported schema automatically. Example usage shown in the OpenAI docs. [1][2][3]
-
Models that support it: supported on recent GPT‑4o models (examples: gpt-4o-mini, gpt-4o-2024-08-06 / gpt-4o-mini-2024-07-18) and the structured-outputs feature is available alongside function-calling for models that support tools. Check the docs for exact model availability for your account/region. [1][2]
-
Supported JSON Schema features/types (subset):
- Primitives: string, number, boolean, integer
- Composites: object, array
- Enum and anyOf
- additionalProperties, required, nested objects/arrays are supported as shown in examples. (Structured Outputs supports a subset of JSON Schema — consult docs for exact constraints.) [1]
-
Behavior & edge cases:
- With strict: true the model’s output will match the schema or return a refusal token if it refuses; otherwise you may get valid JSON that doesn’t match your schema (JSON mode vs Structured Outputs distinction). Handle refusals and interrupted outputs (finish_reason) in your app. [1][2]
References
[1] OpenAI — Structured model outputs (docs, supported schemas & examples).
[2] OpenAI — Introducing Structured Outputs in the API (blog/announcement, examples).
[3] OpenAI — Migrate to the Responses API (notes on text.format vs response_format).
Add support for json_schema and expand response_format type definition.
The response_format field currently only supports { type: 'json_object' }, but OpenRouter's API also supports { type: 'json_schema', json_schema: {...} } for structured outputs. Update the type to:
response_format?:
| { type: 'json_object' }
| { type: 'json_schema'; json_schema: { name: string; schema: Record<string, unknown>; strict?: boolean } }This allows users to leverage OpenRouter's structured output capabilities with schema validation.
🤖 Prompt for AI Agents
In packages/typescript/ai-openrouter/src/text/text-provider-options.ts around
lines 184 to 186, the response_format type only allows { type: 'json_object' }
but must also support OpenRouter's json_schema form; update the type to a union
that includes { type: 'json_object' } OR { type: 'json_schema'; json_schema: {
name: string; schema: Record<string, unknown>; strict?: boolean } } so callers
can provide schema name, the schema object, and optional strict flag for
structured outputs.
Alright, should I resolve the CodeRabbit suggestions now, or should I wait for that as well? |
|
Is this ready to be updated on the new adapter structure? |
|
@LuggaPugga it is, the BaseAdapter should be changed to BaseTextAdapter and if there are other supporting functionalities they should be split |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (4)
packages/typescript/ai-openrouter/src/adapters/text.ts (1)
410-415: Silent failure on malformed JSON chunks may hide API issues.When JSON parsing fails in the SSE stream, the error is silently swallowed. While this prevents crashes on malformed data, it could mask upstream API issues or protocol changes.
Consider logging or tracking parse failures for observability, at least in development mode.
🔎 Suggested improvement
} else { try { yield { done: false, data: JSON.parse(data) } } catch { - continue + // Consider adding debug logging here for observability + // console.debug('Failed to parse SSE chunk:', data) + continue } }packages/typescript/ai-openrouter/tests/openrouter-adapter.test.ts (1)
297-304: Missing type narrowing before accessingtoolCallproperty.At line 301-303, the code accesses
toolCallChunk.toolCallwithout proper type narrowing. While the filter on line 297 ensures onlytool_callchunks are selected, TypeScript may not infer this correctly.🔎 Suggested improvement for type safety
const toolCallChunks = chunks.filter((c) => c.type === 'tool_call') expect(toolCallChunks.length).toBe(1) const toolCallChunk = toolCallChunks[0] - expect(toolCallChunk.toolCall.function.name).toBe('lookup_weather') - expect(toolCallChunk.toolCall.function.arguments).toBe( - '{"location":"Berlin"}', - ) + if (toolCallChunk && toolCallChunk.type === 'tool_call') { + expect(toolCallChunk.toolCall.function.name).toBe('lookup_weather') + expect(toolCallChunk.toolCall.function.arguments).toBe( + '{"location":"Berlin"}', + ) + }packages/typescript/ai-openrouter/live-tests/web-search-test.ts (1)
7-15: Consider using a library for.envparsing.The manual
.env.localparsing is functional but fragile. It doesn't handle edge cases like quoted values, multiline values, or comments properly.For live tests, this is acceptable, but consider using
dotenvif more robust parsing is needed.packages/typescript/ai-openrouter/src/adapters/summarize.ts (1)
117-136: Code duplication:getEnvironmentand related interfaces are duplicated fromtext.ts.The
EnvObject,WindowWithEnvinterfaces andgetEnvironmentfunction are identical copies fromtext.ts. Consider extracting these to a shared utility module to reduce duplication and ensure consistency.🔎 Suggested refactor
Create a shared utility file:
// packages/typescript/ai-openrouter/src/utils/environment.ts export interface EnvObject { OPENROUTER_API_KEY?: string } interface WindowWithEnv { env?: EnvObject } export function getEnvironment(): EnvObject | undefined { if (typeof globalThis !== 'undefined') { const win = (globalThis as { window?: WindowWithEnv }).window if (win?.env) { return win.env } } if (typeof process !== 'undefined') { return process.env as EnvObject } return undefined }Then import from both adapter files.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (10)
docs/config.jsonpackages/typescript/ai-openrouter/live-tests/image-test.tspackages/typescript/ai-openrouter/live-tests/tool-test.tspackages/typescript/ai-openrouter/live-tests/web-search-test.tspackages/typescript/ai-openrouter/src/adapters/summarize.tspackages/typescript/ai-openrouter/src/adapters/text.tspackages/typescript/ai-openrouter/src/index.tspackages/typescript/ai-openrouter/src/text/text-provider-options.tspackages/typescript/ai-openrouter/src/tools/function-tool.tspackages/typescript/ai-openrouter/tests/openrouter-adapter.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/typescript/ai-openrouter/src/text/text-provider-options.ts
- packages/typescript/ai-openrouter/live-tests/tool-test.ts
- packages/typescript/ai-openrouter/live-tests/image-test.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Use tree-shakeable adapter architecture for provider implementations - export specialized adapters (text, embedding, summarize, image) as separate imports from/adapterssubpath rather than monolithic adapters
Use Zod for runtime schema validation and type inference, particularly for tool input/output definitions withtoolDefinition()and Zod schema inference
Implement isomorphic tool system usingtoolDefinition()with.server()and.client()implementations for dual-environment execution
Use type-safe per-model configuration with provider options typed based on selected model to ensure compile-time safety
Implement stream processing with StreamProcessor for handling chunked responses and support partial JSON parsing for streaming AI responses
Files:
packages/typescript/ai-openrouter/live-tests/web-search-test.tspackages/typescript/ai-openrouter/src/tools/function-tool.tspackages/typescript/ai-openrouter/tests/openrouter-adapter.test.tspackages/typescript/ai-openrouter/src/adapters/summarize.tspackages/typescript/ai-openrouter/src/adapters/text.tspackages/typescript/ai-openrouter/src/index.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use camelCase for function and variable names throughout the codebase
Files:
packages/typescript/ai-openrouter/live-tests/web-search-test.tspackages/typescript/ai-openrouter/src/tools/function-tool.tspackages/typescript/ai-openrouter/tests/openrouter-adapter.test.tspackages/typescript/ai-openrouter/src/adapters/summarize.tspackages/typescript/ai-openrouter/src/adapters/text.tspackages/typescript/ai-openrouter/src/index.ts
**/*.test.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Write unit tests using Vitest alongside source files with
.test.tsnaming convention
Files:
packages/typescript/ai-openrouter/tests/openrouter-adapter.test.ts
packages/typescript/*/src/adapters/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Create individual adapter implementations for each provider capability (text, embed, summarize, image) with separate exports to enable tree-shaking
Files:
packages/typescript/ai-openrouter/src/adapters/summarize.tspackages/typescript/ai-openrouter/src/adapters/text.ts
packages/typescript/*/src/index.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Export tree-shakeable adapters with clear subpath exports in package.json (e.g.,
@tanstack/ai/adapters,@tanstack/ai-openai/adapters) to minimize bundle size
Files:
packages/typescript/ai-openrouter/src/index.ts
🧠 Learnings (10)
📓 Common learnings
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/adapters/*.ts : Create individual adapter implementations for each provider capability (text, embed, summarize, image) with separate exports to enable tree-shaking
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.test.ts : Write unit tests using Vitest alongside source files with `.test.ts` naming convention
Applied to files:
packages/typescript/ai-openrouter/live-tests/web-search-test.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Implement isomorphic tool system using `toolDefinition()` with `.server()` and `.client()` implementations for dual-environment execution
Applied to files:
packages/typescript/ai-openrouter/src/tools/function-tool.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Use Zod for runtime schema validation and type inference, particularly for tool input/output definitions with `toolDefinition()` and Zod schema inference
Applied to files:
packages/typescript/ai-openrouter/src/tools/function-tool.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/adapters/*.ts : Create individual adapter implementations for each provider capability (text, embed, summarize, image) with separate exports to enable tree-shaking
Applied to files:
packages/typescript/ai-openrouter/src/tools/function-tool.tspackages/typescript/ai-openrouter/tests/openrouter-adapter.test.tspackages/typescript/ai-openrouter/src/adapters/summarize.tspackages/typescript/ai-openrouter/src/adapters/text.tspackages/typescript/ai-openrouter/src/index.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Use tree-shakeable adapter architecture for provider implementations - export specialized adapters (text, embedding, summarize, image) as separate imports from `/adapters` subpath rather than monolithic adapters
Applied to files:
packages/typescript/ai-openrouter/tests/openrouter-adapter.test.tspackages/typescript/ai-openrouter/src/adapters/summarize.tspackages/typescript/ai-openrouter/src/adapters/text.tspackages/typescript/ai-openrouter/src/index.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Implement stream processing with StreamProcessor for handling chunked responses and support partial JSON parsing for streaming AI responses
Applied to files:
packages/typescript/ai-openrouter/tests/openrouter-adapter.test.tspackages/typescript/ai-openrouter/src/adapters/text.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/index.ts : Export tree-shakeable adapters with clear subpath exports in package.json (e.g., `tanstack/ai/adapters`, `tanstack/ai-openai/adapters`) to minimize bundle size
Applied to files:
packages/typescript/ai-openrouter/tests/openrouter-adapter.test.tspackages/typescript/ai-openrouter/src/adapters/summarize.tspackages/typescript/ai-openrouter/src/adapters/text.tspackages/typescript/ai-openrouter/src/index.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/model-meta.ts : Maintain model metadata files that define provider options and capabilities per model for per-model type safety
Applied to files:
packages/typescript/ai-openrouter/src/adapters/text.tspackages/typescript/ai-openrouter/src/index.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Use type-safe per-model configuration with provider options typed based on selected model to ensure compile-time safety
Applied to files:
packages/typescript/ai-openrouter/src/adapters/text.ts
🧬 Code graph analysis (4)
packages/typescript/ai-openrouter/live-tests/web-search-test.ts (2)
packages/typescript/ai-openrouter/src/adapters/text.ts (1)
createOpenRouterText(712-718)packages/typescript/ai-openrouter/src/index.ts (1)
createOpenRouterText(8-8)
packages/typescript/ai-openrouter/src/tools/function-tool.ts (4)
packages/typescript/ai-openrouter/src/index.ts (1)
FunctionTool(51-51)packages/typescript/ai-openrouter/src/tools/index.ts (2)
FunctionTool(4-4)convertFunctionToolToAdapterFormat(5-5)packages/python/tanstack-ai/src/tanstack_ai/tool_utils.py (1)
tool(12-65)packages/typescript/ai/src/types.ts (1)
JSONSchema(25-64)
packages/typescript/ai-openrouter/src/adapters/summarize.ts (3)
packages/typescript/ai-openrouter/src/index.ts (5)
OpenRouterSummarizeConfig(19-19)OpenRouterConfig(10-10)OpenRouterSummarizeAdapter(16-16)createOpenRouterSummarize(17-17)openrouterSummarize(18-18)packages/typescript/ai-openrouter/src/adapters/text.ts (1)
OpenRouterConfig(26-31)packages/typescript/ai/src/types.ts (1)
StreamChunk(740-748)
packages/typescript/ai-openrouter/src/adapters/text.ts (2)
packages/typescript/ai-openrouter/src/text/text-provider-options.ts (2)
ExternalTextProviderOptions(271-271)InternalTextProviderOptions(273-321)packages/typescript/ai/src/types.ts (2)
TextOptions(565-650)ContentPart(184-195)
🔇 Additional comments (9)
docs/config.json (1)
135-138: LGTM!The OpenRouter adapter is correctly added to the documentation navigation, maintaining proper alphabetical ordering within the Adapters section.
packages/typescript/ai-openrouter/src/adapters/text.ts (3)
699-710: Dead code:getEnvironmentfunction is defined but never used.The
getEnvironmentfunction and related interfaces (EnvObject,WindowWithEnv) at lines 691-710 are defined but never referenced in this file. TheopenrouterTextfactory function at line 724 callsgetEnvironment(), so this is actually used. Let me re-check.After re-reading:
getEnvironment()is called at line 724 in theopenrouterTextfunction. This is correct and not dead code.
265-334: LGTM!The
structuredOutputmethod correctly implements the tool-forcing pattern for structured JSON extraction with appropriate fallback parsing and clear error messages.
712-734: LGTM!The factory functions provide flexible API key handling with both explicit key and environment-based detection patterns. Error messaging is clear and actionable.
packages/typescript/ai-openrouter/tests/openrouter-adapter.test.ts (1)
1-393: LGTM! Comprehensive test coverage for the adapter.The test suite covers key scenarios including option mapping, streaming responses, tool calls, multimodal input, and error handling. The mock SSE helper is well-designed and tests properly clean up mocked resources.
Consider adding tests for
structuredOutputmethod and reasoning/thinking chunk handling in future iterations.packages/typescript/ai-openrouter/src/tools/function-tool.ts (1)
1-33: LGTM!Clean implementation of the tool format converter. The default schema fallback ensures tools without explicit input schemas still work correctly, and the interface aligns with the OpenRouter/OpenAI function calling specification.
packages/typescript/ai-openrouter/live-tests/web-search-test.ts (1)
24-101: LGTM!The live test provides good coverage of the web search plugin functionality with clear logging, proper error handling, and appropriate exit codes for CI integration.
packages/typescript/ai-openrouter/src/adapters/summarize.ts (1)
88-114: LGTM!The
buildSummarizationPromptmethod provides clear, contextual prompts based on style, focus areas, and length constraints.packages/typescript/ai-openrouter/src/index.ts (1)
1-51: LGTM! Well-organized tree-shakeable exports.The barrel file correctly separates exports by capability (text, summarize) and properly uses the
typekeyword for type-only exports, enabling optimal tree-shaking. This aligns with the coding guidelines for adapter architecture.
|
|
||
| const parts = this.convertContentParts(msg.content) | ||
| const role = msg.role === 'user' ? 'user' : 'assistant' | ||
| return { | ||
| role, | ||
| content: | ||
| parts.length === 1 && parts[0]?.type === 'text' | ||
| ? parts[0].text || '' | ||
| : parts, | ||
| name: msg.name, | ||
| } | ||
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
System messages in the messages array are incorrectly converted to assistant role.
If a ModelMessage with role: 'system' is passed in the messages array, it will be converted to an assistant message (line 632). While system prompts are typically passed via systemPrompts option, this could cause unexpected behavior if developers pass system messages directly in the messages array.
🔎 Suggested fix
const parts = this.convertContentParts(msg.content)
- const role = msg.role === 'user' ? 'user' : 'assistant'
+ const role = msg.role === 'system' ? 'system' : msg.role === 'user' ? 'user' : 'assistant'
return {
role,
content:
parts.length === 1 && parts[0]?.type === 'text'
? parts[0].text || ''
: parts,
name: msg.name,
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const parts = this.convertContentParts(msg.content) | |
| const role = msg.role === 'user' ? 'user' : 'assistant' | |
| return { | |
| role, | |
| content: | |
| parts.length === 1 && parts[0]?.type === 'text' | |
| ? parts[0].text || '' | |
| : parts, | |
| name: msg.name, | |
| } | |
| }) | |
| const parts = this.convertContentParts(msg.content) | |
| const role = msg.role === 'system' ? 'system' : msg.role === 'user' ? 'user' : 'assistant' | |
| return { | |
| role, | |
| content: | |
| parts.length === 1 && parts[0]?.type === 'text' | |
| ? parts[0].text || '' | |
| : parts, | |
| name: msg.name, | |
| } |
🤖 Prompt for AI Agents
In packages/typescript/ai-openrouter/src/adapters/text.ts around lines 630 to
641, the mapping forces any non-'user' role to 'assistant', which wrongly
converts 'system' messages to assistant; update the role mapping to preserve
'system' (and 'assistant') explicitly: set role to 'user' for 'user', to
'assistant' for 'assistant', to 'system' for 'system', and fall back to
'assistant' only for unknown values so system messages remain system messages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
packages/typescript/ai-openrouter/src/text/text-provider-options.ts (1)
184-186: Expandresponse_formatto supportjson_schemafor structured outputs.The current type only allows
{ type: 'json_object' }, but OpenRouter's API also supports{ type: 'json_schema', json_schema: {...} }for schema-validated structured outputs. This limitation prevents users from leveraging OpenRouter's full structured output capabilities.🔎 Expand type definition to include json_schema variant
/** * Force the model to respond in a specific format. */ - response_format?: { type: 'json_object' } + response_format?: + | { type: 'json_object' } + | { + type: 'json_schema' + json_schema: { + name: string + schema: Record<string, unknown> + strict?: boolean + } + }Note: This issue was previously flagged but remains unresolved.
🧹 Nitpick comments (1)
packages/typescript/ai-openrouter/src/text/text-provider-options.ts (1)
1-329: Consider Zod schemas for runtime validation and better developer experience.Currently, all types are defined as TypeScript interfaces, which provide compile-time safety but no runtime validation. Using Zod schemas would enable:
- Runtime validation of provider options to catch configuration errors early
- Type inference from schemas (single source of truth)
- Better error messages when invalid options are passed
- Consistency with coding guidelines that recommend Zod for schema validation
This is particularly valuable for complex nested structures like
ProviderPreferencesandOpenRouterBaseOptions.Example: Converting OpenRouterBaseOptions to Zod
import { z } from 'zod' export const openRouterBaseOptionsSchema = z.object({ stop: z.union([z.string(), z.array(z.string())]).optional(), stream: z.boolean().optional(), max_tokens: z.number().optional(), temperature: z.number().min(0).max(2).optional(), // ... additional fields }).strict() export type OpenRouterBaseOptions = z.infer<typeof openRouterBaseOptionsSchema>This approach provides both type safety and runtime validation.
Based on coding guidelines emphasizing Zod for schema validation and type inference.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/typescript/ai-openrouter/src/text/text-provider-options.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Use tree-shakeable adapter architecture for provider implementations - export specialized adapters (text, embedding, summarize, image) as separate imports from/adapterssubpath rather than monolithic adapters
Use Zod for runtime schema validation and type inference, particularly for tool input/output definitions withtoolDefinition()and Zod schema inference
Implement isomorphic tool system usingtoolDefinition()with.server()and.client()implementations for dual-environment execution
Use type-safe per-model configuration with provider options typed based on selected model to ensure compile-time safety
Implement stream processing with StreamProcessor for handling chunked responses and support partial JSON parsing for streaming AI responses
Files:
packages/typescript/ai-openrouter/src/text/text-provider-options.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use camelCase for function and variable names throughout the codebase
Files:
packages/typescript/ai-openrouter/src/text/text-provider-options.ts
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/adapters/*.ts : Create individual adapter implementations for each provider capability (text, embed, summarize, image) with separate exports to enable tree-shaking
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Use tree-shakeable adapter architecture for provider implementations - export specialized adapters (text, embedding, summarize, image) as separate imports from `/adapters` subpath rather than monolithic adapters
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/index.ts : Export tree-shakeable adapters with clear subpath exports in package.json (e.g., `tanstack/ai/adapters`, `tanstack/ai-openai/adapters`) to minimize bundle size
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Implement stream processing with StreamProcessor for handling chunked responses and support partial JSON parsing for streaming AI responses
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/adapters/*.ts : Create individual adapter implementations for each provider capability (text, embed, summarize, image) with separate exports to enable tree-shaking
Applied to files:
packages/typescript/ai-openrouter/src/text/text-provider-options.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to packages/typescript/*/src/model-meta.ts : Maintain model metadata files that define provider options and capabilities per model for per-model type safety
Applied to files:
packages/typescript/ai-openrouter/src/text/text-provider-options.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Use type-safe per-model configuration with provider options typed based on selected model to ensure compile-time safety
Applied to files:
packages/typescript/ai-openrouter/src/text/text-provider-options.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Use tree-shakeable adapter architecture for provider implementations - export specialized adapters (text, embedding, summarize, image) as separate imports from `/adapters` subpath rather than monolithic adapters
Applied to files:
packages/typescript/ai-openrouter/src/text/text-provider-options.ts
📚 Learning: 2025-12-13T17:09:09.794Z
Learnt from: CR
Repo: TanStack/ai PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T17:09:09.794Z
Learning: Applies to **/*.{ts,tsx} : Use Zod for runtime schema validation and type inference, particularly for tool input/output definitions with `toolDefinition()` and Zod schema inference
Applied to files:
packages/typescript/ai-openrouter/src/text/text-provider-options.ts
🔇 Additional comments (1)
packages/typescript/ai-openrouter/src/text/text-provider-options.ts (1)
282-301: Content type definitions properly support multimodal inputs.The message content types now correctly include
audio_url,video_url, anddocument_urlalongsidetextandimage_url, with their corresponding field definitions. This properly reflects the adapter's multimodal capabilities.Note: Previous review flagged this section for having too-narrow content types. This has been resolved.
832f7f4 to
53e6fb2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 100
Note
Due to the large number of review comments, Critical severity comments were prioritized as inline comments.
Fix all issues with AI Agents 🤖
In @docs/adapters/gemini.md:
- Around line 59-63: Remove the merge conflict markers and normalize the import
to use the incoming symbol; replace the conflict block containing chat,
toServerSentEventsResponse and toStreamResponse with a single clean import that
includes chat and toStreamResponse from "@tanstack/ai" (i.e., remove the
<<<<<<<, =======, >>>>>>> lines and ensure only import { chat, toStreamResponse
} from "@tanstack/ai"; remains).
In @docs/adapters/openai.md:
- Around line 59-63: Remove the unresolved merge conflict markers (<<<<<<<,
=======, >>>>>>>) in the import block and standardize the import to use
toStreamResponse from @tanstack/ai (e.g., import { chat, toStreamResponse }
...). Then update any usages of toServerSentEventsResponse (the example around
the previous line 74) to call toStreamResponse instead, ensuring all references
and examples consistently use chat and toStreamResponse.
In @docs/api/ai.md:
- Around line 166-170: There is a merge conflict in the import and usage of the
streaming helper: replace the old import and usage of toServerSentEventsResponse
with the new toStreamResponse (or vice versa if the new API differs), ensuring
the import line and the example call (where toServerSentEventsResponse(stream)
is used) both use the same symbol; update the example documentation text to
mention toStreamResponse and the expected stream parameter so the chat example
(chat and stream variable) matches the consolidated streaming helper API across
docs.
In @docs/guides/runtime-adapter-switching.md:
- Around line 104-108: The file contains unresolved merge markers and
inconsistent return choices between toServerSentEventsResponse and
toStreamResponse; pick one of these two (e.g., toStreamResponse) and replace
every conflicted return (the occurrences around
toServerSentEventsResponse/toStreamResponse, including the one passing {
abortController }) with the chosen function, remove all Git conflict markers
(<<<<<<<, =======, >>>>>>>) and ensure any imports or references for the chosen
symbol (toStreamResponse or toServerSentEventsResponse) are present and the
unused one is removed so the file is consistent across the three conflict
regions.
- Around line 16-20: Resolve the Git merge conflict in the import line by
removing the conflict markers and keeping the correct export name from
@tanstack/ai; replace the conflicting import so it imports the actual function
used in this file (either toServerSentEventsResponse or toStreamResponse)
alongside chat — based on the adapter split in PR #137 you should likely keep
toStreamResponse and remove toServerSentEventsResponse and the conflict markers,
ensuring any downstream usages in this file reference the retained symbol.
- Around line 66-70: Resolve the merge conflict by removing the conflict markers
and keeping a single consistent import statement that matches the other resolved
import (use the newer toStreamResponse variant): import { chat, maxIterations,
toStreamResponse } from '@tanstack/ai'; ensure you replace the conflicting line
that mentions toServerSentEventsResponse and verify the same change was applied
to the other identical conflict earlier so both imports are consistent.
In @docs/guides/streaming.md:
- Around line 33-37: Resolve the merge conflict by choosing a single streaming
adapter import and making usage consistent: replace the conflicting import block
so it imports chat and the streaming helper you decide to keep (either
toServerSentEventsResponse or toStreamResponse) and then update the usage at the
referenced call site (the occurrence currently calling
toServerSentEventsResponse on line 49) to match that chosen symbol; ensure only
one of toServerSentEventsResponse or toStreamResponse is imported and used
throughout the file so imports and usage are consistent with the streaming API
refactor.
In @docs/guides/tool-approval.md:
- Around line 60-64: Remove the Git conflict markers and pick the correct import
API (replace the conflicted import block with a single clean import); if you
adopt the incoming branch API, import toStreamResponse from "@tanstack/ai"
alongside chat and update the later usage by replacing
toServerSentEventsResponse(stream) with toStreamResponse(stream) so the import
and call sites (the import line and the call that currently uses
toServerSentEventsResponse) are consistent.
In @docs/protocol/sse-protocol.md:
- Around line 170-174: Resolve the Git conflict markers in the import block
(remove <<<<<<<, =======, >>>>>>>) and make the import consistent by using the
new API name: replace the import of toServerSentEventsResponse with
toStreamResponse alongside chat; then update all references in the document
(including the call site toServerSentEventsResponse(stream) and the descriptive
section titled "What `toServerSentEventsResponse()` does") to use
toStreamResponse and adjust wording if the behavior or parameters changed to
match the new API signature.
In @docs/reference/classes/ToolCallManager.md:
- Around line 8-12: The docs file has unresolved Git conflict markers around
multiple "Defined in" links pointing to tool-calls.ts with differing line
numbers; open the source (the TypeScript file that defines ToolCallManager /
tool call helpers) to confirm the correct line numbers, remove all conflict
markers (<<<<<<<, =======, >>>>>>>) in ToolCallManager.md, and update each
"Defined in:" link to the verified single correct line reference for the
symbol(s) (e.g., the ToolCallManager and related functions in tool-calls.ts) so
the file contains no merge markers and each link points to the authentic line
number.
- Around line 8-12: The markdown has merge conflict markers and setext-style
headings in ToolCallManager.md (around the conflict block referencing
activities/chat/tools/tool-calls.ts and at the other listed ranges) which
violate the linter; remove the conflict markers and replace the underlined
(setext) headings with atx-style headings (use leading # characters) for each
affected section (including the blocks at 54-58, 78-82, 141-145, 164-168,
194-198, 214-218) so all headings are consistent with markdownlint-cli2
expectations.
In @docs/reference/functions/chat.md:
- Around line 12-16: Remove the unresolved merge markers and fix the `Defined
in` anchor in docs/reference/functions/chat.md by verifying the actual
declaration location in activities/chat/index.ts (check the definition of the
exported Chat activity / function referenced) and update the link to the correct
line number (either :976 or :945) or, better, point to the symbol location
without a hard-coded line (e.g., link to the file or use a commit/anchor that
targets the function name) so the conflicting HEAD/Incoming lines are
eliminated.
In @docs/reference/functions/createChatOptions.md:
- Around line 12-16: Remove the leftover Git conflict markers in the "Defined
in" link inside createChatOptions.md and update the line number to match the
current source; replace the conflict block (the <<<<<<<, =======, >>>>>>> lines)
with a single "Defined in: [activities/chat/index.ts:135]" or the correct line
number that matches activities/chat/index.ts for the current codebase, ensuring
the link points to the actual definition of createChatOptions in
activities/chat/index.ts.
- Around line 25-39: Resolve the merge conflict markers in the TAdapter/TSchema
docs by removing the <<<<<<<, =======, and >>>>>>> lines and keeping a single,
correct declaration for each type parameter; specifically update the TAdapter
line to a single form (e.g., "TAdapter extends AnyTextAdapter" or "TAdapter
extends [`AnyTextAdapter`](../type-aliases/AnyTextAdapter.md)") and update the
TSchema block to a single, correct union (either "TSchema extends
[`SchemaInput`](../type-aliases/SchemaInput.md) | `undefined` = `undefined`" or
the Zod-based form using `ZodType`/`$ZodTypeInternals`), matching the actual
types used by the codebase, and remove all conflict markers so the file contains
only the chosen wording.
In @docs/reference/functions/createSpeechOptions.md:
- Around line 20-24: Remove the merge conflict markers and keep the HEAD variant
that uses a hyperlink to TTSAdapter instead of plain code; specifically restore
the documentation line so it links to the TTSAdapter interface while still
showing the generic type parameters string and object (i.e., the linked
TTSAdapter with the `<string, object>` generics), ensuring backticks/markdown
formatting is valid.
In @docs/reference/functions/createSummarizeOptions.md:
- Around line 20-24: Resolve the merge markers around the TAdapter doc by
removing the conflict tokens and keeping the documentation style consistent with
the rest of the file: use the linked reference form for the generic type, i.e.,
change the conflicted block to `TAdapter` *extends*
[`SummarizeAdapter`](../interfaces/SummarizeAdapter.md)\<`string`, `object`\>,
ensuring the reference link and generic parameters are intact and no merge
markers remain.
In @docs/reference/functions/createTranscriptionOptions.md:
- Around line 20-24: Remove the Git conflict markers (<<<<<<<, =======, >>>>>>>)
around the TAdapter type declaration and leave a single resolved line;
specifically update the declaration involving TAdapter and TranscriptionAdapter
so it contains a single, clean type reference (e.g., TAdapter extends
TranscriptionAdapter<`string`, `object`>) without any conflict markers or
duplicated variants.
In @docs/reference/functions/createVideoOptions.md:
- Around line 20-24: Remove the Git conflict markers and the duplicated lines
and render the TAdapter type parameter as a single, correct declaration:
"TAdapter extends VideoAdapter with generic parameters string and object", using
the linked documentation style for VideoAdapter (i.e., make VideoAdapter a
documentation link) and keep the generics as string and object; ensure only that
single resolved line remains (no conflict markers).
In @docs/reference/functions/generateImage.md:
- Around line 22-26: Resolve the Git conflict markers in generateImage.md by
removing the <<<<<<<, =======, and >>>>>>> lines and keep the link-style
declaration for the type constraint: replace the conflicting block with a single
line using the markdown link to ImageAdapter (i.e., `TAdapter` extends
[ImageAdapter](../interfaces/ImageAdapter.md)\<`string`, `object`, `any`,
`any`\>), ensuring no leftover conflict markers remain and formatting matches
surrounding docs.
In @docs/reference/functions/generateSpeech.md:
- Around line 22-26: Remove the unresolved git conflict markers and keep the
HEAD variant: replace the conflict block with the documentation line that states
TAdapter extends TTSAdapter using the markdown link (i.e., the version that
links to the TTSAdapter docs), ensuring the generic parameters `<string,
object>` remain; verify the final line reads the linked form (no conflict
markers remaining) so the docs build correctly.
In @docs/reference/functions/generateTranscription.md:
- Around line 22-26: The file has unresolved git conflict markers around the
TAdapter type parameter documentation; remove the conflict markers and choose
the canonical form for the repository (prefer the linked interface reference
`[TranscriptionAdapter](../interfaces/TranscriptionAdapter.md)<string,
object>`), replacing the inline alternative `TranscriptionAdapter<string,
object>` and ensure `TAdapter` is documented as extending that linked interface;
repeat the same resolution across all other docs with the same pattern so no
conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`) remain and the repo can
build.
In @docs/reference/functions/generateVideo.md:
- Around line 27-31: Remove the Git conflict markers (<<<<<<<, =======, >>>>>>>)
and resolve the TAdapter line to a single, consistent Markdown form; replace the
conflicted block with a single declaration that TAdapter extends VideoAdapter
with generics (use the linked interface name VideoAdapter pointing to
../interfaces/VideoAdapter.md and show the generic parameters as inline
code/string, e.g., VideoAdapter\<`string`, `object`\>) so the doc contains no
conflict markers and matches nearby docs formatting.
In @docs/reference/functions/getVideoJobStatus.md:
- Around line 32-36: Resolve the unresolved merge conflict in the TAdapter type
parameter by removing the git conflict markers and keeping the HEAD version:
replace the conflict block with the markdown-linked form `TAdapter` *extends*
[`VideoAdapter`](../interfaces/VideoAdapter.md)\<`string`, `object`\>, ensuring
the link to the VideoAdapter docs remains and no leftover <<<<<<<, =======, or
>>>>>>> markers remain in the file.
In @docs/reference/functions/summarize.md:
- Around line 22-26: There is an unresolved merge conflict in the TAdapter type
parameter; remove the conflict markers and replace the block with the HEAD
version that uses a proper markdown link to the SummarizeAdapter docs—i.e.,
ensure the declaration reads that TAdapter extends the linked SummarizeAdapter
with type args string and object (refer to the TAdapter token and
SummarizeAdapter symbol to find and fix the text).
In @docs/reference/functions/toolDefinition.md:
- Around line 12-16: Remove the unresolved git conflict markers (<<<<<<<,
=======, >>>>>>>) in the header block and replace the two conflicting "Defined
in:" lines with a single correct reference to the exported toolDefinition
function; update the documentation link so it points to the actual
toolDefinition export location (line 187) in
activities/chat/tools/tool-definition.ts and ensure the text references the
toolDefinition export name to avoid future ambiguity.
- Around line 12-16: Remove the merge conflict markers (<<<<<<<, =======,
>>>>>>>) from the "Defined in" line and convert the setext-style heading into an
ATX-style heading by prefixing it with a single "#" (e.g., "# Defined in: ...")
so the reference to tool-definition.ts (the tool-definition symbol) no longer
uses underline-style heading and the Markdown lint rule MD003 is satisfied; pick
the correct resolved URL/reference (the one from tool-definition.ts) and keep
just that single ATX heading line.
In @docs/reference/functions/toStreamResponse.md:
- Around line 39-51: The example POST handler calls toStreamResponse with three
arguments but the function accepts two, with abortController as an optional
property of the second parameter; update the call in the POST function to pass
the AbortController as part of the ResponseInit/options object (i.e., replace
the third-argument usage with passing { abortController } as the second argument
to toStreamResponse), and leave other code (chat, openaiText, messages)
unchanged; optionally consider replacing deprecated toStreamResponse with
toServerSentEventsStream if applicable.
In @docs/reference/index.md:
- Around line 36-39: Remove the git conflict markers and reconcile the API
reference so it matches the finalized adapter refactor: delete removed adapter
entries (e.g., ImageAdapter) and any stale type aliases, keep only the new
adapter names and unified type aliases that exist in code (e.g.,
SummarizeAdapter/TextAdapter vs the new split adapters,
TranscriptionAdapter/TTSAdapter/VideoAdapter as applicable, or consolidated
AnyTextAdapter/AnyAudioAdapter/AnyVideoAdapter), update all Markdown links to
point to the actual interface/type files, and resolve the function name conflict
by using the final exported name convertZodToJsonSchema (replace
convertSchemaToJsonSchema). Ensure all referenced symbols (ImageAdapter,
SummarizeAdapter, TextAdapter, TranscriptionAdapter, TTSAdapter, VideoAdapter,
Any*Adapter aliases, convertSchemaToJsonSchema/convertZodToJsonSchema) match the
codebase exports and remove leftover conflict markers.
In @docs/reference/interfaces/ApprovalRequestedStreamChunk.md:
- Around line 8-12: Remove all Git merge markers from
ApprovalRequestedStreamChunk.md and replace each conflicting "Defined in:
[types.ts:...]" reference with the exact line number where the corresponding
type is actually defined in types.ts: open the repository types.ts and locate
the declaration for each referenced symbol (e.g., the
ApprovalRequestedStreamChunk/type names shown in the file) and update each
"Defined in" URL to use that precise line number (apply the same fix for all 8
conflict blocks), then save so no conflict markers remain and all links
consistently point to the true locations.
In @docs/reference/interfaces/DefaultMessageMetadataByModality.md:
- Around line 8-12: The docs contain unresolved git merge conflict markers
propagated from the source type file; open the TypeScript source that defines
DefaultMessageMetadataByModality (the types.ts entry for that type), remove the
conflict markers (<<<<<<<, =======, >>>>>>>), reconcile the conflicting variants
into the correct unified definition, ensure no other conflict markers remain in
that file (and resolve similar conflicts at the other noted positions), then
regenerate the docs by running the project's doc generation command (pnpm
generate-docs) so the docs/reference/*.md files are rebuilt without conflict
annotations.
In @docs/reference/interfaces/DocumentPart.md:
- Around line 8-12: Remove all unresolved Git merge conflict markers (<<<<<<<,
=======, >>>>>>>) from DocumentPart.md and replace the incorrect reference at
the first conflict with the correct location; update the "Defined in" link to
point to types.ts:173 where DocumentPart is actually defined, then scan the rest
of the file (conflicts at the other markers reported) to resolve and remove any
remaining markers so the file is clean and references are consistent.
In @docs/reference/interfaces/DoneStreamChunk.md:
- Around line 8-12: Remove the Git conflict markers and update all seven
"Defined in" references in the docs files to point to the current locations in
types.ts (e.g., DoneStreamChunk is at line 708, BaseStreamChunk at line 675) —
either regenerate the docs from TypeDoc if available to ensure all anchors/line
numbers are correct, or manually replace each conflicting pair with the single
correct "Defined in: [types.ts:708]" (or the appropriate symbol's current line)
for the properties listed at lines 8-12, 26-30, 40-44, 58-62, 76-80, 94-98, and
112-116 so there are no <<<<<<< / ======= / >>>>>>> markers left.
In @docs/reference/interfaces/ErrorStreamChunk.md:
- Around line 8-12: This file contains unresolved Git merge conflict markers
(e.g., <<<<<<<, =======, >>>>>>>) in ErrorStreamChunk.md; rebase your branch
onto the latest adapter-structure changes, remove the conflict markers, and
reconcile the two versions by keeping the updated documentation that matches the
new adapter split (matching how other docs were resolved), then regenerate the
docs (or manually update the definitions referencing the types declaration) and
ensure the same fixes are applied to the other reported ranges (26-30, 52-56,
70-74, 88-92, 106-110).
In @docs/reference/interfaces/ImageGenerationOptions.md:
- Around line 8-12: Resolve the merge conflicts by choosing the post-refactor
line references (the cfa7844 offsets) for the ImageGenerationOptions interface
and its properties: set the "Defined in" reference for ImageGenerationOptions to
types.ts:787, for model to types.ts:791, for prompt to types.ts:793, for
numberOfImages to types.ts:795, for size to types.ts:797, and for modelOptions
to types.ts:799; update each conflicting "Defined in" block to use these cfa7844
line numbers and remove the conflict markers.
In @docs/reference/interfaces/ImagePart.md:
- Around line 8-12: The docs file contains unresolved Git conflict markers
around the ImagePart reference sections; remove all conflict markers (<<<<<<<,
=======, >>>>>>>) in the four affected blocks and replace the incorrect "Defined
in" links with the correct line references for the ImagePart interface (use line
numbers 137 for the interface and 138, 140, 142 for the type, source, metadata
properties) so every occurrence (the blocks at lines ~8–12, ~32–36, ~48–52,
~64–68) points to those updated line numbers and the file contains no merge
markers remaining.
- Line 8: Remove the leftover merge conflict markers and convert any
setext-style headings in ImagePart.md to ATX-style headings (prefix with one or
more '#' as appropriate) at the affected locations (around the previously
conflicted area and the other flagged spots near lines 32, 48, and 64); ensure
there are no underline-style headings or dangling "===" / "---" lines, and keep
heading levels consistent with surrounding docs.
In @docs/reference/interfaces/SummarizationResult.md:
- Around line 8-12: The documentation file SummarizationResult.md contains
unresolved merge conflict markers for five "Defined in" references (blocks
around lines 8–12, 22–26, 36–40, 50–54, 64–68); inspect the canonical types.ts
to determine the correct definition line(s) for the SummarizationResult type and
replace each conflict block with a single, consistent "Defined in:
[types.ts:NNN](...)" entry using the accurate line numbers (remove all conflict
markers <<<<<<<, =======, >>>>>>>), and ensure all five occurrences reference
the same validated line number from types.ts.
In @docs/reference/interfaces/TextCompletionChunk.md:
- Around line 8-12: The TextCompletionChunk.md contains unresolved Git conflict
markers; remove all conflict blocks and merge artifacts and update the "Defined
in" link to point to types.ts line 765 for the TextCompletionChunk interface,
and update the property links to lines 766–775 for id, model, content, role,
finishReason, and usage; ensure the final file references the single correct
definition (TextCompletionChunk) and properties without any conflict markers or
duplicate entries so the docs build cleanly.
In @docs/reference/interfaces/ThinkingPart.md:
- Around line 8-12: The file contains unresolved git conflict markers in the
"Defined in" lines for the ThinkingPart interface; remove the conflict markers
and update the three "Defined in" references so they point to the correct lines
in packages/typescript/ai/src/types.ts: set the interface definition "Defined
in" to line 282, the "type" property reference to line 283, and the "content"
property reference to line 284 (ensure no remaining <<<<<<<, =======, >>>>>>>
markers remain).
In @docs/reference/interfaces/ToolCallPart.md:
- Around line 8-12: Resolve the eight "Defined in" merge conflicts in
docs/reference/interfaces/ToolCallPart.md by removing the conflict markers and
replacing each conflicting link with a single verified reference to the current
source location (use types.ts:258 where ToolCallPart is actually defined);
ensure all 8 occurrences (lines groups around 8–12, 22–26, 56–60, 70–74, 84–88,
98–102, 114–118, 128–132) consistently point to [types.ts:258] and update the
URL to the correct blob/commit path if needed, then run a quick search for other
"Defined in" entries to confirm no remaining conflict markers.
- Around line 8-12: Resolve and remove the git conflict markers (<<<<<<<,
=======, >>>>>>>) in the "Defined in:" blocks, pick the correct target
link/version, and convert each setext-style "Defined in: [types.ts:...](...)"
heading to an atx-style heading by prefixing it with "# " (ensure you update all
occurrences noted: the current block and ranges 22-26, 56-60, 70-74, 84-88,
98-102, 114-118, 128-132), keeping the chosen link text intact and making the
heading style consistent with MD003.
In @docs/reference/interfaces/ToolCallStreamChunk.md:
- Around line 8-12: The docs file ToolCallStreamChunk.md contains unresolved git
conflict markers in the "Defined in" metadata (multiple blocks showing differing
line numbers like 676 vs 671) which must be removed; resolve by fixing the
underlying conflicts in the source types file (types.ts) for the related symbols
(e.g., ToolCallStreamChunk and other referenced types), then regenerate the
documentation (TypeDoc) so the "Defined in" line-number references are correct,
or if you must edit the generated doc manually remove all conflict markers and
pick the correct line numbers from the branch you intend to keep (cfa7844),
ensuring the final references match the current types.ts.
In @docs/reference/interfaces/ToolConfig.md:
- Around line 8-12: Remove the unresolved Git conflict markers around the
Defined in link in ToolConfig.md, keeping a single correct "Defined in" line;
update the URL reference so it points to types.ts at the correct line for the
ToolConfig interface (line 444) and ensure there are no leftover <<<<<<<,
=======, or >>>>>>> markers in the file; verify the link format remains
consistent with other docs entries and commit the cleaned file.
- Around line 6-9: Replace the setext-style heading for "Interface: ToolConfig"
with an ATX-style heading: change the underlined title into a single line
starting with the appropriate number of # (e.g., "# Interface: ToolConfig") and
remove the subsequent dash underline so the file complies with MD003; ensure the
rest of the file keeps ATX headings consistently and that the merge conflict
markers have been resolved.
In @docs/reference/interfaces/ToolDefinition.md:
- Around line 76-80: This file contains unresolved Git merge conflict markers in
ToolDefinition.md for several property blocks (including ranges 76-80, 105-109,
153-157, 215-219, 235-239, 264-268, 284-288); remove the conflict markers
(<<<<<<<, =======, >>>>>>>) and pick the correct "Defined in" reference for each
property by either regenerating the docs from the post-PR types.ts (which moved
symbols during adapter restructuring) or manually selecting the correct branch
variant, then update the "Defined in: types.ts:NNN" references to the accurate
line numbers or symbol locations and regenerate the documentation to ensure all
seven property definitions are consistent.
In @docs/reference/interfaces/ToolDefinitionInstance.md:
- Around line 52-56: Resolve the seven merge markers in
ToolDefinitionInstance.md by updating each "Defined in" reference for the
properties description, execute, inputSchema, metadata, name, needsApproval, and
outputSchema to the correct line numbers from the merged types.ts (use the
incoming branch locations introduced by the adapter-restructure PR if those
match the merged file), remove the conflict markers (<<<<<<<, =======, >>>>>>>),
and make all "Defined in" references consistent across the file (also update the
other ranges noted: 81-85, 129-133, 191-195, 211-215, 240-244, 260-264); after
editing, verify each referenced line number points to the actual type
declaration in the final merged types.ts and adjust numbers to match exactly.
In @docs/reference/interfaces/ToolInputAvailableStreamChunk.md:
- Around line 8-12: Resolve the unresolved merge conflicts in the source types
file by fixing the two conflict regions: choose and consolidate the correct
import for the schema type (pick either StandardJSONSchemaV1 or Zod and remove
the conflict markers around the imports) and reconcile the conflicting
outputSchema definition/documentation (ensure the
ToolInputAvailableStreamChunk-related outputSchema type and its JSDoc are
consistent and remove conflict markers). After cleaning those two regions so the
file compiles, run pnpm generate-docs to regenerate the docs and clear all
autogenerated conflict markers; do not manually edit generated docs.
In @docs/reference/interfaces/ToolResultPart.md:
- Around line 8-12: The file docs/reference/interfaces/ToolResultPart.md
contains six unresolved git merge conflicts showing alternate line references;
resolve them by removing all conflict markers and reconciling the competing
lines so the documentation consistently references the actual ToolResultPart
declaration (interface ToolResultPart) in packages/typescript/ai/src/types.ts at
its current location (now starting at line 274 with properties on lines
275-279), update every “Defined in:” and property line links to point to
types.ts:274–279, and ensure the final markdown is a single, clean definition
matching the ToolResultPart shape.
In @docs/reference/interfaces/TranscriptionOptions.md:
- Around line 8-12: Resolve the merge conflicts in
docs/reference/interfaces/TranscriptionOptions.md by removing all conflict
markers (<<<<<<<, =======, >>>>>>>) and ensure the "Defined in" references for
TranscriptionOptions and its properties point to the correct TypeScript source
line numbers: TranscriptionOptions at types.ts:966, model at types.ts:970, audio
at types.ts:972, language at types.ts:974, prompt at types.ts:976,
responseFormat at types.ts:978, and modelOptions at types.ts:980; update all
seven occurrences accordingly so the file no longer contains conflict markers
and all links reference the correct lines.
- Around line 8-12: The file contains unresolved git conflict markers (e.g.,
<<<<<<< HEAD and >>>>>>> cfa7844) inside setext-style heading regions for the
"Defined in:" references; remove all conflict markers and convert each affected
"Defined in:" reference to an atx-style heading (prefix with "# ") so lines like
"Defined in: [types.ts:953]..." become a single line heading starting with "#
Defined in: ..." and repeat this fix for the other occurrences mentioned (31-35,
47-51, 63-67, 79-83, 95-99, 111-115).
In @docs/reference/interfaces/TranscriptionSegment.md:
- Around line 8-12: Resolve the unresolved merge markers in the source types
file that generated TranscriptionSegment.md: open
packages/typescript/ai/src/types.ts, find the TranscriptionSegment type
definition around the conflicting region (near the previous line refs ~968–973)
and remove the <<<<<<<, =======, >>>>>>> blocks by selecting the correct variant
(or merging the changes) so the type has a single, consistent definition; save
and commit that fix, then regenerate docs by running the repository's
documentation script (e.g., npm/yarn run generate-docs) so
TranscriptionSegment.md is recreated without conflict markers.
In @docs/reference/interfaces/VideoJobResult.md:
- Around line 8-12: The file docs/reference/interfaces/VideoJobResult.md
contains unresolved merge conflict markers in the "Defined in" lines; remove the
conflict markers (<<<<<<<, =======, >>>>>>>) and update the three "Defined in"
references so they point to the current locations in
packages/typescript/ai/src/types.ts: use line 880 for the VideoJobResult
interface, line 882 for the jobId property, and line 884 for the model property;
ensure all three occurrences are cleaned up and formatted consistently with the
other docs entries.
In @docs/reference/interfaces/VideoUrlResult.md:
- Around line 8-12: Remove all git conflict markers from
docs/reference/interfaces/VideoUrlResult.md and update the "Defined in" source
references to the correct lines in types.ts: set the interface reference to line
908 and update the property references so jobId points to line 910, url to line
913, and expiresAt to line 916; ensure there are no remaining <<<<<<<, =======,
>>>>>>> blocks anywhere in the file and that each "Defined in:" link uses the
new types.ts line numbers.
In @docs/reference/type-aliases/AgentLoopStrategy.md:
- Around line 12-16: Resolve the merge conflict markers in the AgentLoopStrategy
doc by removing the HEAD/other-branch conflict lines and leaving a single
correct "Defined in" reference; replace the incorrect links pointing to
types.ts:560 or :600 with the correct link to types.ts:564 and ensure the line
reads "Defined in:
[types.ts:564](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/types.ts#L564)"
so the documentation points to the actual definition of AgentLoopStrategy.
In @docs/reference/type-aliases/ConstrainedContent.md:
- Around line 15-19: The file docs/reference/type-aliases/ConstrainedContent.md
contains unresolved merge conflict markers (<<<<<<<, =======, >>>>>>>) around
the "Defined in" source link; remove the conflict markers and replace the two
conflicting references with the single correct source link pointing to the
actual location of the ConstrainedContent type in the current types.ts (locate
the ConstrainedContent definition in types.ts and use that file:line URL), e.g.
update the "Defined in:" line to the one matching the current codebase and
remove any leftover conflict text so the markdown shows only the accurate
reference.
In @docs/reference/type-aliases/ConstrainedModelMessage.md:
- Around line 12-16: Remove the unresolved merge conflict markers and the two
incorrect references, and replace that entire conflict block with the correct
single reference for the ConstrainedModelMessage type: "Defined in:
[types.ts:313](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/types.ts#L313)";
ensure the final line mentions ConstrainedModelMessage so the symbol is clear
and no conflict markers (<<<<<<<, =======, >>>>>>>) remain.
In @docs/reference/type-aliases/ContentPartForInputModalitiesTypes.md:
- Around line 14-18: The markdown contains unresolved git conflict markers for
the "Defined in" link for ContentPartForInputModalitiesTypes; remove the
conflict markers (<<<<<<<, =======, >>>>>>>) and replace the two conflicting
references with a single correct reference pointing to types.ts line 205 (i.e.,
"Defined in: [types.ts:205](.../types.ts#L205)"); ensure the heading/name
ContentPartForInputModalitiesTypes remains intact and that no other conflict
remnants remain in the file.
In @docs/reference/type-aliases/InferSchemaType.md:
- Around line 12-16: Resolve the unresolved merge conflicts in both
docs/reference/type-aliases/InferSchemaType.md and the source types file by
removing the conflict markers and merging the correct changes; in the source
file (types.ts) find the InferSchemaType type export and finish resolving any
<<<<<<< / ======= / >>>>>>> sections so the file is clean, then update the
"Defined in" link in InferSchemaType.md to point to the actual exported location
of InferSchemaType in types.ts (use the final line number or a stable anchor if
available) so the documentation no longer references conflicting line numbers.
In @docs/reference/type-aliases/InputModalitiesTypes.md:
- Around line 12-16: The docs file
docs/reference/type-aliases/InputModalitiesTypes.md contains unresolved merge
conflict markers at the blocks around lines 12–16, 26–30, and 40–44 caused by PR
#137 changing adapter references and line numbers; do not edit the generated
file directly—instead resolve the underlying merge in the source (ensure
types.ts is merged so the type definition lines are stable around the actual
definition near lines ~304–306), then regenerate the docs by running the
documentation generator (invoke pnpm run generate-docs which runs
scripts/generate-docs.ts using @tanstack/typedoc-config) so the conflict markers
and incorrect type links are removed and the references to the correct types.ts
line numbers are updated.
In @docs/reference/type-aliases/MessagePart.md:
- Around line 16-20: Resolve the unresolved merge conflict in the MessagePart
docs by removing the conflict markers (<<<<<<<, =======, >>>>>>>) and accepting
the HEAD variant so the "Defined in" link points to types.ts:283 (the actual
MessagePart definition); update the file to only include the correct reference
for MessagePart and ensure no leftover conflict text remains.
In @docs/reference/type-aliases/ModalitiesArrayToUnion.md:
- Around line 12-16: This doc contains unresolved Git conflict markers around
the ModalitiesArrayToUnion reference; remove the conflict markers (<<<<<<<,
=======, >>>>>>>) and keep the HEAD variant that points to the correct JSDoc
location (the version referencing line 218), deleting the stale competing line
that points to line 269 so the file contains a single clean "Defined in: ..."
line for ModalitiesArrayToUnion.
In @docs/reference/type-aliases/Modality.md:
- Around line 12-16: Resolve the merge conflict markers in the "Defined in"
reference for the Modality type by removing the <<<<<<<, =======, and >>>>>>>
lines and keeping a single correct link; replace the conflicting two links with
one link that points to the Modality definition in types.ts (update the
reference to the file location where the Modality type is actually defined) so
the documentation builds cleanly.
In @docs/reference/type-aliases/SchemaInput.md:
- Around line 14-18: Remove the leftover git conflict markers in SchemaInput.md
around the "Defined in" line and replace the conflicting block with the correct
reference text: set the "Defined in:" link to types.ts line 81 (use "Defined in:
[types.ts:81](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/types.ts#L81)")
so the file no longer contains <<<<<<<, =======, or >>>>>>> markers and points
to the specified location.
In @docs/reference/type-aliases/StreamChunk.md:
- Around line 20-24: Remove the unresolved merge conflict markers (<<<<<<<,
=======, >>>>>>>) from StreamChunk.md and choose the correct "Defined in" link:
verify the current line number of StreamChunk's type in
packages/typescript/ai/src/types.ts (after the adapter restructure) and update
the reference to that exact line (either types.ts:735 or types.ts:740 as
appropriate); ensure only the final resolved line with a single "Defined in"
link remains and no conflict markers are left.
In @docs/reference/type-aliases/StreamChunkType.md:
- Around line 20-24: The file docs/reference/type-aliases/StreamChunkType.md
contains unresolved Git merge conflict markers (<<<<<<<, =======, >>>>>>>)
around the "Defined in" link; remove the conflict markers and keep the correct
"Defined in" reference that matches the current location of StreamChunkType in
packages/typescript/ai/src/types.ts (verify the actual line number in that
file), then update the Markdown link to the correct line number and commit the
cleaned file so the documentation can parse and render properly.
In @examples/ts-react-chat/src/routes/api.tanchat.ts:
- Around line 6-10: Resolve the unresolved git conflict by removing the conflict
markers and keep the cleaner convenience import: replace the conflicted import
entry with toServerSentEventsResponse (remove toServerSentEventsStream and the
<<<<<<</=======/>>>>>>> markers), ensure the import list is comma-correct and
deduplicated, and update any local usages to call toServerSentEventsResponse (it
internally uses toServerSentEventsStream and sets SSE headers) so no header
duplication remains.
- Around line 129-143: Resolve the merge conflict by using the convenience
wrapper toServerSentEventsResponse instead of manually creating a ReadableStream
and new Response; remove the toServerSentEventsStream/readableStream/Response
block and return toServerSentEventsResponse(stream, { abortController }) so
headers and stream creation are handled by the existing implementation (keep the
existing variables stream and abortController).
In @examples/ts-solid-chat/src/routes/api.chat.ts:
- Around line 78-92: Resolve the merge conflict by keeping the convenience
wrapper call toServerSentEventsResponse instead of manually creating a Response
with toServerSentEventsStream; replace the conflicting block so you return
toServerSentEventsResponse(stream, { abortController }) and remove the manual
creation of readableStream/new Response and the explicit headers, ensuring you
still pass the existing stream and abortController variables to the wrapper.
- Around line 2-6: Resolve the unresolved git conflict markers in the import
line by removing the conflict blocks (<<<<<<<, =======, >>>>>>>) and import the
recommended symbol; change the import to use toServerSentEventsResponse (not
toServerSentEventsStream) alongside chat and maxIterations so the module imports
are consistent with the rest of the code and avoid syntax errors. Ensure any
subsequent usage refers to toServerSentEventsResponse if that is what's expected
by the surrounding code (e.g., where you call toServerSentEventsResponse(...));
finally run a quick compile to confirm there are no remaining conflict markers
or mismatched symbol names.
In @examples/ts-svelte-chat/src/routes/api/chat/+server.ts:
- Around line 123-134: Remove the Git conflict markers and the old
toServerSentEventsResponse call and adopt the new streaming approach: call
toServerSentEventsStream(stream, abortController) to get readableStream, then
return a new Response(readableStream, { headers: { 'Content-Type':
'text/event-stream', 'Cache-Control': 'no-cache', Connection: 'keep-alive' } });
ensure abortController is passed to toServerSentEventsStream and the obsolete
toServerSentEventsResponse reference is deleted.
- Around line 5-9: There is an unresolved git merge conflict in the import list
around toServerSentEventsResponse / toServerSentEventsStream; remove the
conflict markers (<<<<<<, =======, >>>>>>>), delete the
toServerSentEventsResponse import, and keep toServerSentEventsStream in the
import list; also scan for any usages of toServerSentEventsResponse in this file
(e.g., in the handler function) and rename them to toServerSentEventsStream to
match the new adapter API (ensure the import and usage names match exactly).
In @packages/typescript/ai-anthropic/package.json:
- Around line 49-53: The package.json has an unresolved git conflict for the
peer dependency "@tanstack/ai" with leftover conflict markers; remove the
conflict markers and set the dependency value to "workspace:*" (replace the
"<<<<<<<", "=======", and ">>>>>>>", and change any "workspace:^" to
"workspace:*") so the JSON is valid and uses the correct workspace protocol.
In @packages/typescript/ai-anthropic/src/tools/custom-tool.ts:
- Around line 1-6: Remove the Git conflict markers and fix the import lines in
custom-tool.ts: delete the <<<<<<<, =======, and >>>>>>> markers and ensure the
file imports the used types from '@tanstack/ai' (include JSONSchema, SchemaInput
and Tool since SchemaInput is used in the file) and remove the unused 'z' import
from 'zod'.
In @packages/typescript/ai-client/package.json:
- Around line 51-55: The package.json contains unresolved Git conflict markers
around the "zod" dependency making the file invalid; open
packages/typescript/ai-client/package.json, remove the conflict markers
(<<<<<<<, =======, >>>>>>>) and choose the correct "zod" version (replace the
conflicted block with a single "zod" entry), likely keeping "zod": "^4.2.0" to
match the updated adapter changes so the JSON is valid and installs/builds
succeed.
In @packages/typescript/ai-gemini/package.json:
- Around line 50-54: Remove the unresolved merge conflict markers around the
@tanstack/ai dependency in package.json and set the dependency to use the
workspace protocol recommended (change the conflicted block to
"\"@tanstack/ai\": \"workspace:*\""); ensure you delete the <<<<<<<, =======,
and >>>>>>> lines and scan the rest of package.json for any other conflict
markers so the file parses correctly.
In @packages/typescript/ai-ollama/package.json:
- Around line 55-59: Remove the Git conflict markers and accept the incoming
change for the @tanstack/ai peerDependency: replace the conflicted block
containing "@tanstack/ai": "workspace:^" and the surrounding <<<<<<<, =======,
>>>>>>> markers with a single entry using "workspace:*" so the peerDependencies
JSON is valid and consistent with the dependencies section; ensure the final
package.json has no merge markers and uses "@tanstack/ai": "workspace:*".
- Around line 44-47: Remove the git conflict markers (<<<<<<<, =======, >>>>>>>)
from the package.json and accept the incoming change that adds the dependency
entry "@tanstack/ai": "workspace:*" into the dependencies object; ensure the
dependencies object remains valid JSON (proper commas and quoting) after adding
the line so the file parses and the workspace:* protocol is used for the
internal package reference.
In @packages/typescript/ai-ollama/src/adapters/text.ts:
- Around line 297-323: Remove the Git conflict markers and keep the incoming
change (no type assertion) in the convertToolsToOllamaFormat return mapping:
assign parameters: tool.inputSchema ?? { type: 'object', properties: {},
required: [] } (remove the "as OllamaTool['function']['parameters']" cast and
delete the HEAD/<<<<<<</>>>>>>> markers), ensuring the resulting object still
returns { type: 'function', function: { name: tool.name, description:
tool.description, parameters: ... } } as before.
In @packages/typescript/ai-openai/package.json:
- Around line 50-54: Remove the Git conflict markers and set the peerDependency
entry for "@tanstack/ai" to use the workspace:* protocol (replace the conflicted
block with "@tanstack/ai": "workspace:*") so package.json is valid and matches
the project's internal dependency convention.
In @packages/typescript/ai-react/package.json:
- Around line 51-56: Resolve the Git conflict markers in package.json
devDependencies by removing the conflict lines and merging the two entries so
both "vite": "^7.2.7" and "zod": "^4.1.13" appear as valid JSON entries; update
the devDependencies object (where "vite" and the added "zod" appear) to include
both dependencies and ensure there is a trailing comma only where valid JSON
requires it and no <<<<<<<, =======, >>>>>>> markers remain.
In @packages/typescript/ai-solid/README.md:
- Around line 160-164: There are unresolved merge conflict markers using
toServerSentEventsResponse vs toStreamResponse; resolve all occurrences by
choosing the new streaming API (replace toServerSentEventsResponse with
toStreamResponse), remove all conflict markers (<<<<<<<, =======, >>>>>>>) and
ensure the import line (import { chat, toStreamResponse } from '@tanstack/ai')
and every usage (e.g., calls to toStreamResponse) are updated consistently
across the file (including the other listed locations) so the adapter compiles
with the new toStreamResponse API.
In @packages/typescript/ai-svelte/package.json:
- Around line 58-63: The package.json contains unresolved git conflict markers
around the dependencies entry (see the "vite" and "zod" lines) which makes the
JSON invalid; remove the conflict markers and merge the entries so dependencies
include both "vite": "^7.2.7" and "zod": "^4.1.13" (or keep the intended one if
zod was not meant to be added), ensuring the resulting package.json is valid
JSON (commas and quoting correct) and run a quick JSON lint or npm install to
verify.
- Line 62: Remove the unresolved git merge conflict markers (<<<<<<<, =======,
>>>>>>>) from package.json and replace the "zod" dependency entry so it is a
valid JSON string without conflict artifacts; change the "zod" version to
"^4.2.0" to match the monorepo standard, save the file and regenerate/update
lockfiles (npm/yarn/pnpm) so all packages are aligned.
In @packages/typescript/ai/src/activities/chat/index.ts:
- Around line 11-19: Resolve all git conflict markers (<<<<<<<, =======,
>>>>>>>) in this file by accepting the incoming Zod-based changes: remove
usages/imports of SchemaInput, isStandardSchema, parseWithStandardSchema, and
convertSchemaToJsonSchema and replace them with z.ZodType imports/usages and
convertZodToJsonSchema; update any parsing/validation code that previously
called parseWithStandardSchema to use Zod parsing/validation on z.ZodType
schemas; ensure all occurrences of the conflict markers (around imports and the
blocks referencing SchemaInput/Standard Schema) are cleaned up and the file
consistently uses convertZodToJsonSchema and z.ZodType throughout.
In @packages/typescript/ai/src/activities/chat/tools/tool-calls.ts:
- Around line 9-20: Remove the Git conflict markers and accept the incoming
addition that defines isZodSchema: delete the<<<<<<< HEAD/=======/>>>>>>>
cfa7844 markers and keep the import type { z } from 'zod' plus the
isZodSchema(schema: SchemaInput | undefined): schema is z.ZodType function;
ensure SchemaInput is in scope (or adjust the parameter type) and that any
usages of isZodSchema reference the same symbol name, then run TypeScript build
to confirm no parsing errors remain.
- Around line 16-19: Delete the unused duplicate function isZodSchema from this
file (it’s already implemented in zod-converter.ts and not referenced here);
remove any now-unused imports (e.g., z) introduced only for that helper, and
verify existing code continues to use isStandardSchema where needed (no
replacements required in this file since isZodSchema is not called).
In @packages/typescript/ai/src/activities/chat/tools/tool-definition.ts:
- Around line 1-5: Resolve the merge conflict by removing the conflict markers
and keeping both required type imports: add back `import type {
StandardJSONSchemaV1 } from '@standard-schema/spec'` and also import `type { z }
from 'zod'` (or `import type { ZodType } from 'zod'` if more appropriate) at the
top of the file, then ensure `InferToolInput` and `InferToolOutput` still
reference `StandardJSONSchemaV1` as used below and any new zod-related types
from the incoming branch are used where needed; delete the <<<<<<<, =======, and
>>>>>>> lines so the file parses cleanly.
In @packages/typescript/ai/src/index.ts:
- Around line 62-69: Resolve the leftover merge conflict markers and restore
consistent exports: remove the conflict delimiters and export the actual
utilities found in stream-to-response.ts (ensure toServerSentEventsResponse and
toHttpResponse are exported) while preserving the new toStreamResponse name as
either an alias to toServerSentEventsResponse or as an additional export for
backward compatibility; update the export list that currently includes
toHttpStream to include both toServerSentEventsResponse (or its alias
toStreamResponse) and toHttpResponse so consumers of toStreamResponse and
existing callers of toServerSentEventsResponse/toHttpResponse continue to work.
- Around line 50-56: Resolve the merge conflict by exporting both converters to
preserve backward compatibility: keep export of convertZodToJsonSchema (from
'./activities/chat/tools/zod-converter') and also restore or alias
convertSchemaToJsonSchema so existing consumers still work; update the module
export block in index.ts to re-export convertZodToJsonSchema and either
re-export a convertSchemaToJsonSchema symbol (pointing to the Zod
implementation) or import and re-export the original generic converter if it
still exists, ensuring both convertZodToJsonSchema and convertSchemaToJsonSchema
symbols are present.
In @packages/typescript/ai/src/stream-to-response.ts:
- Around line 48-57: Resolve the leftover merge conflict markers in the JSDoc
for toServerSentEventsStream by removing the conflict lines (<<<<<<<, =======,
>>>>>>>) and preserving the intended comment content (including the example
block showing usage with chat, openaiText(), model "gpt-4o", and
toServerSentEventsStream). Ensure the JSDoc is validly formatted (no leftover
markers or duplicated sections) so the file
packages/typescript/ai/src/stream-to-response.ts compiles.
In @packages/typescript/ai/src/types.ts:
- Around line 628-643: Resolve the merge conflict for the
TextOptions.outputSchema property by using Zod per project guidelines: change
the type to z.ZodType and update the JSDoc to state "Zod schema for structured
output"; ensure the code imports z from 'zod' and remove/replace any references
to SchemaInput in this type definition so the adapter expects a Zod schema
(symbol: outputSchema on the TextOptions type).
- Around line 1-5: Remove the Git conflict markers and resolve the import to
match the new adapter structure: delete the StandardJSONSchemaV1 import and the
conflict markers, and import the zod symbol and BaseTextAdapter instead (e.g.,
import type { z } from 'zod' and import type { BaseTextAdapter } from the
adapter module you now use). Ensure the file exports/types reference z and
BaseTextAdapter as needed and that no leftover conflict markers or the old
StandardJSONSchemaV1 symbol remain.
In @packages/typescript/ai/tests/standard-converter.test.ts:
- Around line 3-13: This file contains a git merge conflict that mixed two
distinct tests; remove the conflict markers and keep the HEAD version as
standard-converter.test.ts that imports convertSchemaToJsonSchema,
isStandardJSONSchema, isStandardSchema, parseWithStandardSchema, and
validateWithStandardSchema from schema-converter; then create a separate
zod-converter.test.ts in the same tests directory that imports
convertZodToJsonSchema from zod-converter (so convertZodToJsonSchema tests live
separately); ensure no leftover conflict markers remain and each test file only
imports the functions it needs.
In @packages/typescript/ai/tests/stream-to-response.test.ts:
- Around line 4-9: Remove the Git conflict markers and fix the import so it
matches what the test actually uses: either import toStreamResponse if the test
calls toStreamResponse, or import toServerSentEventsResponse if that is
referenced; if both are used, import both. Make the import look like a normal ES
import (e.g., "toStreamResponse" or "toServerSentEventsResponse" or both) from
'../src/stream-to-response' without any conflict markers.
In @testing/panel/package.json:
- Around line 35-39: The package.json contains unresolved Git conflict markers
around the "zod" dependency which breaks JSON parsing; remove the conflict
markers (<<<<<<<, =======, >>>>>>>) and pick the correct version string for
"zod" (e.g., replace the conflicted block with a single "zod": "^4.2.0" entry or
whichever version your project requires), ensuring surrounding commas and JSON
syntax remain valid so the file parses and installs correctly.
In @testing/panel/src/routes/api.addon-chat.ts:
- Around line 74-88: There is a merge conflict in the response handling: either
call toServerSentEventsResponse(stream, { abortController }) which returns a
ready Response with proper headers, or use toServerSentEventsStream(stream,
abortController) and wrap that readable stream in a new Response with the SSE
headers and keep-alive settings; pick one consistent approach, remove the
conflict markers and the unused branch, and ensure the chosen branch supplies
the abortController to the underlying SSE helper (reference to
toServerSentEventsResponse, toServerSentEventsStream, stream, and
abortController).
- Around line 2-6: Resolve the unresolved Git conflict markers by removing the
<<<<<<<, =======, and >>>>>>> lines and pick the new adapter import; replace the
conflicted import with a single clean import line that includes chat,
maxIterations and the chosen SSE helper—either toServerSentEventsStream (as in
the feature branch) or preferably toServerSentEventsResponse (the higher-level
helper that wraps toServerSentEventsStream and sets SSE headers automatically);
then update any downstream usage to call the chosen helper (update calls
referencing toServerSentEventsStream to use toServerSentEventsResponse if you
opt for the higher-level helper).
In @testing/panel/src/routes/api.chat.ts:
- Around line 8-12: The import contains unresolved merge conflict markers and
two competing symbols; remove the conflict markers (<<<<<<<, =======, >>>>>>>)
and keep only the clean import for toServerSentEventsResponse (drop
toServerSentEventsStream), then verify any local references that expect the
stream variant use toServerSentEventsResponse instead so SSE headers are handled
properly (e.g., update call sites that import or invoke toServerSentEventsStream
to use toServerSentEventsResponse).
docs/adapters/openai.md
Outdated
| <<<<<<< HEAD | ||
| import { chat, toServerSentEventsResponse } from "@tanstack/ai"; | ||
| ======= | ||
| import { chat, toStreamResponse } from "@tanstack/ai"; | ||
| >>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolve merge conflict markers and update example code.
Unresolved merge conflict markers are present in the example code. Additionally, line 74 still references toServerSentEventsResponse which should be updated to toStreamResponse to match the resolved import.
🔎 Proposed fix
-<<<<<<< HEAD
-import { chat, toServerSentEventsResponse } from "@tanstack/ai";
-=======
-import { chat, toStreamResponse } from "@tanstack/ai";
->>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137))
+import { chat, toStreamResponse } from "@tanstack/ai";
import { openaiText } from "@tanstack/ai-openai";
export async function POST(request: Request) {
@@ -71,7 +67,7 @@
messages,
});
- return toServerSentEventsResponse(stream);
+ return toStreamResponse(stream);
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <<<<<<< HEAD | |
| import { chat, toServerSentEventsResponse } from "@tanstack/ai"; | |
| ======= | |
| import { chat, toStreamResponse } from "@tanstack/ai"; | |
| >>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137)) | |
| import { chat, toStreamResponse } from "@tanstack/ai"; | |
| import { openaiText } from "@tanstack/ai-openai"; | |
| export async function POST(request: Request) { | |
| const stream = await chat({ | |
| model: new OpenAIAdapter({ | |
| apiKey: process.env.OPENAI_API_KEY, | |
| }), | |
| messages, | |
| }); | |
| return toStreamResponse(stream); | |
| } |
🤖 Prompt for AI Agents
In @docs/adapters/openai.md around lines 59-63, Remove the unresolved merge
conflict markers (<<<<<<<, =======, >>>>>>>) in the import block and standardize
the import to use toStreamResponse from @tanstack/ai (e.g., import { chat,
toStreamResponse } ...). Then update any usages of toServerSentEventsResponse
(the example around the previous line 74) to call toStreamResponse instead,
ensuring all references and examples consistently use chat and toStreamResponse.
| <<<<<<< HEAD | ||
| Defined in: [activities/chat/tools/tool-calls.ts:42](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/activities/chat/tools/tool-calls.ts#L42) | ||
| ======= | ||
| Defined in: [activities/chat/tools/tool-calls.ts:51](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/activities/chat/tools/tool-calls.ts#L51) | ||
| >>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# Check if the markdown file exists and contains merge conflicts
if [ -f "docs/reference/classes/ToolCallManager.md" ]; then
echo "=== Checking for merge conflict markers in ToolCallManager.md ==="
grep -n "^<<<<<<<\|^=======\|^>>>>>>>" "docs/reference/classes/ToolCallManager.md" | head -20
echo ""
echo "=== Total merge conflict markers ==="
grep -c "^<<<<<<<\|^=======\|^>>>>>>>" "docs/reference/classes/ToolCallManager.md" || echo "No conflicts found"
else
echo "File does not exist: docs/reference/classes/ToolCallManager.md"
fiRepository: TanStack/ai
Length of output: 954
🏁 Script executed:
# Check if the source file exists and examine its structure
if [ -f "packages/typescript/ai/src/activities/chat/tools/tool-calls.ts" ]; then
echo "=== File exists ==="
wc -l "packages/typescript/ai/src/activities/chat/tools/tool-calls.ts"
echo ""
echo "=== ToolCallManager class definition ==="
grep -n "class ToolCallManager" "packages/typescript/ai/src/activities/chat/tools/tool-calls.ts"
else
echo "Source file does not exist"
# Try to find the file
echo "=== Searching for tool-calls.ts ==="
find . -name "tool-calls.ts" 2>/dev/null | head -5
fiRepository: TanStack/ai
Length of output: 217
🏁 Script executed:
# Check the actual content of a few conflict blocks to verify they are about line number references
echo "=== Conflict at lines 8-12 ==="
sed -n '8,12p' "docs/reference/classes/ToolCallManager.md"
echo ""
echo "=== Conflict at lines 54-58 ==="
sed -n '54,58p' "docs/reference/classes/ToolCallManager.md"
echo ""
echo "=== Conflict at lines 78-82 ==="
sed -n '78,82p' "docs/reference/classes/ToolCallManager.md"Repository: TanStack/ai
Length of output: 1474
🏁 Script executed:
# Check what's at the disputed line numbers in tool-calls.ts
echo "=== Lines 42-52 (dispute between HEAD:42 vs incoming:51) ==="
sed -n '42,52p' "packages/typescript/ai/src/activities/chat/tools/tool-calls.ts" | cat -n
echo ""
echo "=== Lines 46-56 (dispute between HEAD:46 vs incoming:55) ==="
sed -n '46,56p' "packages/typescript/ai/src/activities/chat/tools/tool-calls.ts" | cat -n
echo ""
echo "=== Lines 54-64 (dispute between HEAD:54 vs incoming:63) ==="
sed -n '54,64p' "packages/typescript/ai/src/activities/chat/tools/tool-calls.ts" | cat -nRepository: TanStack/ai
Length of output: 1404
Resolve unresolved merge conflicts before merging.
The file contains 7 unresolved Git merge conflicts preventing merge. These appear between HEAD and the incoming branch (cfa7844), with disagreements about line number references in tool-calls.ts. The incoming branch shifted all references down by 9 lines compared to HEAD, indicating code additions earlier in the file.
To resolve:
- Verify the correct line numbers in the actual source file (
packages/typescript/ai/src/activities/chat/tools/tool-calls.ts) - Choose the correct line numbers for each conflict
- Remove all conflict markers and finalize the references
Also applies to: 54-58, 78-82, 141-145, 164-168, 194-198, 214-218
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
8-8: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
🤖 Prompt for AI Agents
In @docs/reference/classes/ToolCallManager.md around lines 8-12, The docs file
has unresolved Git conflict markers around multiple "Defined in" links pointing
to tool-calls.ts with differing line numbers; open the source (the TypeScript
file that defines ToolCallManager / tool call helpers) to confirm the correct
line numbers, remove all conflict markers (<<<<<<<, =======, >>>>>>>) in
ToolCallManager.md, and update each "Defined in:" link to the verified single
correct line reference for the symbol(s) (e.g., the ToolCallManager and related
functions in tool-calls.ts) so the file contains no merge markers and each link
points to the authentic line number.
docs/reference/functions/chat.md
Outdated
| <<<<<<< HEAD | ||
| Defined in: [activities/chat/index.ts:976](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/activities/chat/index.ts#L976) | ||
| ======= | ||
| Defined in: [activities/chat/index.ts:945](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/activities/chat/index.ts#L945) | ||
| >>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unresolved merge conflict: Defined in anchor mismatch.
The documentation contains an unresolved merge conflict with two conflicting line number references:
- HEAD:
activities/chat/index.ts:976 - Incoming:
activities/chat/index.ts:945
This must be resolved before the PR can be merged.
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
12-12: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
🤖 Prompt for AI Agents
In @docs/reference/functions/chat.md around lines 12-16, Remove the unresolved
merge markers and fix the `Defined in` anchor in
docs/reference/functions/chat.md by verifying the actual declaration location in
activities/chat/index.ts (check the definition of the exported Chat activity /
function referenced) and update the link to the correct line number (either :976
or :945) or, better, point to the symbol location without a hard-coded line
(e.g., link to the file or use a commit/anchor that targets the function name)
so the conflicting HEAD/Incoming lines are eliminated.
docs/reference/functions/chat.md
Outdated
| <<<<<<< HEAD | ||
| `TAdapter` *extends* [`AnyTextAdapter`](../type-aliases/AnyTextAdapter.md) | ||
|
|
||
| ### TSchema | ||
|
|
||
| `TSchema` *extends* [`SchemaInput`](../type-aliases/SchemaInput.md) \| `undefined` = `undefined` | ||
| ======= | ||
| `TAdapter` *extends* `AnyTextAdapter` | ||
|
|
||
| ### TSchema | ||
|
|
||
| `TSchema` *extends* | ||
| \| `ZodType`\<`unknown`, `unknown`, `$ZodTypeInternals`\<`unknown`, `unknown`\>\> | ||
| \| `undefined` = `undefined` | ||
| >>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
git ls-files docs/reference/functions/chat.mdRepository: TanStack/ai
Length of output: 87
🏁 Script executed:
# Check if the file exists and view the problematic lines
if [ -f "docs/reference/functions/chat.md" ]; then
echo "=== File exists, checking lines 30-44 ==="
sed -n '20,50p' docs/reference/functions/chat.md
else
echo "File not found at docs/reference/functions/chat.md"
# Try searching for the file
find . -name "chat.md" -type f 2>/dev/null | grep -E "(docs|reference)" | head -20
fiRepository: TanStack/ai
Length of output: 1034
🏁 Script executed:
# Search for any merge conflict markers in the repo
rg -l "^<<<<<<< HEAD" --type md | head -20Repository: TanStack/ai
Length of output: 818
🏁 Script executed:
# Search for type definitions related to AnyTextAdapter and TSchema
rg "TAdapter.*extends.*AnyTextAdapter" --type md --type ts --type tsx -A 3 -B 1 | head -50Repository: TanStack/ai
Length of output: 82
🏁 Script executed:
# Search for type definitions
rg "AnyTextAdapter" --type md --type ts | head -30Repository: TanStack/ai
Length of output: 2809
🏁 Script executed:
# Search for SchemaInput type definition
rg "SchemaInput" --type md --type ts | head -30Repository: TanStack/ai
Length of output: 3176
🏁 Script executed:
# Look for adapter-related files
fd -e ts -e md | grep -i adapter | head -30Repository: TanStack/ai
Length of output: 1417
🏁 Script executed:
# Check if this is a generated documentation file
head -20 docs/reference/functions/chat.mdRepository: TanStack/ai
Length of output: 751
🏁 Script executed:
# Check the actual chat function type definition in source
sed -n '940,960p' packages/typescript/ai/src/activities/chat/index.tsRepository: TanStack/ai
Length of output: 621
🏁 Script executed:
# Look for ZodType usage in the source
rg "ZodType" packages/typescript/ai/src/activities/chat/ -A 2 -B 2Repository: TanStack/ai
Length of output: 4168
🏁 Script executed:
# Check if this documentation is auto-generated
rg "generated" docs/reference/functions/chat.mdRepository: TanStack/ai
Length of output: 37
🏁 Script executed:
# Check the actual git history of the merge conflict
git log --oneline -1 cfa7844 2>/dev/null || echo "commit not in history"Repository: TanStack/ai
Length of output: 76
🏁 Script executed:
# Check how many merge conflict markers exist in the source
rg -c "<<<<<<< HEAD" packages/typescript/ai/src/activities/chat/index.ts docs/reference/functions/chat.mdRepository: TanStack/ai
Length of output: 144
🏁 Script executed:
# Get the actual merge conflict sections from source code
sed -n '1,100p' packages/typescript/ai/src/activities/chat/index.ts | rg -A 15 "<<<<<<< HEAD"Repository: TanStack/ai
Length of output: 1962
🏁 Script executed:
# Count total merge conflicts across the repo
rg "<<<<<<< HEAD" -l | wc -lRepository: TanStack/ai
Length of output: 58
🏁 Script executed:
# Get a summary of which files have unresolved merge conflicts
rg "<<<<<<< HEAD" -lRepository: TanStack/ai
Length of output: 5054
🏁 Script executed:
# Check if the repo is in a merge state
cat .git/MERGE_HEAD 2>/dev/null || echo "Not in active merge"Repository: TanStack/ai
Length of output: 74
🏁 Script executed:
# Check the current branch
git branch --show-current 2>/dev/null || echo "Unable to determine branch"Repository: TanStack/ai
Length of output: 37
🏁 Script executed:
# Get info about the PR/branch
git log --oneline -n 5 2>/dev/null || echo "Git log unavailable"Repository: TanStack/ai
Length of output: 141
🏁 Script executed:
# See which version appears to be more complete in source - check imports
sed -n '1,50p' packages/typescript/ai/src/activities/chat/index.ts | cat -ARepository: TanStack/ai
Length of output: 1520
🏁 Script executed:
# Check git status
git statusRepository: TanStack/ai
Length of output: 290
🏁 Script executed:
# See what's the current HEAD
git log --oneline HEAD -1Repository: TanStack/ai
Length of output: 141
🏁 Script executed:
# Check if there are stashed changes or if this is a completed merge with unresolved conflicts
git diff --name-only | head -20Repository: TanStack/ai
Length of output: 37
🏁 Script executed:
# Look at the actual type in the InferSchemaType to understand expected behavior
rg "type InferSchemaType" -A 10Repository: TanStack/ai
Length of output: 1766
Unresolved merge conflict spanning 116 files—this PR requires proper conflict resolution, not just documentation updates.
The repository contains widespread unresolved merge conflicts between the current codebase (HEAD) and the incoming changes (cfa7844). The docs/reference/functions/chat.md conflict at lines 30-44 is one of many symptoms:
HEAD version (current):
TSchemaextendsSchemaInput | undefined(supports Standard JSON Schema or JSON Schema)- Uses
InferSchemaTypeutility that expectsStandardJSONSchemaV1
Incoming version (cfa7844):
TSchemaextendsz.ZodType | undefined(Zod-specific only)- Type inference breaks because
InferSchemaTypeis incompatible withZodType
The incoming branch changed schema handling to Zod-only (aligning with learnings), but the refactoring is incomplete: the InferSchemaType utility and related type infrastructure were not updated to handle z.ZodType inference. This creates a broken type system where Zod schemas cannot be properly typed.
The PR requires resolving all 116 merge conflicts with a comprehensive refactoring that updates both the schema type constraints AND all dependent type utilities.
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
35-35: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
39-39: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
| <<<<<<< HEAD | ||
| `TAdapter` *extends* [`ImageAdapter`](../interfaces/ImageAdapter.md)\<`string`, `object`, `any`, `any`\> | ||
| ======= | ||
| `TAdapter` *extends* `ImageAdapter`\<`string`, `object`, `any`, `any`\> | ||
| >>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolve unresolved merge conflict.
This file contains unresolved merge conflict markers that must be resolved before merging. The conflict involves two formatting styles for the TAdapter type constraint:
- Line 23 (HEAD): Uses markdown link syntax with
[ImageAdapter](../interfaces/ImageAdapter.md)— enables reader navigation to the interface definition. - Line 25 (incoming): Uses plain inline code
ImageAdapter— simpler but loses navigation context.
Recommend resolving in favor of the link-style version (line 23) to maintain documentation navigation and consistency with best practices for API reference docs.
🔎 Proposed resolution
-<<<<<<< HEAD
-`TAdapter` *extends* [`ImageAdapter`](../interfaces/ImageAdapter.md)\<`string`, `object`, `any`, `any`\>
-=======
-`TAdapter` *extends* `ImageAdapter`\<`string`, `object`, `any`, `any`\>
->>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137))
+`TAdapter` *extends* [`ImageAdapter`](../interfaces/ImageAdapter.md)\<`string`, `object`, `any`, `any`\>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <<<<<<< HEAD | |
| `TAdapter` *extends* [`ImageAdapter`](../interfaces/ImageAdapter.md)\<`string`, `object`, `any`, `any`\> | |
| ======= | |
| `TAdapter` *extends* `ImageAdapter`\<`string`, `object`, `any`, `any`\> | |
| >>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137)) | |
| `TAdapter` *extends* [`ImageAdapter`](../interfaces/ImageAdapter.md)\<`string`, `object`, `any`, `any`\> |
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
22-22: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
🤖 Prompt for AI Agents
In @docs/reference/functions/generateImage.md around lines 22-26, Resolve the
Git conflict markers in generateImage.md by removing the <<<<<<<, =======, and
>>>>>>> lines and keep the link-style declaration for the type constraint:
replace the conflicting block with a single line using the markdown link to
ImageAdapter (i.e., `TAdapter` extends
[ImageAdapter](../interfaces/ImageAdapter.md)\<`string`, `object`, `any`,
`any`\>), ensuring no leftover conflict markers remain and formatting matches
surrounding docs.
| <<<<<<< HEAD | ||
| "@tanstack/ai": "workspace:^", | ||
| ======= | ||
| "@tanstack/ai": "workspace:*", | ||
| >>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolve merge conflict in peerDependencies.
The merge conflict markers make the JSON file invalid. You should accept the incoming changes from the cfa7844 branch that use "workspace:*" instead of "workspace:^" for consistency with the dependencies section and monorepo best practices.
🔎 Proposed fix
-<<<<<<< HEAD
- "@tanstack/ai": "workspace:^",
-=======
- "@tanstack/ai": "workspace:*",
->>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137))
+ "@tanstack/ai": "workspace:*",Based on learnings, the workspace:* protocol should be used for internal package dependencies.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <<<<<<< HEAD | |
| "@tanstack/ai": "workspace:^", | |
| ======= | |
| "@tanstack/ai": "workspace:*", | |
| >>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137)) | |
| "@tanstack/ai": "workspace:*", |
🧰 Tools
🪛 Biome (2.1.2)
[error] 55-55: unexpected character <
(parse)
[error] 55-55: unexpected character <
(parse)
[error] 55-55: unexpected character <
(parse)
[error] 55-55: unexpected character <
(parse)
[error] 55-55: unexpected character <
(parse)
[error] 55-55: unexpected character <
(parse)
[error] 55-55: String values must be double quoted.
(parse)
[error] 56-56: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 56-56: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 56-56: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 56-57: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 56-57: unexpected character =
(parse)
[error] 57-57: unexpected character =
(parse)
[error] 57-57: unexpected character =
(parse)
[error] 57-57: unexpected character =
(parse)
[error] 57-57: unexpected character =
(parse)
[error] 57-57: unexpected character =
(parse)
[error] 57-57: unexpected character =
(parse)
[error] 58-58: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 58-58: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 58-58: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 58-59: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 58-59: unexpected character >
(parse)
[error] 59-59: unexpected character >
(parse)
[error] 59-59: unexpected character >
(parse)
[error] 59-59: unexpected character >
(parse)
[error] 59-59: unexpected character >
(parse)
[error] 59-59: unexpected character >
(parse)
[error] 59-59: unexpected character >
(parse)
[error] 59-59: unexpected character (
(parse)
[error] 59-59: unexpected character (
(parse)
[error] 59-59: unexpected character #
(parse)
[error] 59-59: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 59-59: unexpected character )
(parse)
[error] 59-59: unexpected character )
(parse)
🤖 Prompt for AI Agents
In @packages/typescript/ai-ollama/package.json around lines 55-59, Remove the
Git conflict markers and accept the incoming change for the @tanstack/ai
peerDependency: replace the conflicted block containing "@tanstack/ai":
"workspace:^" and the surrounding <<<<<<<, =======, >>>>>>> markers with a
single entry using "workspace:*" so the peerDependencies JSON is valid and
consistent with the dependencies section; ensure the final package.json has no
merge markers and uses "@tanstack/ai": "workspace:*".
| <<<<<<< HEAD | ||
| "vite": "^7.2.7" | ||
| ======= | ||
| "vite": "^7.2.7", | ||
| "zod": "^4.1.13" | ||
| >>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolve the merge conflict in devDependencies.
The file contains unresolved Git conflict markers, making the JSON invalid and breaking all npm/pnpm operations and builds.
🔎 Proposed fix
-<<<<<<< HEAD
- "vite": "^7.2.7"
-=======
"vite": "^7.2.7",
"zod": "^4.1.13"
->>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137))Keep both dependencies since the zod addition supports the new schema conversion utilities mentioned in the PR.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <<<<<<< HEAD | |
| "vite": "^7.2.7" | |
| ======= | |
| "vite": "^7.2.7", | |
| "zod": "^4.1.13" | |
| >>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137)) | |
| "vite": "^7.2.7", | |
| "zod": "^4.1.13" |
🧰 Tools
🪛 Biome (2.1.2)
[error] 51-51: unexpected character <
(parse)
[error] 51-51: unexpected character <
(parse)
[error] 51-51: unexpected character <
(parse)
[error] 51-51: unexpected character <
(parse)
[error] 51-51: unexpected character <
(parse)
[error] 51-51: unexpected character <
(parse)
[error] 51-51: String values must be double quoted.
(parse)
[error] 52-52: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 52-52: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 52-52: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 52-53: unexpected character =
(parse)
[error] 53-53: unexpected character =
(parse)
[error] 53-53: unexpected character =
(parse)
[error] 53-53: unexpected character =
(parse)
[error] 53-53: unexpected character =
(parse)
[error] 53-53: unexpected character =
(parse)
[error] 53-53: unexpected character =
(parse)
[error] 54-54: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 54-54: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 54-54: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 54-54: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 55-55: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 55-55: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 55-55: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 55-56: unexpected character >
(parse)
[error] 56-56: unexpected character >
(parse)
[error] 56-56: unexpected character >
(parse)
[error] 56-56: unexpected character >
(parse)
[error] 56-56: unexpected character >
(parse)
[error] 56-56: unexpected character >
(parse)
[error] 56-56: unexpected character >
(parse)
[error] 56-56: String values must be double quoted.
(parse)
[error] 56-56: unexpected character (
(parse)
[error] 56-56: String values must be double quoted.
(parse)
[error] 56-56: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 56-56: unexpected character (
(parse)
[error] 56-56: unexpected character #
(parse)
[error] 56-56: End of file expected
Use an array for a sequence of values: [1, 2]
(parse)
[error] 56-56: unexpected character )
(parse)
[error] 56-56: unexpected character )
(parse)
🤖 Prompt for AI Agents
In @packages/typescript/ai-react/package.json around lines 51-56, Resolve the
Git conflict markers in package.json devDependencies by removing the conflict
lines and merging the two entries so both "vite": "^7.2.7" and "zod": "^4.1.13"
appear as valid JSON entries; update the devDependencies object (where "vite"
and the added "zod" appear) to include both dependencies and ensure there is a
trailing comma only where valid JSON requires it and no <<<<<<<, =======,
>>>>>>> markers remain.
| <<<<<<< HEAD | ||
| import { chat, toServerSentEventsResponse } from '@tanstack/ai' | ||
| ======= | ||
| import { chat, toStreamResponse } from '@tanstack/ai' | ||
| >>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolve unresolved merge conflicts across the file.
The file contains 6 unresolved merge conflicts between toServerSentEventsResponse (HEAD) and toStreamResponse (incoming branch). These must be resolved before the PR can be merged.
Based on the PR context, the incoming changes (toStreamResponse) represent the new streaming API being introduced in the adapter refactor. Review the conflicts and choose the appropriate version for each location, then remove all conflict markers.
Also applies to: 318-322, 363-367, 376-380, 394-398, 408-412
🤖 Prompt for AI Agents
In @packages/typescript/ai-solid/README.md around lines 160-164, There are
unresolved merge conflict markers using toServerSentEventsResponse vs
toStreamResponse; resolve all occurrences by choosing the new streaming API
(replace toServerSentEventsResponse with toStreamResponse), remove all conflict
markers (<<<<<<<, =======, >>>>>>>) and ensure the import line (import { chat,
toStreamResponse } from '@tanstack/ai') and every usage (e.g., calls to
toStreamResponse) are updated consistently across the file (including the other
listed locations) so the adapter compiles with the new toStreamResponse API.
| <<<<<<< HEAD | ||
| ======= | ||
| import type { z } from 'zod' | ||
|
|
||
| /** | ||
| * Check if a value is a Zod schema by looking for Zod-specific internals. | ||
| */ | ||
| function isZodSchema(schema: SchemaInput | undefined): schema is z.ZodType { | ||
| if (!schema) return false | ||
| return '_zod' in schema && typeof (schema as any)._zod === 'object' | ||
| } | ||
| >>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: Resolve merge conflict.
This merge conflict will cause TypeScript parsing to fail, preventing compilation. The conflict markers must be removed before the PR can be merged.
🔎 Recommended resolution
Accept the incoming changes (lines 11-19) which add the isZodSchema helper function:
-<<<<<<< HEAD
-=======
import type { z } from 'zod'
/**
* Check if a value is a Zod schema by looking for Zod-specific internals.
*/
function isZodSchema(schema: SchemaInput | undefined): schema is z.ZodType {
if (!schema) return false
return '_zod' in schema && typeof (schema as any)._zod === 'object'
}
->>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137))However, see the next comment regarding whether this function is actually needed.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <<<<<<< HEAD | |
| ======= | |
| import type { z } from 'zod' | |
| /** | |
| * Check if a value is a Zod schema by looking for Zod-specific internals. | |
| */ | |
| function isZodSchema(schema: SchemaInput | undefined): schema is z.ZodType { | |
| if (!schema) return false | |
| return '_zod' in schema && typeof (schema as any)._zod === 'object' | |
| } | |
| >>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137)) | |
| import type { z } from 'zod' | |
| /** | |
| * Check if a value is a Zod schema by looking for Zod-specific internals. | |
| */ | |
| function isZodSchema(schema: SchemaInput | undefined): schema is z.ZodType { | |
| if (!schema) return false | |
| return '_zod' in schema && typeof (schema as any)._zod === 'object' | |
| } |
🧰 Tools
🪛 Biome (2.1.2)
[error] 19-20: Expected a statement but instead found '>>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate'.
Expected a statement here.
(parse)
[error] 20-20: expected a name for the function in a function declaration, but found none
(parse)
[error] 20-20: Expected a parameter but instead found '#137'.
Expected a parameter here.
(parse)
[error] 20-20: Expected a function body but instead found ')'.
Expected a function body here.
(parse)
🤖 Prompt for AI Agents
In @packages/typescript/ai/src/activities/chat/tools/tool-calls.ts around lines
9-20, Remove the Git conflict markers and accept the incoming addition that
defines isZodSchema: delete the<<<<<<< HEAD/=======/>>>>>>> cfa7844 markers and
keep the import type { z } from 'zod' plus the isZodSchema(schema: SchemaInput |
undefined): schema is z.ZodType function; ensure SchemaInput is in scope (or
adjust the parameter type) and that any usages of isZodSchema reference the same
symbol name, then run TypeScript build to confirm no parsing errors remain.
| <<<<<<< HEAD | ||
| import type { StandardJSONSchemaV1 } from '@standard-schema/spec' | ||
| ======= | ||
| import type { z } from 'zod' | ||
| >>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate function (#137)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: Resolve merge conflict before proceeding.
The file contains unresolved merge conflict markers that prevent it from being parsed or compiled. Both sides of the conflict import different types:
- HEAD:
StandardJSONSchemaV1(used byInferToolInputandInferToolOutputbelow) - Incoming branch:
ztype from zod
Based on the code that follows, StandardJSONSchemaV1 is actively used in type inference (lines 71, 82). The incoming z type import may represent additional Zod-specific typing from PR #137's adapter changes. You may need both imports after resolution.
Please resolve this conflict, ensuring all necessary type imports are preserved.
🧰 Tools
🪛 Biome (2.1.2)
[error] 1-1: Expected a statement but instead found '<<<<<<< HEAD'.
Expected a statement here.
(parse)
[error] 2-3: Expected a statement but instead found '======='.
Expected a statement here.
(parse)
[error] 4-5: Expected a statement but instead found '>>>>>>> cfa7844 (feat: split up adapters into functionalities and add generate'.
Expected a statement here.
(parse)
[error] 5-5: expected a name for the function in a function declaration, but found none
(parse)
[error] 5-5: Expected a parameter but instead found '#137'.
Expected a parameter here.
(parse)
[error] 5-5: Expected a function body but instead found ')'.
Expected a function body here.
(parse)
🤖 Prompt for AI Agents
In @packages/typescript/ai/src/activities/chat/tools/tool-definition.ts around
lines 1-5, Resolve the merge conflict by removing the conflict markers and
keeping both required type imports: add back `import type { StandardJSONSchemaV1
} from '@standard-schema/spec'` and also import `type { z } from 'zod'` (or
`import type { ZodType } from 'zod'` if more appropriate) at the top of the
file, then ensure `InferToolInput` and `InferToolOutput` still reference
`StandardJSONSchemaV1` as used below and any new zod-related types from the
incoming branch are used where needed; delete the <<<<<<<, =======, and >>>>>>>
lines so the file parses cleanly.
|
Yeah, I messed up the rebase a bit, so coderabbit reviewed the wrong version 😅 |
53e6fb2 to
cf7c2b1
Compare
|
No worries, I'm also building some architecture around this to enable some cool things on top of openrouter. |
… introduce summarization adapter
cf7c2b1 to
89162f0
Compare
|
@AlemTuzlak |

🎯 Changes
This PR adds an OpenRouter adapter.
Since OpenRouter frequently adds new models, there is no typed list of models.
If anyone has suggestions for a better approach, I’d be happy to implement it.
I’m happy to make any changes if needed.
✅ Checklist
pnpm run test:pr.🚀 Release Impact
Summary by CodeRabbit
New Features
Documentation
Tests
Chores
✏️ Tip: You can customize this high-level summary in your review settings.