@orpc/ai-sdk 2.0.0-beta.45 → 2.0.0-beta.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,9 +21,40 @@
21
21
  </a>
22
22
  </div>
23
23
 
24
+ **oRPC** is a TypeScript framework for building end-to-end typesafe APIs. Write your API once as plain TypeScript functions, and oRPC gives you a fully typed client, a REST API with an OpenAPI document, and MCP tools for AI agents, with no code generation. It runs on Node.js, Bun, Deno, Cloudflare Workers, and more.
25
+
26
+ Define procedures on the server and serve them with an [RPC handler](https://orpc.dev/docs/rpc/handler):
27
+
28
+ ```ts
29
+ import { os } from '@orpc/server'
30
+ import * as z from 'zod'
31
+
32
+ export const router = {
33
+ planet: {
34
+ find: os
35
+ .input(z.object({ id: z.number() }))
36
+ .handler(({ input }) => ({ id: input.id, name: 'Earth' })),
37
+ },
38
+ }
39
+ ```
40
+
41
+ Then call them from a client that knows every input and output, without generating anything:
42
+
43
+ ```ts
44
+ import type { RouterClient } from '@orpc/server'
45
+ import type { router } from './router'
46
+ import { createORPCClient } from '@orpc/client'
47
+ import { RPCLink } from '@orpc/client/fetch'
48
+
49
+ const link = new RPCLink({ origin: 'http://localhost:3000', url: '/rpc' })
50
+ const client: RouterClient<typeof router> = createORPCClient(link)
51
+
52
+ const planet = await client.planet.find({ id: 1 }) // { id: number, name: string }
53
+ ```
54
+
24
55
  ## Documentation
25
56
 
26
- You can read the documentation [here](https://orpc.dev).
57
+ Read the full documentation at [orpc.dev](https://orpc.dev), starting with the [Getting Started guide](https://orpc.dev/docs/getting-started).
27
58
 
28
59
  ## Packages
29
60
 
@@ -56,21 +87,21 @@ You can read the documentation [here](https://orpc.dev).
56
87
 
57
88
  **Framework & ecosystem integrations**
58
89
 
59
- | Package | Purpose | Docs |
60
- | ------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
61
- | [@orpc/next](https://www.npmjs.com/package/@orpc/next) | Integrate with [Next.js Server Functions](https://nextjs.org/docs/app/getting-started/mutating-data). | [Next.js](https://orpc.dev/docs/integrations/next) |
62
- | [@orpc/ai-sdk](https://www.npmjs.com/package/@orpc/ai-sdk) | Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools. | [AI SDK](https://orpc.dev/docs/integrations/ai-sdk) |
63
- | [@orpc/mcp](https://www.npmjs.com/package/@orpc/mcp) | Expose procedures as [MCP](https://modelcontextprotocol.io/) tools. | [MCP](https://orpc.dev/docs/integrations/mcp) |
64
- | [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query) | Integrate with [TanStack Query](https://tanstack.com/query/latest). | [TanStack Query](https://orpc.dev/docs/integrations/tanstack-query) |
65
- | [@orpc/pinia-colada](https://www.npmjs.com/package/@orpc/pinia-colada) | Integrate with [Pinia Colada](https://pinia-colada.esm.dev/). | [Pinia Colada](https://orpc.dev/docs/integrations/pinia-colada) |
66
- | [@orpc/swr](https://www.npmjs.com/package/@orpc/swr) | Integrate with [SWR](https://swr.vercel.app/). | [SWR](https://orpc.dev/docs/integrations/swr) |
67
- | [@orpc/msw](https://www.npmjs.com/package/@orpc/msw) | Mock procedures with [Mock Service Worker](https://mswjs.io/). | [MSW](https://orpc.dev/docs/integrations/msw) |
68
- | [@orpc/experimental-effect](https://www.npmjs.com/package/@orpc/experimental-effect) | Integrate with [Effect](https://effect.website/). | [Effect](https://orpc.dev/docs/integrations/effect) |
69
- | [@orpc/nest](https://www.npmjs.com/package/@orpc/nest) | Implement your contract with [NestJS](https://nestjs.com/). | [NestJS](https://orpc.dev/docs/integrations/nest) |
70
- | [@orpc/node](https://www.npmjs.com/package/@orpc/node) | [Node.js](https://nodejs.org/) plugins for static file serving and large uploads. | [Static File](https://orpc.dev/docs/plugins/static-file), [Tmp File Upload](https://orpc.dev/docs/plugins/tmp-file-upload), [Batch Response Compression](https://orpc.dev/docs/plugins/batch-response-compression) |
71
- | [@orpc/bun](https://www.npmjs.com/package/@orpc/bun) | Adapters for [Bun's Redis](https://bun.sh/). | [Publisher](https://orpc.dev/docs/helpers/publisher), [Rate Limit](https://orpc.dev/docs/helpers/ratelimit), [Lock](https://orpc.dev/docs/helpers/lock) |
72
- | [@orpc/cloudflare](https://www.npmjs.com/package/@orpc/cloudflare) | Adapters for [Cloudflare Workers](https://developers.cloudflare.com/workers/). | [Publisher](https://orpc.dev/docs/helpers/publisher), [Rate Limit](https://orpc.dev/docs/helpers/ratelimit), [Lock](https://orpc.dev/docs/helpers/lock), [Traces](https://orpc.dev/docs/integrations/cloudflare-traces) |
73
- | [@orpc/trpc](https://www.npmjs.com/package/@orpc/trpc) | Reuse existing [tRPC](https://trpc.io/) routers within oRPC. | [tRPC](https://orpc.dev/docs/integrations/trpc) |
90
+ | Package | Purpose | Docs |
91
+ | -------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
92
+ | [@orpc/next](https://www.npmjs.com/package/@orpc/next) | Integrate with [Next.js Server Functions](https://nextjs.org/docs/app/getting-started/mutating-data). | [Next.js](https://orpc.dev/docs/integrations/next) |
93
+ | [@orpc/ai-sdk](https://www.npmjs.com/package/@orpc/ai-sdk) | Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools. | [AI SDK](https://orpc.dev/docs/integrations/ai-sdk) |
94
+ | [@orpc/mcp](https://www.npmjs.com/package/@orpc/mcp) | Expose procedures as [MCP](https://modelcontextprotocol.io/) tools. | [MCP](https://orpc.dev/docs/integrations/mcp) |
95
+ | [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query) | Integrate with [TanStack Query](https://tanstack.com/query/latest). | [TanStack Query](https://orpc.dev/docs/integrations/tanstack-query) |
96
+ | [@orpc/pinia-colada](https://www.npmjs.com/package/@orpc/pinia-colada) | Integrate with [Pinia Colada](https://pinia-colada.esm.dev/). | [Pinia Colada](https://orpc.dev/docs/integrations/pinia-colada) |
97
+ | [@orpc/swr](https://www.npmjs.com/package/@orpc/swr) | Integrate with [SWR](https://swr.vercel.app/). | [SWR](https://orpc.dev/docs/integrations/swr) |
98
+ | [@orpc/msw](https://www.npmjs.com/package/@orpc/msw) | Mock procedures with [Mock Service Worker](https://mswjs.io/). | [MSW](https://orpc.dev/docs/integrations/msw) |
99
+ | [@orpc/effect](https://www.npmjs.com/package/@orpc/effect) | Integrate with [Effect](https://effect.website/). | [Effect](https://orpc.dev/docs/integrations/effect) |
100
+ | [@orpc/nest](https://www.npmjs.com/package/@orpc/nest) | Implement your contract with [NestJS](https://nestjs.com/). | [NestJS](https://orpc.dev/docs/integrations/nest) |
101
+ | [@orpc/node](https://www.npmjs.com/package/@orpc/node) | [Node.js](https://nodejs.org/) plugins for static file serving and large uploads. | [Static File](https://orpc.dev/docs/plugins/static-file), [Tmp File Upload](https://orpc.dev/docs/plugins/tmp-file-upload), [Batch Response Compression](https://orpc.dev/docs/plugins/batch-response-compression) |
102
+ | [@orpc/bun](https://www.npmjs.com/package/@orpc/bun) | Adapters for [Bun's Redis](https://bun.sh/). | [Publisher](https://orpc.dev/docs/helpers/publisher), [Rate Limit](https://orpc.dev/docs/helpers/ratelimit), [Lock](https://orpc.dev/docs/helpers/lock) |
103
+ | [@orpc/cloudflare](https://www.npmjs.com/package/@orpc/cloudflare) | Adapters for [Cloudflare Workers](https://developers.cloudflare.com/workers/). | [Publisher](https://orpc.dev/docs/helpers/publisher), [Rate Limit](https://orpc.dev/docs/helpers/ratelimit), [Lock](https://orpc.dev/docs/helpers/lock), [Traces](https://orpc.dev/docs/integrations/cloudflare-traces) |
104
+ | [@orpc/trpc](https://www.npmjs.com/package/@orpc/trpc) | Reuse existing [tRPC](https://trpc.io/) routers within oRPC. | [tRPC](https://orpc.dev/docs/integrations/trpc) |
74
105
 
75
106
  **Observability**
76
107
 
@@ -125,10 +156,11 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
125
156
  <td align="center"><a href="https://github.com/christ12938?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="christ12938"><img src="https://avatars.githubusercontent.com/u/25758598?v=4" width="167" alt="christ12938"/><br />christ12938</a></td>
126
157
  <td align="center"><a href="https://github.com/Ryanjso?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Ryan Soderberg"><img src="https://avatars.githubusercontent.com/u/39172778?u=5ed913c31d57e7221b75784abcad48c7ebddde27&amp;v=4" width="167" alt="Ryan Soderberg"/><br />Ryan Soderberg</a></td>
127
158
  <td align="center"><a href="https://github.com/itigoore01?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="shota"><img src="https://avatars.githubusercontent.com/u/11831107?u=c976a6dc7e055eb026304c46c99100ed22b0c8e0&amp;v=4" width="167" alt="shota"/><br />shota</a></td>
159
+ <td align="center"><a href="https://github.com/Nic13Gamer?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Nicholas"><img src="https://avatars.githubusercontent.com/u/54724556?u=56a7ab430ce7a80d648ab6eba051d454a818ed0b&amp;v=4" width="167" alt="Nicholas"/><br />Nicholas</a></td>
128
160
  <td align="center"><a href="https://github.com/ellis-driscoll?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Ellis Driscoll"><img src="https://avatars.githubusercontent.com/u/70685966?u=c5f95bc33b5991d9744abe00052542e4a2ed3cb9&amp;v=4" width="167" alt="Ellis Driscoll"/><br />Ellis Driscoll</a></td>
129
- <td align="center"><a href="https://github.com/hoangbn?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Hoang Nguyen"><img src="https://avatars.githubusercontent.com/u/38968280?u=c90084c6de65c56facabab7ba13a72a49ddbc3e4&amp;v=4" width="167" alt="Hoang Nguyen"/><br />Hoang Nguyen</a></td>
130
161
  </tr>
131
162
  <tr>
163
+ <td align="center"><a href="https://github.com/hoangbn?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Hoang Nguyen"><img src="https://avatars.githubusercontent.com/u/38968280?u=c90084c6de65c56facabab7ba13a72a49ddbc3e4&amp;v=4" width="167" alt="Hoang Nguyen"/><br />Hoang Nguyen</a></td>
132
164
  <td align="center"><a href="https://opencollective.com/guest-ac41de3b?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Orestis Ioannou"><img src="https://images.opencollective.com/guest-ac41de3b/avatar/460.png" width="167" alt="Orestis Ioannou"/><br />Orestis Ioannou</a></td>
133
165
  <td align="center"><a href="https://automatio.ai/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Stefan Smiljkovic"><img src="https://avatars.githubusercontent.com/u/1984909?u=b7bf5bc40ed49df3c22f69d2da7b8d78709c49ed&amp;v=4" width="167" alt="Stefan Smiljkovic"/><br />Stefan Smiljkovic</a></td>
134
166
  </tr>
@@ -167,7 +199,7 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
167
199
  </tr>
168
200
  </table>
169
201
 
170
- With thanks to [40 past sponsors](https://orpc.dev/sponsors#past-sponsors) who helped get oRPC here.
202
+ With thanks to [39 past sponsors](https://orpc.dev/sponsors#past-sponsors) who helped get oRPC here.
171
203
 
172
204
  ## Open Source Programs
173
205
 
@@ -175,7 +207,9 @@ With thanks to [40 past sponsors](https://orpc.dev/sponsors#past-sponsors) who h
175
207
 
176
208
  <table>
177
209
  <tr>
178
- <td align="center"><a href="https://claude.com/contact-sales/claude-for-oss" target="_blank" rel="noopener" title="Claude for Open Source"><img src="https://cdn.simpleicons.org/claude" width="64" alt="Claude"/><br />Claude for Open Source</a></td>
210
+ <td align="center"><a href="https://claude.com/contact-sales/claude-for-oss" target="_blank" rel="noopener" title="Claude for Open Source"><img src="https://cdn.simpleicons.org/claude" width="64" alt="Claude"/><br />Claude</a></td>
211
+ <td align="center"><a href="https://pullfrog.com/for-oss" target="_blank" rel="noopener" title="Pullfrog for OSS"><img src="https://avatars.githubusercontent.com/in/1768019?s=128&amp;v=4" width="64" alt="Pullfrog"/><br />Pullfrog</a></td>
212
+ <td align="center"><a href="https://macroscope.com/open-source" target="_blank" rel="noopener" title="Macroscope for Open Source"><img src="https://avatars.githubusercontent.com/in/900172?s=128&amp;v=4" width="64" alt="Macroscope"/><br />Macroscope</a></td>
179
213
  </tr>
180
214
  </table>
181
215
 
package/dist/index.d.mts CHANGED
@@ -1,8 +1,9 @@
1
1
  import { ClientOptions } from '@orpc/client';
2
2
  import { AnySchema, ErrorMap, InferSchemaOutput, InferSchemaInput, MetaPlugin, AnyProcedureContract, Schema, ProcedureContract } from '@orpc/contract';
3
3
  import { Lazy, Context, ProcedureClientOptions, Procedure } from '@orpc/server';
4
- import { MaybeOptionalOptions } from '@orpc/shared';
4
+ import { Public, MaybeOptionalOptions } from '@orpc/shared';
5
5
  import { JSONValue, Tool } from 'ai';
6
+ import { OpenAPIJsonSerializer } from '@orpc/openapi';
6
7
 
7
8
  /**
8
9
  * The [function tool](https://ai-sdk.dev/docs/foundations/tools) member of the AI SDK `Tool` union,
@@ -66,6 +67,14 @@ declare function getAiSdkToolMeta(procedureOrLazy: AnyProcedureContract | Lazy<a
66
67
  */
67
68
  type ToolOutput<T> = T extends AsyncIteratorObject<infer TYield, any, any> ? TYield : T;
68
69
  interface ImplementToolFactoryOptions {
70
+ /**
71
+ * Serializes outputs for the default `toModelOutput`, converting types such as `Date`, `BigInt`, and `Set`
72
+ * the same way OpenAPI responses do.
73
+ *
74
+ * @default new OpenAPIJsonSerializer()
75
+ * @see {@link https://orpc.dev/docs/integrations/ai-sdk#tool-outputs | AI SDK Integration - Tool Outputs}
76
+ */
77
+ serializer?: Public<OpenAPIJsonSerializer> | undefined;
69
78
  }
70
79
  interface ToolImplementer {
71
80
  <TInputSchema extends AnySchema, TOutputSchema extends AnySchema>(contract: ProcedureContract<TInputSchema, TOutputSchema, any>, ...rest: MaybeOptionalOptions<Omit<FunctionTool<InferSchemaOutput<TInputSchema>, ToolOutput<InferSchemaInput<TOutputSchema>>>, 'inputSchema' | 'outputSchema'>>): Tool<InferSchemaOutput<TInputSchema>, ToolOutput<InferSchemaInput<TOutputSchema>>>;
@@ -113,7 +122,7 @@ interface ToolImplementer {
113
122
  *
114
123
  * @see {@link https://orpc.dev/docs/integrations/ai-sdk#tool-implementer | AI SDK Integration - Tool Implementer}
115
124
  */
116
- declare function implementToolFactory(_options?: ImplementToolFactoryOptions): ToolImplementer;
125
+ declare function implementToolFactory(options?: ImplementToolFactoryOptions): ToolImplementer;
117
126
  type CreateToolFactoryOptions<TInitialContext extends Context> = ImplementToolFactoryOptions & ProcedureClientOptions<TInitialContext, Schema<unknown>, object, object> & Omit<ClientOptions<object>, 'context' | 'signal'>;
118
127
  interface ToolFactory<TInitialContext extends Context> {
119
128
  <TInputSchema extends AnySchema, TOutputSchema extends AnySchema>(procedure: Procedure<TInitialContext, any, TInputSchema, TOutputSchema, any>, ...rest: MaybeOptionalOptions<Omit<FunctionTool<InferSchemaOutput<TInputSchema>, ToolOutput<InferSchemaInput<TOutputSchema>>>, 'inputSchema' | 'outputSchema' | 'execute'>>): Tool<InferSchemaOutput<TInputSchema>, ToolOutput<InferSchemaInput<TOutputSchema>>>;
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import { ClientOptions } from '@orpc/client';
2
2
  import { AnySchema, ErrorMap, InferSchemaOutput, InferSchemaInput, MetaPlugin, AnyProcedureContract, Schema, ProcedureContract } from '@orpc/contract';
3
3
  import { Lazy, Context, ProcedureClientOptions, Procedure } from '@orpc/server';
4
- import { MaybeOptionalOptions } from '@orpc/shared';
4
+ import { Public, MaybeOptionalOptions } from '@orpc/shared';
5
5
  import { JSONValue, Tool } from 'ai';
6
+ import { OpenAPIJsonSerializer } from '@orpc/openapi';
6
7
 
7
8
  /**
8
9
  * The [function tool](https://ai-sdk.dev/docs/foundations/tools) member of the AI SDK `Tool` union,
@@ -66,6 +67,14 @@ declare function getAiSdkToolMeta(procedureOrLazy: AnyProcedureContract | Lazy<a
66
67
  */
67
68
  type ToolOutput<T> = T extends AsyncIteratorObject<infer TYield, any, any> ? TYield : T;
68
69
  interface ImplementToolFactoryOptions {
70
+ /**
71
+ * Serializes outputs for the default `toModelOutput`, converting types such as `Date`, `BigInt`, and `Set`
72
+ * the same way OpenAPI responses do.
73
+ *
74
+ * @default new OpenAPIJsonSerializer()
75
+ * @see {@link https://orpc.dev/docs/integrations/ai-sdk#tool-outputs | AI SDK Integration - Tool Outputs}
76
+ */
77
+ serializer?: Public<OpenAPIJsonSerializer> | undefined;
69
78
  }
70
79
  interface ToolImplementer {
71
80
  <TInputSchema extends AnySchema, TOutputSchema extends AnySchema>(contract: ProcedureContract<TInputSchema, TOutputSchema, any>, ...rest: MaybeOptionalOptions<Omit<FunctionTool<InferSchemaOutput<TInputSchema>, ToolOutput<InferSchemaInput<TOutputSchema>>>, 'inputSchema' | 'outputSchema'>>): Tool<InferSchemaOutput<TInputSchema>, ToolOutput<InferSchemaInput<TOutputSchema>>>;
@@ -113,7 +122,7 @@ interface ToolImplementer {
113
122
  *
114
123
  * @see {@link https://orpc.dev/docs/integrations/ai-sdk#tool-implementer | AI SDK Integration - Tool Implementer}
115
124
  */
116
- declare function implementToolFactory(_options?: ImplementToolFactoryOptions): ToolImplementer;
125
+ declare function implementToolFactory(options?: ImplementToolFactoryOptions): ToolImplementer;
117
126
  type CreateToolFactoryOptions<TInitialContext extends Context> = ImplementToolFactoryOptions & ProcedureClientOptions<TInitialContext, Schema<unknown>, object, object> & Omit<ClientOptions<object>, 'context' | 'signal'>;
118
127
  interface ToolFactory<TInitialContext extends Context> {
119
128
  <TInputSchema extends AnySchema, TOutputSchema extends AnySchema>(procedure: Procedure<TInitialContext, any, TInputSchema, TOutputSchema, any>, ...rest: MaybeOptionalOptions<Omit<FunctionTool<InferSchemaOutput<TInputSchema>, ToolOutput<InferSchemaInput<TOutputSchema>>>, 'inputSchema' | 'outputSchema' | 'execute'>>): Tool<InferSchemaOutput<TInputSchema>, ToolOutput<InferSchemaInput<TOutputSchema>>>;
package/dist/index.mjs CHANGED
@@ -1,7 +1,8 @@
1
1
  import { getAsyncIteratorObjectSchemasDetails } from '@orpc/contract';
2
2
  import { combineJsonSchemasWithComposition } from '@orpc/json-schema';
3
+ import { OpenAPIJsonSerializer } from '@orpc/openapi';
3
4
  import { Procedure, call } from '@orpc/server';
4
- import { resolveMaybeOptionalOptions, isAsyncGeneratorFunction, toArray, ORPC_NAME, mergeTwoLevels } from '@orpc/shared';
5
+ import { resolveMaybeOptionalOptions, isAsyncGeneratorFunction, toArray, ORPC_NAME, mergeTwoLevels, encodeBase64, loadBytes, stringifyJSON } from '@orpc/shared';
5
6
  import { tool } from 'ai';
6
7
 
7
8
  const aiSdkTool = (incoming) => ({
@@ -78,7 +79,30 @@ function combineOutputSchemas(outputSchemas) {
78
79
  const yieldSchemas = getAsyncIteratorObjectSchemasDetails(outputSchemas)?.yieldSchemas;
79
80
  return combineSchemas([...yieldSchemas ?? outputSchemas].reverse(), false);
80
81
  }
81
- function implementToolFactory(_options = {}) {
82
+ async function toModelOutput(serializer, output) {
83
+ const { json, maps, blobs } = serializer.serializeJson(output);
84
+ if (typeof json === "string") {
85
+ return { type: "text", value: json };
86
+ }
87
+ if (!blobs?.length) {
88
+ return { type: "json", value: json ?? null };
89
+ }
90
+ const files = await Promise.all(blobs.map(async (blob, i) => {
91
+ const path = maps[i];
92
+ const names = blob instanceof File && blob.name !== "" ? [...path, blob.name] : path;
93
+ return {
94
+ type: "file",
95
+ mediaType: blob.type || "application/octet-stream",
96
+ // base64 is encoded once, providers would otherwise re-encode the bytes on every step
97
+ data: { type: "data", data: encodeBase64(await loadBytes(blob)) },
98
+ ...names.length === 0 ? {} : { filename: names.join("/") }
99
+ };
100
+ }));
101
+ return { type: "content", value: json instanceof Blob ? files : [{ type: "text", text: stringifyJSON(json) }, ...files] };
102
+ }
103
+ function implementToolFactory(options = {}) {
104
+ const serializer = options.serializer ?? new OpenAPIJsonSerializer();
105
+ const defaultToModelOutput = ({ output }) => toModelOutput(serializer, output);
82
106
  const factory = (contract, ...rest) => {
83
107
  const toolOptions = resolveMaybeOptionalOptions(rest);
84
108
  const inputSchemas = toArray(contract["~orpc"].inputSchemas);
@@ -87,6 +111,7 @@ function implementToolFactory(_options = {}) {
87
111
  return tool({
88
112
  ...defaults,
89
113
  ...toolOptions,
114
+ toModelOutput: toolOptions.toModelOutput ?? defaults?.toModelOutput ?? defaultToModelOutput,
90
115
  inputSchema: combineSchemas(inputSchemas, true) ?? ANY_SCHEMA,
91
116
  outputSchema: combineOutputSchemas(outputSchemas)
92
117
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/ai-sdk",
3
3
  "type": "module",
4
- "version": "2.0.0-beta.45",
4
+ "version": "2.0.0-beta.47",
5
5
  "description": "AI SDK integration for oRPC: turn contracts and procedures into typesafe AI SDK tools",
6
6
  "license": "MIT",
7
7
  "funding": [
@@ -40,11 +40,12 @@
40
40
  "ai": ">=7.0.31"
41
41
  },
42
42
  "dependencies": {
43
- "@orpc/client": "2.0.0-beta.45",
44
- "@orpc/contract": "2.0.0-beta.45",
45
- "@orpc/json-schema": "2.0.0-beta.45",
46
- "@orpc/server": "2.0.0-beta.45",
47
- "@orpc/shared": "2.0.0-beta.45"
43
+ "@orpc/client": "2.0.0-beta.47",
44
+ "@orpc/contract": "2.0.0-beta.47",
45
+ "@orpc/json-schema": "2.0.0-beta.47",
46
+ "@orpc/openapi": "2.0.0-beta.47",
47
+ "@orpc/server": "2.0.0-beta.47",
48
+ "@orpc/shared": "2.0.0-beta.47"
48
49
  },
49
50
  "devDependencies": {
50
51
  "ai": "^7.0.141",