@browserlessapi/inferlo 0.5.0 → 0.7.0

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.
Files changed (138) hide show
  1. package/README.md +14 -5
  2. package/dist/ai/ai-sdk.d.ts +48 -0
  3. package/dist/ai/ai-sdk.js +235 -0
  4. package/dist/ai/ai-sdk.js.map +1 -0
  5. package/dist/ai/index.d.ts +44 -3
  6. package/dist/ai/index.js +164 -9
  7. package/dist/ai/index.js.map +1 -1
  8. package/dist/ai/public.d.ts +6 -1
  9. package/dist/ai/public.js +2 -0
  10. package/dist/ai/public.js.map +1 -1
  11. package/dist/ai/ui.d.ts +47 -0
  12. package/dist/ai/ui.js +33 -0
  13. package/dist/ai/ui.js.map +1 -0
  14. package/dist/api-version.d.ts +32 -0
  15. package/dist/api-version.js +45 -0
  16. package/dist/api-version.js.map +1 -0
  17. package/dist/app.d.ts +60 -6
  18. package/dist/app.js +310 -66
  19. package/dist/app.js.map +1 -1
  20. package/dist/astro.d.ts +60 -0
  21. package/dist/astro.js +68 -0
  22. package/dist/astro.js.map +1 -0
  23. package/dist/audit.d.ts +57 -0
  24. package/dist/audit.js +99 -0
  25. package/dist/audit.js.map +1 -0
  26. package/dist/auth.d.ts +1 -0
  27. package/dist/auth.js +1 -0
  28. package/dist/auth.js.map +1 -1
  29. package/dist/azure.d.ts +66 -0
  30. package/dist/azure.js +119 -0
  31. package/dist/azure.js.map +1 -0
  32. package/dist/cache.d.ts +96 -0
  33. package/dist/cache.js +247 -0
  34. package/dist/cache.js.map +1 -0
  35. package/dist/cli/main.js +28 -7
  36. package/dist/cli/main.js.map +1 -1
  37. package/dist/client-ip.d.ts +36 -1
  38. package/dist/client-ip.js +80 -1
  39. package/dist/client-ip.js.map +1 -1
  40. package/dist/db/memory.js +2 -1
  41. package/dist/db/memory.js.map +1 -1
  42. package/dist/db/postgres.js +4 -1
  43. package/dist/db/postgres.js.map +1 -1
  44. package/dist/db/table.d.ts +37 -5
  45. package/dist/db/table.js +96 -15
  46. package/dist/db/table.js.map +1 -1
  47. package/dist/db/types.d.ts +2 -0
  48. package/dist/describe.d.ts +54 -2
  49. package/dist/describe.js +34 -3
  50. package/dist/describe.js.map +1 -1
  51. package/dist/events.d.ts +134 -0
  52. package/dist/events.js +196 -0
  53. package/dist/events.js.map +1 -0
  54. package/dist/fastify.d.ts +10 -2
  55. package/dist/fastify.js +22 -4
  56. package/dist/fastify.js.map +1 -1
  57. package/dist/h3.d.ts +76 -0
  58. package/dist/h3.js +61 -0
  59. package/dist/h3.js.map +1 -0
  60. package/dist/hapi.d.ts +45 -0
  61. package/dist/hapi.js +57 -0
  62. package/dist/hapi.js.map +1 -0
  63. package/dist/index.d.ts +25 -5
  64. package/dist/index.js +9 -1
  65. package/dist/index.js.map +1 -1
  66. package/dist/jobs.d.ts +70 -10
  67. package/dist/jobs.js +78 -13
  68. package/dist/jobs.js.map +1 -1
  69. package/dist/koa.d.ts +51 -0
  70. package/dist/koa.js +45 -0
  71. package/dist/koa.js.map +1 -0
  72. package/dist/lambda.d.ts +110 -0
  73. package/dist/lambda.js +169 -0
  74. package/dist/lambda.js.map +1 -0
  75. package/dist/langchain.d.ts +58 -0
  76. package/dist/langchain.js +220 -0
  77. package/dist/langchain.js.map +1 -0
  78. package/dist/mcp.d.ts +1 -1
  79. package/dist/mcp.js +7 -3
  80. package/dist/mcp.js.map +1 -1
  81. package/dist/model.d.ts +23 -6
  82. package/dist/model.js +35 -6
  83. package/dist/model.js.map +1 -1
  84. package/dist/module.d.ts +52 -0
  85. package/dist/module.js +152 -0
  86. package/dist/module.js.map +1 -0
  87. package/dist/nextjs.d.ts +35 -0
  88. package/dist/nextjs.js +33 -0
  89. package/dist/nextjs.js.map +1 -0
  90. package/dist/openapi.d.ts +3 -0
  91. package/dist/openapi.js +12 -3
  92. package/dist/openapi.js.map +1 -1
  93. package/dist/permissions.d.ts +26 -0
  94. package/dist/permissions.js +78 -0
  95. package/dist/permissions.js.map +1 -0
  96. package/dist/rate-limit.d.ts +5 -3
  97. package/dist/rate-limit.js +3 -3
  98. package/dist/rate-limit.js.map +1 -1
  99. package/dist/react-router.d.ts +41 -0
  100. package/dist/react-router.js +42 -0
  101. package/dist/react-router.js.map +1 -0
  102. package/dist/redis-events.d.ts +27 -0
  103. package/dist/redis-events.js +163 -0
  104. package/dist/redis-events.js.map +1 -0
  105. package/dist/redis-jobs.d.ts +24 -0
  106. package/dist/redis-jobs.js +203 -0
  107. package/dist/redis-jobs.js.map +1 -0
  108. package/dist/redis.d.ts +30 -0
  109. package/dist/redis.js +106 -0
  110. package/dist/redis.js.map +1 -0
  111. package/dist/request-matcher.d.ts +4 -0
  112. package/dist/request-matcher.js +14 -0
  113. package/dist/request-matcher.js.map +1 -0
  114. package/dist/response-body.d.ts +6 -0
  115. package/dist/response-body.js +7 -0
  116. package/dist/response-body.js.map +1 -0
  117. package/dist/route.d.ts +50 -2
  118. package/dist/route.js +24 -0
  119. package/dist/route.js.map +1 -1
  120. package/dist/schema.d.ts +2 -2
  121. package/dist/serve.d.ts +26 -2
  122. package/dist/serve.js +111 -10
  123. package/dist/serve.js.map +1 -1
  124. package/dist/service-client.d.ts +91 -0
  125. package/dist/service-client.js +177 -0
  126. package/dist/service-client.js.map +1 -0
  127. package/dist/sessions.d.ts +74 -0
  128. package/dist/sessions.js +172 -0
  129. package/dist/sessions.js.map +1 -0
  130. package/dist/sveltekit.d.ts +72 -0
  131. package/dist/sveltekit.js +68 -0
  132. package/dist/sveltekit.js.map +1 -0
  133. package/dist/tracing.d.ts +122 -0
  134. package/dist/tracing.js +210 -0
  135. package/dist/tracing.js.map +1 -0
  136. package/llms.txt +8 -3
  137. package/package.json +78 -4
  138. package/templates/app/AGENTS.md +10 -6
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  **The enterprise-ready TypeScript backend framework, with AI models built in.**
4
4
 
5
- Inferlo is a batteries-included TypeScript backend framework for production APIs, SaaS products and enterprise services, in the same class as NestJS, Fastify and AdonisJS. It gives you routing, validation, a typed database layer with PostgreSQL and migrations, auth, rate limiting, background jobs, cron, OpenAPI and secure defaults in one package with zero runtime dependencies, running on Node.js, Bun and edge runtimes.
5
+ Inferlo is a batteries-included TypeScript backend framework for production APIs, SaaS products and enterprise services, in the same class as NestJS, Fastify and AdonisJS. It gives you routing, validation, a typed database layer with PostgreSQL and migrations, auth, rate limiting, background jobs, cron, OpenAPI and secure defaults in one package with zero runtime dependencies, running on Node.js, Bun, Deno and edge runtimes.
6
6
 
7
7
  What sets it apart is that AI models are part of the core, not a plugin: Anthropic, OpenAI, Gemini, local models through Ollama and any OpenAI-compatible server behind one API, with fallback between models, typed structured output, streaming, tool calling, image input and per-user usage and cost tracking, plus an MCP server built from your routes.
8
8
 
@@ -47,12 +47,12 @@ That one model definition gives you the database table, insert and update valida
47
47
  - **Embeddings** for search and recommendations.
48
48
  - **Usage, cost and budgets.** Every call is tracked per user, so you can bill customers and stop calls when their credits run out.
49
49
  - **MCP server.** Mark a route `tool: true` and AI agents can call your API, with the same permissions as any other client.
50
- - **Use it in any framework.** `import { createAI } from "@browserlessapi/inferlo/ai"` gives you the same AI module without `createApp`, for Express, Hono, Fastify, NestJS or a plain script, and `toNodeHandler(app, { prefix: "/ai" })` mounts a whole Inferlo app (routes, OpenAPI, MCP) inside Express, Fastify, NestJS or `node:http`, `hono.use(inferloAI(ai))` from `@browserlessapi/inferlo/hono` gives Hono handlers `c.var.ai`, `server.use(inferloAI(ai))` from `@browserlessapi/inferlo/express` gives Express handlers `req.ai`, and `fastify.register(inferloPlugin, { ai })` from `@browserlessapi/inferlo/fastify` gives Fastify `request.ai`, `new Elysia().use(inferloAI(ai))` from `@browserlessapi/inferlo/elysia` gives Elysia handlers `ai`, `InferloModule.forRoot({ ai })` from `@browserlessapi/inferlo/nestjs` makes the AI client injectable in NestJS, the provider from `@browserlessapi/inferlo/adonisjs` gives AdonisJS routes `ctx.ai`, `@Configuration({ imports: [inferloAI(ai)] })` from `@browserlessapi/inferlo/tsed` makes the AI client injectable in Ts.ED as `InferloAI`, and `trpc.procedure.use(inferloAI(ai))` from `@browserlessapi/inferlo/trpc` gives tRPC procedures `ctx.ai` while `trpcTools(router, { caller, procedures })` lets a model call tRPC procedures as tools (see [Use with other frameworks](docs/integrations.md)).
50
+ - **Use it in any framework.** `import { createAI } from "@browserlessapi/inferlo/ai"` gives you the same AI module without `createApp`, for Express, Hono, Fastify, NestJS or a plain script, and `toNodeHandler(app, { prefix: "/ai" })` mounts a whole Inferlo app (routes, OpenAPI, MCP) inside Express, Fastify, NestJS or `node:http`, `hono.use(inferloAI(ai))` from `@browserlessapi/inferlo/hono` gives Hono handlers `c.var.ai`, `server.use(inferloAI(ai))` from `@browserlessapi/inferlo/express` gives Express handlers `req.ai`, and `fastify.register(inferloPlugin, { ai })` from `@browserlessapi/inferlo/fastify` gives Fastify `request.ai`, `server.register({ plugin: inferloPlugin, options: { ai } })` from `@browserlessapi/inferlo/hapi` gives hapi `request.ai` (and `options: { app }` with `routes: { prefix }` serves a whole Inferlo app), `new Elysia().use(inferloAI(ai))` from `@browserlessapi/inferlo/elysia` gives Elysia handlers `ai`, `InferloModule.forRoot({ ai })` from `@browserlessapi/inferlo/nestjs` makes the AI client injectable in NestJS, the provider from `@browserlessapi/inferlo/adonisjs` gives AdonisJS routes `ctx.ai`, `@Configuration({ imports: [inferloAI(ai)] })` from `@browserlessapi/inferlo/tsed` makes the AI client injectable in Ts.ED as `InferloAI`, `trpc.procedure.use(inferloAI(ai))` from `@browserlessapi/inferlo/trpc` gives tRPC procedures `ctx.ai` while `trpcTools(router, { caller, procedures })` lets a model call tRPC procedures as tools, `koa.use(inferloAI(ai))` and `koa.use(toKoaMiddleware(app, { prefix: "/api" }))` from `@browserlessapi/inferlo/koa` give Koa `ctx.ai` and a whole Inferlo app, `export const { GET, POST } = toNextHandlers(app, { prefix: "/api" })` from `@browserlessapi/inferlo/nextjs` serves a whole Inferlo app from a Next.js App Router route, `export default toH3Handler(app, { prefix: "/api" })` from `@browserlessapi/inferlo/h3` serves it from a Nuxt or Nitro server route (with `event.context.ai` from a Nitro plugin), `export const { GET, POST, fallback } = toSvelteKitHandlers(app, { prefix: "/api" })` from `@browserlessapi/inferlo/sveltekit` serves it from a SvelteKit rest route (with `event.locals.ai` from a handle hook), `export const ALL = toAstroHandler(app, { prefix: "/api" })` from `@browserlessapi/inferlo/astro` serves it from an Astro endpoint (with `locals.ai` from a middleware), `export const { loader, action } = toReactRouterHandlers(app, { prefix: "/api" })` from `@browserlessapi/inferlo/react-router` serves it from a React Router (Remix) resource route, `export const handler = toLambdaHandler(app)` from `@browserlessapi/inferlo/lambda` runs it on AWS Lambda (function URLs and API Gateway, with response streaming), `handler: toAzureHandler(app, { prefix: "/api" })` from `@browserlessapi/inferlo/azure` runs it in an Azure Functions HTTP trigger (with streaming), `functions.http("inferlo", toNodeHandler(app))` runs it as a Google Cloud Run function, `export default app` runs it as a Cloudflare Worker or a Vercel Function and `export default app.fetch` as a Netlify Function, and an Encore.ts raw endpoint serves a whole Inferlo app with `api.raw({ expose: true, method: "*", path: "/inferlo/*rest" }, toNodeHandler(app, { prefix: "/inferlo" }))` An app that already uses Drizzle ORM adds Inferlo on the same Postgres pool, with Drizzle and Inferlo writes in one transaction through `tx.$pgClient()` (see [Use with other frameworks](docs/integrations.md)).
51
51
  - **Background jobs for slow AI work.** Queue a typed job from a route with `ctx.jobs.enqueue(...)` and it runs after the response, with retries, from a Postgres queue shared by every instance (`inferlo worker` runs them in their own process), and schedule jobs with `cron("0 3 * * *", job)`.
52
52
 
53
53
  ## Why Inferlo
54
54
 
55
- See the full [comparison with NestJS, AdonisJS, Fastify, Hono, ElysiaJS, Ts.ED, tRPC and Encore.ts](docs/comparison.md). Integrations that let you use Inferlo's AI features inside those frameworks are in progress (see the [roadmap](ROADMAP.md)).
55
+ See the full [comparison with NestJS, AdonisJS, Fastify, Hono, ElysiaJS, Ts.ED, tRPC and Encore.ts](docs/comparison.md). Inferlo's AI features work inside each of those frameworks, and a whole Inferlo app mounts inside them (see [Use with other frameworks](docs/integrations.md)).
56
56
 
57
57
  | | NestJS | Hono | AdonisJS | Express | **Inferlo** |
58
58
  |---|---|---|---|---|---|
@@ -81,9 +81,9 @@ Inferlo is also designed so AI coding tools (Claude Code, Cursor, Codex, NeonCod
81
81
 
82
82
  ## Quick start
83
83
 
84
- Requires Node.js 22.18+ or Bun 1.3+. TypeScript runs directly with no build step.
84
+ Requires Node.js 22.18+, Bun 1.3+ or Deno 2.9+. TypeScript runs directly with no build step.
85
85
 
86
- Every release is tested on Node.js 22.18, 22, 24, 26 and the current release; Bun 1.3.0 and latest; PostgreSQL 14, 15, 16, 17, 18 and latest; and TypeScript 5.9 and latest.
86
+ Every release is tested on Node.js 22.18, 22, 24, 26 and the current release; Bun 1.3.0 and latest; Deno 2.9.0 and latest; PostgreSQL 14, 15, 16, 17, 18 and latest; and TypeScript 5.9 and latest.
87
87
 
88
88
  ```bash
89
89
  npx @browserlessapi/inferlo new my-app
@@ -118,14 +118,23 @@ npm install @browserlessapi/inferlo
118
118
  - [Routes](docs/routes.md)
119
119
  - [Auth](docs/auth.md)
120
120
  - [AI](docs/ai.md)
121
+ - [Modules](docs/modules.md)
122
+ - [Service-to-service calls](docs/services.md)
123
+ - [Caching](docs/caching.md)
124
+ - [Redis](docs/redis.md)
121
125
  - [MCP, OpenAPI and describe](docs/mcp.md)
122
126
  - [CLI](docs/cli.md)
123
127
  - [Testing](docs/testing.md)
124
128
  - [Use with other frameworks](docs/integrations.md)
125
129
  - [Migrate from Express](docs/migrate-from-express.md)
130
+ - [Migrate from NestJS](docs/migrate-from-nestjs.md)
131
+ - [Migrate from Hono](docs/migrate-from-hono.md)
132
+ - [Migrate from Koa](docs/migrate-from-koa.md)
133
+ - [Migrate from Fastify](docs/migrate-from-fastify.md)
126
134
  - [Security](docs/security.md)
127
135
  - [Observability](docs/observability.md)
128
136
  - [Deployment](docs/deploy.md)
137
+ - [Performance](docs/performance.md)
129
138
  - [Error codes](docs/errors.md)
130
139
  - [Support policy](docs/support.md)
131
140
  - [Example: helpdesk with AI triage](examples/helpdesk)
@@ -0,0 +1,48 @@
1
+ import { type Provider } from "./providers.ts";
2
+ /** The parts of an AI SDK language model (LanguageModelV2, V3 or V4) that Inferlo uses. */
3
+ export interface AISdkLanguageModel {
4
+ readonly specificationVersion: string;
5
+ readonly provider: string;
6
+ readonly modelId: string;
7
+ doGenerate(options: any): PromiseLike<{
8
+ content: readonly object[];
9
+ usage: unknown;
10
+ }>;
11
+ doStream(options: any): PromiseLike<{
12
+ stream: ReadableStream<any>;
13
+ }>;
14
+ }
15
+ /** The parts of an AI SDK embedding model (EmbeddingModelV2, V3 or V4) that Inferlo uses. */
16
+ export interface AISdkEmbeddingModel {
17
+ readonly specificationVersion: string;
18
+ readonly modelId: string;
19
+ readonly maxEmbeddingsPerCall?: PromiseLike<number | undefined> | number | undefined;
20
+ doEmbed(options: {
21
+ values: string[];
22
+ abortSignal?: AbortSignal;
23
+ }): PromiseLike<{
24
+ embeddings: number[][];
25
+ usage?: {
26
+ tokens: number;
27
+ };
28
+ }>;
29
+ }
30
+ /**
31
+ * An AI SDK provider: what createOpenAI(), createAnthropic(), bedrock, mistral, gateway and the others
32
+ * return, and what customProvider() from "ai" builds. Only languageModel is required.
33
+ */
34
+ export interface AISdkProvider {
35
+ readonly specificationVersion?: string;
36
+ languageModel(modelId: string): AISdkLanguageModel;
37
+ embeddingModel?(modelId: string): AISdkEmbeddingModel;
38
+ textEmbeddingModel?(modelId: string): AISdkEmbeddingModel;
39
+ }
40
+ export interface AISdkOptions {
41
+ /** Provider name in errors, usage and traces. Default: the AI SDK provider's own name (the part before the first dot, e.g. "openai"). */
42
+ name?: string;
43
+ }
44
+ /**
45
+ * Use any Vercel AI SDK provider in createAI({ providers }) or createApp({ ai: { providers } }):
46
+ * providers: { openai: aiSdk(createOpenAI({ apiKey })) }, then models: { fast: "openai:gpt-5-mini" }.
47
+ */
48
+ export declare function aiSdk(provider: AISdkProvider, options?: AISdkOptions): Provider;
@@ -0,0 +1,235 @@
1
+ /**
2
+ * Vercel AI SDK providers as Inferlo providers: every @ai-sdk/* provider (OpenAI, Anthropic, Google,
3
+ * Mistral, Amazon Bedrock, Azure, Vertex, Groq, xAI, the AI Gateway, ...) works with aliases, fallback,
4
+ * usage tracking, structured output, tools, streaming and embeddings.
5
+ *
6
+ * import { createMistral } from "@ai-sdk/mistral";
7
+ * createAI({ providers: { mistral: aiSdk(createMistral({ apiKey })) }, models: { fast: "mistral:mistral-small-latest" } })
8
+ *
9
+ * Inferlo has no dependency on the AI SDK: aiSdk() calls the provider's languageModel(id) and
10
+ * embeddingModel(id) (textEmbeddingModel(id) on older providers) and speaks the model specification
11
+ * versions v2 (ai 5), v3 (ai 6) and v4 (ai 7) itself.
12
+ */
13
+ import { InferloError } from "../errors.js";
14
+ import { imageData, ProviderError } from "./providers.js";
15
+ /** The specification versions aiSdk() speaks. */
16
+ const VERSIONS = new Set(["v2", "v3", "v4"]);
17
+ /**
18
+ * Use any Vercel AI SDK provider in createAI({ providers }) or createApp({ ai: { providers } }):
19
+ * providers: { openai: aiSdk(createOpenAI({ apiKey })) }, then models: { fast: "openai:gpt-5-mini" }.
20
+ */
21
+ export function aiSdk(provider, options = {}) {
22
+ if (!provider || typeof provider !== "object" && typeof provider !== "function" || typeof provider.languageModel !== "function") {
23
+ throw new InferloError("IL5029", "aiSdk() needs an AI SDK provider, such as createOpenAI({ apiKey }) from @ai-sdk/openai.", {
24
+ fix: 'Pass the provider, not a model: aiSdk(createOpenAI({ apiKey })) with models: { fast: "openai:gpt-5-mini" }. For single models use customProvider({ languageModels: { ... } }) from "ai".',
25
+ });
26
+ }
27
+ if (options.name !== undefined && (typeof options.name !== "string" || !/^[a-zA-Z0-9._-]{1,64}$/.test(options.name))) {
28
+ throw new InferloError("IL5029", `aiSdk() name must be 1 to 64 letters, digits, dots, dashes or underscores, got ${JSON.stringify(options.name)}.`);
29
+ }
30
+ const languageModels = new Map();
31
+ const embeddingModels = new Map();
32
+ let label = options.name;
33
+ const nameOf = (model) => (label ??= String(model.provider ?? "ai-sdk").split(".")[0] || "ai-sdk");
34
+ const languageModel = (id) => {
35
+ let model = languageModels.get(id);
36
+ if (!model) {
37
+ model = provider.languageModel(id);
38
+ checkVersion(model, id, "language");
39
+ languageModels.set(id, model);
40
+ }
41
+ return model;
42
+ };
43
+ const embeddingModel = (id) => {
44
+ let model = embeddingModels.get(id);
45
+ if (!model) {
46
+ const make = provider.embeddingModel ?? provider.textEmbeddingModel;
47
+ if (typeof make !== "function") {
48
+ throw new InferloError("IL5029", `The AI SDK provider${label ? ` "${label}"` : ""} has no embedding models.`, { fix: "Use an embedding model of another provider in ai.embed({ model })." });
49
+ }
50
+ model = make.call(provider, id);
51
+ checkVersion(model, id, "embedding");
52
+ embeddingModels.set(id, model);
53
+ }
54
+ return model;
55
+ };
56
+ const out = {
57
+ get name() {
58
+ return label ?? "ai-sdk";
59
+ },
60
+ async generate(r) {
61
+ const model = languageModel(r.model);
62
+ const name = nameOf(model);
63
+ const v2 = model.specificationVersion === "v2";
64
+ let result;
65
+ try {
66
+ result = (await model.doGenerate(callOptions(r, v2)));
67
+ }
68
+ catch (error) {
69
+ throw providerError(name, error);
70
+ }
71
+ const text = result.content.filter((c) => c.type === "text").map((c) => c.text ?? "").join("");
72
+ const toolCalls = result.content
73
+ .filter((c) => c.type === "tool-call")
74
+ .map((c) => ({ id: c.toolCallId ?? "", name: c.toolName ?? "", input: parseInput(c.input) }));
75
+ return { text, usage: usage(result.usage), ...(toolCalls.length ? { toolCalls } : {}) };
76
+ },
77
+ async *stream(r) {
78
+ const model = languageModel(r.model);
79
+ const name = nameOf(model);
80
+ const v2 = model.specificationVersion === "v2";
81
+ let stream;
82
+ try {
83
+ ({ stream } = await model.doStream(callOptions(r, v2)));
84
+ }
85
+ catch (error) {
86
+ throw providerError(name, error);
87
+ }
88
+ const reader = stream.getReader();
89
+ let total;
90
+ try {
91
+ while (true) {
92
+ const { done, value: part } = await reader.read();
93
+ if (done)
94
+ break;
95
+ if (part.type === "text-delta") {
96
+ const text = part.delta ?? part.textDelta;
97
+ if (text)
98
+ yield text;
99
+ }
100
+ else if (part.type === "finish")
101
+ total = usage(part.usage);
102
+ else if (part.type === "error")
103
+ throw providerError(name, part.error);
104
+ }
105
+ }
106
+ finally {
107
+ reader.releaseLock();
108
+ }
109
+ yield { usage: total ?? { inputTokens: 0, outputTokens: 0 } };
110
+ },
111
+ async embed({ model: id, input, signal }) {
112
+ const model = embeddingModel(id);
113
+ const name = nameOf({ provider: model.provider });
114
+ const max = (await model.maxEmbeddingsPerCall) ?? input.length;
115
+ const embeddings = [];
116
+ let tokens = 0;
117
+ for (let i = 0; i < input.length; i += Math.max(1, max)) {
118
+ let result;
119
+ try {
120
+ result = await model.doEmbed({ values: input.slice(i, i + Math.max(1, max)), abortSignal: signal });
121
+ }
122
+ catch (error) {
123
+ throw providerError(name, error);
124
+ }
125
+ embeddings.push(...result.embeddings.map((e) => Array.from(e)));
126
+ tokens += result.usage?.tokens ?? 0;
127
+ }
128
+ return { embeddings, usage: { inputTokens: tokens, outputTokens: 0 } };
129
+ },
130
+ };
131
+ return out;
132
+ }
133
+ function checkVersion(model, id, kind) {
134
+ if (!model || typeof model !== "object" || !VERSIONS.has(String(model.specificationVersion))) {
135
+ throw new InferloError("IL5029", `The AI SDK ${kind} model "${id}" uses specification ${String(model?.specificationVersion ?? "(none)")}, which aiSdk() does not speak.`, {
136
+ fix: "Use a provider package made for ai 5 or later (@ai-sdk/* 2.0 or later, LanguageModelV2, V3 or V4).",
137
+ });
138
+ }
139
+ }
140
+ /** Inferlo's request as AI SDK call options. v2 file parts carry data or a URL directly; v3 and v4 wrap it. */
141
+ function callOptions(r, v2) {
142
+ const out = { prompt: prompt(r.messages, v2), abortSignal: r.signal };
143
+ if (r.maxTokens !== undefined)
144
+ out.maxOutputTokens = r.maxTokens;
145
+ if (r.temperature !== undefined)
146
+ out.temperature = r.temperature;
147
+ if (r.json)
148
+ out.responseFormat = r.jsonSchema ? { type: "json", schema: r.jsonSchema, name: "output" } : { type: "json" };
149
+ if (r.tools?.length) {
150
+ out.tools = r.tools.map((tool) => ({ type: "function", name: tool.name, description: tool.description, inputSchema: tool.inputSchema }));
151
+ out.toolChoice = { type: "auto" };
152
+ }
153
+ return out;
154
+ }
155
+ function prompt(messages, v2) {
156
+ const names = new Map();
157
+ const out = [];
158
+ for (const m of messages) {
159
+ if (m.role === "system")
160
+ out.push({ role: "system", content: m.content });
161
+ else if (m.role === "user") {
162
+ const content = [];
163
+ if (m.content)
164
+ content.push({ type: "text", text: m.content });
165
+ for (const image of m.images ?? [])
166
+ content.push(filePart(image, v2));
167
+ out.push({ role: "user", content: content.length ? content : [{ type: "text", text: "" }] });
168
+ }
169
+ else if (m.role === "assistant") {
170
+ const content = [];
171
+ if (m.content)
172
+ content.push({ type: "text", text: m.content });
173
+ for (const call of m.toolCalls ?? []) {
174
+ names.set(call.id, call.name);
175
+ content.push({ type: "tool-call", toolCallId: call.id, toolName: call.name, input: call.input ?? {} });
176
+ }
177
+ out.push({ role: "assistant", content });
178
+ }
179
+ else {
180
+ const id = m.toolCallId ?? "";
181
+ const part = { type: "tool-result", toolCallId: id, toolName: names.get(id) ?? "", output: { type: m.isError ? "error-text" : "text", value: m.content } };
182
+ // Results of one assistant turn's calls go in one tool message, as the AI SDK expects.
183
+ const last = out.at(-1);
184
+ if (last?.role === "tool")
185
+ last.content.push(part);
186
+ else
187
+ out.push({ role: "tool", content: [part] });
188
+ }
189
+ }
190
+ return out;
191
+ }
192
+ function filePart(image, v2) {
193
+ const data = imageData(image);
194
+ if (v2)
195
+ return data ? { type: "file", data: data.base64, mediaType: data.mediaType } : { type: "file", data: new URL(image.url), mediaType: "image/*" };
196
+ return data
197
+ ? { type: "file", data: { type: "data", data: data.base64 }, mediaType: data.mediaType }
198
+ : { type: "file", data: { type: "url", url: new URL(image.url) }, mediaType: "image/*" };
199
+ }
200
+ /** Tool call arguments: v2 to v4 send them as a JSON string. */
201
+ function parseInput(input) {
202
+ if (typeof input !== "string")
203
+ return input ?? {};
204
+ if (!input.trim())
205
+ return {};
206
+ try {
207
+ return JSON.parse(input);
208
+ }
209
+ catch {
210
+ return input;
211
+ }
212
+ }
213
+ /** Usage of v2 ({ inputTokens: number }) and v3/v4 ({ inputTokens: { total } }). */
214
+ function usage(raw) {
215
+ const u = (raw ?? {});
216
+ const count = (value) => {
217
+ const n = typeof value === "object" && value !== null ? value.total : value;
218
+ return typeof n === "number" && Number.isFinite(n) ? n : 0;
219
+ };
220
+ return { inputTokens: count(u.inputTokens), outputTokens: count(u.outputTokens) };
221
+ }
222
+ /** AI SDK errors (APICallError has statusCode) as ProviderError, so fallback and IL5006 work as with other providers. */
223
+ function providerError(name, error) {
224
+ if (error instanceof InferloError)
225
+ return error;
226
+ if (error && typeof error === "object" && error.name === "AbortError")
227
+ return error;
228
+ const e = (error ?? {});
229
+ const status = typeof e.statusCode === "number" ? e.statusCode : 0;
230
+ const body = typeof e.responseBody === "string" && e.responseBody ? e.responseBody : String(e.message ?? error);
231
+ const wrapped = new ProviderError(name, status, body);
232
+ wrapped.cause = error;
233
+ return wrapped;
234
+ }
235
+ //# sourceMappingURL=ai-sdk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-sdk.js","sourceRoot":"","sources":["../../src/ai/ai-sdk.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,12 @@
1
1
  import { type AnySchema, type Infer } from "../schema.ts";
2
2
  import type { RouteDef } from "../route.ts";
3
3
  import { type ToolDef } from "./tool.ts";
4
- import { type Image, type Message, type Provider, type ProviderUsage, type ToolSpec } from "./providers.ts";
4
+ import { type TracingConfig } from "../tracing.ts";
5
+ import { type Image, type Message, type Provider, type ProviderUsage, type ToolCall, type ToolSpec } from "./providers.ts";
5
6
  export * from "./providers.ts";
6
7
  export { tool, isTool, ToolBuilder } from "./tool.ts";
7
8
  export type { ToolDef, FunctionToolOptions, ToolContext } from "./tool.ts";
9
+ export { uiChatBody, fromUIMessages, type UIChatMessage } from "./ui.ts";
8
10
  export interface Pricing {
9
11
  /** USD per million input tokens. */
10
12
  input: number;
@@ -44,6 +46,12 @@ export interface AIConfig {
44
46
  for: string;
45
47
  model: string;
46
48
  }) => boolean | Promise<boolean>;
49
+ /**
50
+ * OpenTelemetry spans for AI calls: import * as otel from "@opentelemetry/api", then tracing: { api: otel }.
51
+ * Every generate, stream and embed call gets a client span ("chat claude-haiku-4-5") with the provider, the model
52
+ * that answered, tokens and cost. Prompts and answers are never recorded. In an app, createApp({ tracing }) sets it.
53
+ */
54
+ tracing?: TracingConfig;
47
55
  }
48
56
  export interface GenerateOptions<O extends AnySchema | undefined> {
49
57
  /** Alias ("fast") or "provider:model". */
@@ -107,18 +115,51 @@ export type ToolRunner = (route: RouteDef, input: unknown) => Promise<{
107
115
  output: unknown;
108
116
  text: string;
109
117
  }>;
118
+ /** One model call that returns the tool calls instead of running them, for agent loops such as LangChain's. */
119
+ export interface ModelCallOptions {
120
+ model?: string;
121
+ messages: Message[];
122
+ tools?: ToolSpec[];
123
+ temperature?: number;
124
+ maxTokens?: number;
125
+ for?: string;
126
+ signal?: AbortSignal;
127
+ }
128
+ export interface ModelCallResult {
129
+ text: string;
130
+ toolCalls: ToolCall[];
131
+ usage: Usage;
132
+ }
133
+ /**
134
+ * One model call with the AI's aliases, fallback, budgets, usage tracking and tracing, which returns the tool calls
135
+ * the model asked for without running them. Internal: used by the LangChain integration.
136
+ */
137
+ export declare function callModel(ai: AI, options: ModelCallOptions): Promise<ModelCallResult>;
138
+ /** The route tools of ctx.ai (a request's AI client), or undefined for other clients. Internal. */
139
+ export declare function routeToolsOf(ai: AI): {
140
+ runner: ToolRunner;
141
+ describe: (route: RouteDef) => ToolSpec;
142
+ } | undefined;
110
143
  /**
111
144
  * ctx.ai for one request: the same AI, with tools that run as the request's user, and the request's signal
112
145
  * on every call that does not pass its own. Internal: used by createApp.
113
146
  */
114
147
  export declare function bindTools(ai: AI, runner: ToolRunner, describe: (route: RouteDef) => ToolSpec, signal?: AbortSignal): AI;
148
+ /** Options of StreamResult.toResponse: a ResponseInit (status, headers) and the stream format. */
149
+ export interface StreamResponseInit extends ResponseInit {
150
+ /** "sse" (default): Inferlo's text and done events. "ai-sdk": the AI SDK UI message stream protocol, for useChat. */
151
+ format?: "sse" | "ai-sdk";
152
+ }
115
153
  export interface StreamResult {
116
154
  /** Text chunks as they arrive. */
117
155
  [Symbol.asyncIterator](): AsyncIterator<string>;
118
156
  /** Full text once the stream finishes. */
119
157
  text(): Promise<string>;
120
- /** A server-sent events Response for browsers (events: "text", then "done" with usage). */
121
- toResponse(init?: ResponseInit): Response;
158
+ /**
159
+ * A server-sent events Response for browsers. The default format sends "text" events, then "done" with usage.
160
+ * format: "ai-sdk" speaks the AI SDK UI message stream protocol (v1), for useChat from @ai-sdk/react.
161
+ */
162
+ toResponse(init?: StreamResponseInit): Response;
122
163
  /** Usage once the stream finishes. */
123
164
  usage(): Promise<Usage>;
124
165
  }