@aparte/provider-ai-sdk 0.16.10 → 0.17.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.
package/dist/index.d.ts CHANGED
@@ -70,9 +70,9 @@ export interface AiSdkProviderOptions {
70
70
  configSchema?: AparteAIProviderConfigSchema;
71
71
  }
72
72
  /**
73
- * AparteChatMessage[] → AI SDK ModelMessage[]. Handles aparté's `tool_call` /
74
- * `tool_result` envelope (assistant tool-call parts + tool-role results); the
75
- * tool name for a result is recovered from the preceding envelope.
73
+ * AparteChatMessage[] → AI SDK ModelMessage[]. Handles a tool turn (an assistant
74
+ * message carrying `toolCalls`, then the `tool` messages answering them); the tool
75
+ * name for a result is the message's own `toolName`, else the call that declared it.
76
76
  */
77
77
  export declare function toModelMessages(messages: AparteChatMessage[]): ModelMessage[];
78
78
  /** AparteTool[] → AI SDK ToolSet — declaration only, NO `execute` (aparté's loop runs tools). */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,KAAK,EACR,gBAAgB,EAChB,aAAa,EACb,4BAA4B,EAC5B,iBAAiB,EAEjB,iBAAiB,EACjB,iBAAiB,EAEpB,MAAM,cAAc,CAAC;AAGtB,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAI3E,MAAM,WAAW,oBAAoB;IACjC,6EAA6E;IAC7E,EAAE,EAAE,MAAM,CAAC;IACX;;;;OAIG;IACH,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,aAAa,CAAC;IAC1F,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,4CAA4C;IAC5C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;IACzB,mDAAmD;IACnD,YAAY,CAAC,EAAE,4BAA4B,CAAC;CAC/C;AAID;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,YAAY,EAAE,CA6D7E;AAED,iGAAiG;AACjG,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAQjF;AAED,6FAA6F;AAC7F,wBAAgB,YAAY,CAAC,MAAM,EAAE,iBAAiB,CAAC,YAAY,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,SAAS,CAIrG;AAYD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACpC,UAAU,EAAE,aAAa,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACtE,cAAc,CAAC,iBAAiB,CAAC,CA0DnC;AAUD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,oBAAoB,GAAG,gBAAgB,CAiDhF;AAED,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,KAAK,EACR,gBAAgB,EAChB,aAAa,EACb,4BAA4B,EAC5B,iBAAiB,EAEjB,iBAAiB,EACjB,iBAAiB,EAEpB,MAAM,cAAc,CAAC;AAGtB,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAI3E,MAAM,WAAW,oBAAoB;IACjC,6EAA6E;IAC7E,EAAE,EAAE,MAAM,CAAC;IACX;;;;OAIG;IACH,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,aAAa,CAAC;IAC1F,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,4CAA4C;IAC5C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;IACzB,mDAAmD;IACnD,YAAY,CAAC,EAAE,4BAA4B,CAAC;CAC/C;AAwBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,YAAY,EAAE,CAyE7E;AAED,iGAAiG;AACjG,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAQjF;AAED,6FAA6F;AAC7F,wBAAgB,YAAY,CAAC,MAAM,EAAE,iBAAiB,CAAC,YAAY,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,SAAS,CAIrG;AAYD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACpC,UAAU,EAAE,aAAa,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACtE,cAAc,CAAC,iBAAiB,CAAC,CAoEnC;AAUD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,oBAAoB,GAAG,gBAAgB,CAiDhF;AAED,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -1,36 +1,35 @@
1
1
  import { contentToText } from "@aparte/core";
2
2
  import { tool, jsonSchema, streamText } from "ai";
3
+ const LEGACY_TOOL_ROLES = /* @__PURE__ */ new Set(["tool_call", "tool_result"]);
4
+ const warnedLegacyRoles = /* @__PURE__ */ new Set();
5
+ function warnLegacyToolRole(role) {
6
+ if (warnedLegacyRoles.has(role)) return;
7
+ warnedLegacyRoles.add(role);
8
+ console.warn(
9
+ `[@aparte/provider-ai-sdk] Skipping a message with the removed role "${role}". A tool turn is now an assistant message carrying its calls — { role: 'assistant', content: <what it said>, toolCalls } — followed by one { role: 'tool', content: <result>, toolCallId, toolName } per call. This warning is removed in 0.18.`
10
+ );
11
+ }
3
12
  function toModelMessages(messages) {
4
13
  const toolNames = /* @__PURE__ */ new Map();
5
14
  for (const msg of messages) {
6
- if (msg.role === "tool_call") {
15
+ if (msg.role === "assistant") {
7
16
  for (const tc of msg.toolCalls ?? []) toolNames.set(tc.id, tc.name);
8
17
  }
9
18
  }
10
19
  const out = [];
11
20
  for (const msg of messages) {
12
- if (msg.role === "tool_call") {
13
- out.push({
14
- role: "assistant",
15
- content: [
16
- ...msg.precedingText ? [{ type: "text", text: msg.precedingText }] : [],
17
- ...(msg.toolCalls ?? []).map((tc) => ({
18
- type: "tool-call",
19
- toolCallId: tc.id,
20
- toolName: tc.name,
21
- input: tc.input
22
- }))
23
- ]
24
- });
21
+ const role = msg.role;
22
+ if (LEGACY_TOOL_ROLES.has(role)) {
23
+ warnLegacyToolRole(role);
25
24
  continue;
26
25
  }
27
- if (msg.role === "tool_result") {
26
+ if (msg.role === "tool") {
28
27
  out.push({
29
28
  role: "tool",
30
29
  content: [{
31
30
  type: "tool-result",
32
31
  toolCallId: msg.toolCallId ?? "",
33
- toolName: toolNames.get(msg.toolCallId ?? "") ?? "unknown",
32
+ toolName: msg.toolName ?? toolNames.get(msg.toolCallId ?? "") ?? "unknown",
34
33
  output: { type: "text", value: contentToText(msg.content) }
35
34
  }]
36
35
  });
@@ -41,6 +40,25 @@ function toModelMessages(messages) {
41
40
  continue;
42
41
  }
43
42
  if (msg.role === "assistant") {
43
+ if (msg.toolCalls?.length) {
44
+ const text = contentToText(msg.content);
45
+ out.push({
46
+ role: "assistant",
47
+ content: [
48
+ // No empty text part: '' is what an assistant that said nothing
49
+ // before its calls now carries, and a part saying nothing is a
50
+ // part the model still reads.
51
+ ...text ? [{ type: "text", text }] : [],
52
+ ...msg.toolCalls.map((tc) => ({
53
+ type: "tool-call",
54
+ toolCallId: tc.id,
55
+ toolName: tc.name,
56
+ input: tc.input
57
+ }))
58
+ ]
59
+ });
60
+ continue;
61
+ }
44
62
  out.push({ role: "assistant", content: contentToText(msg.content) });
45
63
  continue;
46
64
  }
@@ -49,11 +67,10 @@ function toModelMessages(messages) {
49
67
  } else {
50
68
  out.push({
51
69
  role: "user",
52
- content: msg.content.map((p) => {
53
- if (p.type === "text") return { type: "text", text: p.text };
54
- if (p.type === "image") return { type: "image", image: p.image };
55
- return { type: "text", text: "" };
56
- })
70
+ // Two arms, exhaustive: a part is text or an image. A third used to answer
71
+ // the removed `AparteFilePart` with an empty text part a branch nothing
72
+ // could reach, standing in for a file bridge that was never written.
73
+ content: msg.content.map((p) => p.type === "text" ? { type: "text", text: p.text } : { type: "image", image: p.image })
57
74
  });
58
75
  }
59
76
  }
@@ -120,6 +137,10 @@ function fullStreamToAparteEvents(fullStream) {
120
137
  controller.enqueue({ type: "error", message: err?.message ?? "Stream error" });
121
138
  }
122
139
  } finally {
140
+ try {
141
+ await iterator?.return?.(void 0);
142
+ } catch {
143
+ }
123
144
  controller.close();
124
145
  }
125
146
  },
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * @aparte/provider-ai-sdk — bridge any Vercel AI SDK model into aparté.\n *\n * aparté's own wire concern is deliberately tiny: `@aparte/provider-openai-compat`\n * covers the one de-facto-standard format. EVERYTHING else (Anthropic, Google,\n * Bedrock, 25+ vendors) rides the AI SDK ecosystem through this bridge: you\n * bring your `@ai-sdk/*` package and hand its model to `createAiSdkProvider`;\n * the bridge runs `streamText` (single step — aparté's agent loop owns the\n * multi-turn) and maps `fullStream` parts to aparté's `AparteStreamEvent`s.\n *\n * ```ts\n * import { createAnthropic } from '@ai-sdk/anthropic';\n * import { createAiSdkProvider } from '@aparte/provider-ai-sdk';\n *\n * aparteGlobalConfig.registerAIProvider(createAiSdkProvider({\n * id: 'anthropic',\n * name: 'Anthropic',\n * models: [{ id: 'claude-sonnet-4-5', name: 'Claude Sonnet 4.5' }],\n * languageModel: (modelId, auth) =>\n * createAnthropic({\n * apiKey: typeof auth === 'string' ? auth : auth?.['apiKey'],\n * headers: { 'anthropic-dangerous-direct-browser-access': 'true' }, // BYOK\n * })(modelId),\n * }));\n * ```\n *\n * DEPENDENCY POLICY: `ai` is a **peerDependency pinned to the verified major**\n * (`^7`). The AI SDK moves fast (v5→v7 in about a year); this bridge is the\n * ONLY aparté module touching its types, so a breaking major costs one small\n * package bump — widened per-major after verification, never speculatively.\n *\n * The bridge is an `AparteAIProvider` with a `chat()` (it owns its I/O via the\n * SDK — same shape as `@aparte/provider-transformers`), driven by\n * `AparteDirectTransport`'s delegation branch, which forwards `ctx.signal` so a user\n * \"stop\" aborts the underlying vendor call.\n *\n * NOTE (loop contract): the bridge never sees `toolChoice: { name, input }` —\n * the agent loop (engine `runStreamAgent` / core `_streamLoop`) executes that\n * synthetic call itself and strips `toolChoice` before the transport call.\n * Only `'auto' | 'none' | { name }` reach this module.\n */\n\nimport type {\n AparteAIProvider,\n AparteAIModel,\n AparteAIProviderConfigSchema,\n AparteChatRequest,\n AparteChatResponse,\n AparteChatMessage,\n AparteStreamEvent,\n AparteUsage,\n} from '@aparte/core';\nimport { contentToText } from '@aparte/core';\nimport { streamText, jsonSchema, tool } from 'ai';\nimport type { LanguageModel, ModelMessage, ToolSet, ToolChoice } from 'ai';\n\n// ─── Options ─────────────────────────────────────────────────────────────────\n\nexport interface AiSdkProviderOptions {\n /** Provider id used across aparté (key resolution, model picker, events). */\n id: string;\n /**\n * Resolve the AI SDK model for a chat call. `auth` is the key/config the\n * aparté key-resolver produced — rebuild the vendor provider per call for\n * UI-driven BYOK, or ignore it if your factory already carries the key.\n */\n languageModel: (modelId: string, auth?: string | Record<string, string>) => LanguageModel;\n /** Display name (defaults to `id`). */\n name?: string;\n /** Brand icon (SVG string / data URI / icon-provider key). */\n icon?: string;\n /** Brand color. */\n color?: string;\n /** Short tag line. */\n description?: string;\n /** Where the user gets a key. */\n helpUrl?: string;\n /** Whether the vendor offers free models. */\n hasFreeModels?: boolean;\n /** Model runs locally (no key expected). */\n isLocal?: boolean;\n /** Model list — **consumer data** (the AI SDK has no model-listing API). */\n models?: AparteAIModel[];\n /** Override the default apiKey settings schema. */\n configSchema?: AparteAIProviderConfigSchema;\n}\n\n// ─── aparté ⇄ AI SDK shaping ─────────────────────────────────────────────────\n\n/**\n * AparteChatMessage[] → AI SDK ModelMessage[]. Handles aparté's `tool_call` /\n * `tool_result` envelope (assistant tool-call parts + tool-role results); the\n * tool name for a result is recovered from the preceding envelope.\n */\nexport function toModelMessages(messages: AparteChatMessage[]): ModelMessage[] {\n // toolCallId → toolName (results reference calls by id only).\n const toolNames = new Map<string, string>();\n for (const msg of messages) {\n if (msg.role === 'tool_call') {\n for (const tc of msg.toolCalls ?? []) toolNames.set(tc.id, tc.name);\n }\n }\n\n const out: ModelMessage[] = [];\n for (const msg of messages) {\n if (msg.role === 'tool_call') {\n out.push({\n role: 'assistant',\n content: [\n ...(msg.precedingText ? [{ type: 'text' as const, text: msg.precedingText }] : []),\n ...(msg.toolCalls ?? []).map(tc => ({\n type: 'tool-call' as const,\n toolCallId: tc.id,\n toolName: tc.name,\n input: tc.input,\n })),\n ],\n });\n continue;\n }\n if (msg.role === 'tool_result') {\n out.push({\n role: 'tool',\n content: [{\n type: 'tool-result',\n toolCallId: msg.toolCallId ?? '',\n toolName: toolNames.get(msg.toolCallId ?? '') ?? 'unknown',\n output: { type: 'text', value: contentToText(msg.content) },\n }],\n });\n continue;\n }\n if (msg.role === 'system') {\n out.push({ role: 'system', content: contentToText(msg.content) });\n continue;\n }\n if (msg.role === 'assistant') {\n out.push({ role: 'assistant', content: contentToText(msg.content) });\n continue;\n }\n // user (default) — keep multimodal parts.\n if (typeof msg.content === 'string') {\n out.push({ role: 'user', content: msg.content });\n } else {\n out.push({\n role: 'user',\n content: msg.content.map(p => {\n if (p.type === 'text') return { type: 'text' as const, text: p.text };\n if (p.type === 'image') return { type: 'image' as const, image: p.image };\n return { type: 'text' as const, text: '' }; // AparteFilePart — not bridged\n }),\n });\n }\n }\n return out;\n}\n\n/** AparteTool[] → AI SDK ToolSet — declaration only, NO `execute` (aparté's loop runs tools). */\nexport function toToolSet(tools: NonNullable<AparteChatRequest['tools']>): ToolSet {\n return Object.fromEntries(tools.map(t => [\n t.name,\n tool({\n description: t.description,\n inputSchema: jsonSchema(t.inputSchema as Parameters<typeof jsonSchema>[0]),\n }),\n ]));\n}\n\n/** aparté toolChoice → AI SDK toolChoice (the synthetic {name,input} never reaches here). */\nexport function toToolChoice(choice: AparteChatRequest['toolChoice']): ToolChoice<ToolSet> | undefined {\n if (choice === 'auto' || choice === 'none') return choice;\n if (choice && typeof choice === 'object') return { type: 'tool', toolName: choice.name };\n return undefined;\n}\n\n/** fullStream `finish.totalUsage` → AparteUsage. */\nfunction toAparteUsage(u: { inputTokens?: number; outputTokens?: number; totalTokens?: number; inputTokenDetails?: { cacheReadTokens?: number } }): AparteUsage {\n return {\n inputTokens: u.inputTokens ?? 0,\n outputTokens: u.outputTokens ?? 0,\n totalTokens: u.totalTokens,\n cacheReadTokens: u.inputTokenDetails?.cacheReadTokens,\n };\n}\n\n/**\n * Map the AI SDK `fullStream` to aparté's event stream:\n * `text-delta`→text · `reasoning-delta`→thinking · `tool-call`→tool_use ·\n * `finish`→done{usage} · `error`→error. Everything else (step markers,\n * tool-input deltas, sources, files) is dropped — aparté's loop consumes whole\n * tool calls, not input deltas.\n */\nexport function fullStreamToAparteEvents(\n fullStream: AsyncIterable<{ type: string } & Record<string, unknown>>,\n): ReadableStream<AparteStreamEvent> {\n // Held so `cancel()` can signal the AI SDK's iterator to stop (calling\n // `.return()` propagates cancellation the same way breaking a `for await`\n // loop would), instead of leaving `start()` draining `fullStream` to its\n // natural end after the consumer has already walked away.\n let iterator: AsyncIterator<{ type: string } & Record<string, unknown>> | undefined;\n\n return new ReadableStream<AparteStreamEvent>({\n async start(controller) {\n iterator = fullStream[Symbol.asyncIterator]();\n try {\n while (true) {\n const { value: part, done } = await iterator.next();\n if (done) break;\n\n switch (part.type) {\n case 'text-delta':\n controller.enqueue({ type: 'text', delta: part['text'] as string });\n break;\n case 'reasoning-delta':\n controller.enqueue({ type: 'thinking', delta: part['text'] as string });\n break;\n case 'tool-call':\n controller.enqueue({\n type: 'tool_use',\n id: part['toolCallId'] as string,\n name: part['toolName'] as string,\n input: (part['input'] ?? {}) as Record<string, unknown>,\n });\n break;\n case 'finish':\n controller.enqueue({ type: 'done', usage: toAparteUsage(part['totalUsage'] as Parameters<typeof toAparteUsage>[0]) });\n // Terminal: stop reading `fullStream` so a stray second\n // finish/error part (if the SDK ever emits one) can't\n // enqueue past the done event.\n return;\n case 'error': {\n const err = part['error'];\n controller.enqueue({ type: 'error', message: err instanceof Error ? err.message : String(err) });\n return;\n }\n // 'abort', step markers, tool-input-* deltas, sources… → dropped.\n }\n }\n } catch (err: unknown) {\n // AbortError surfaces here when ctx.signal fires mid-stream: the\n // consumer (agent loop) cancelled on purpose — end quietly.\n if ((err as { name?: string })?.name !== 'AbortError') {\n controller.enqueue({ type: 'error', message: (err as Error | undefined)?.message ?? 'Stream error' });\n }\n } finally {\n controller.close();\n }\n },\n async cancel(reason) {\n await iterator?.return?.(reason);\n },\n });\n}\n\n// ─── The provider factory ────────────────────────────────────────────────────\n\nconst DEFAULT_CONFIG_SCHEMA = (opts: AiSdkProviderOptions): AparteAIProviderConfigSchema => ({\n fields: opts.isLocal\n ? []\n : [{ id: 'apiKey', type: 'password', label: 'API Key', required: true }],\n});\n\n/**\n * Wrap an AI SDK model factory into an `AparteAIProvider`. The returned provider\n * owns its I/O through the SDK (`chat()` shape — `AparteDirectTransport` delegates\n * to it and forwards the abort signal).\n */\nexport function createAiSdkProvider(opts: AiSdkProviderOptions): AparteAIProvider {\n const displayName = opts.name ?? opts.id;\n\n return {\n id: opts.id,\n\n getMetadata() {\n return {\n id: opts.id,\n name: displayName,\n icon: opts.icon,\n color: opts.color,\n description: opts.description,\n helpUrl: opts.helpUrl,\n hasFreeModels: opts.hasFreeModels,\n isLocal: opts.isLocal,\n configSchema: opts.configSchema ?? DEFAULT_CONFIG_SCHEMA(opts),\n };\n },\n\n getModels(): AparteAIModel[] {\n return opts.models ?? [];\n },\n\n async chat(\n request: AparteChatRequest,\n auth?: string | Record<string, string>,\n ctx?: { providerId: string; signal?: AbortSignal },\n ): Promise<AparteChatResponse> {\n const model = opts.languageModel(request.modelId ?? '', auth);\n\n const result = streamText({\n model,\n messages: toModelMessages(request.messages),\n temperature: request.temperature,\n maxOutputTokens: request.maxTokens,\n seed: request.seed,\n abortSignal: ctx?.signal,\n ...(request.tools?.length\n ? { tools: toToolSet(request.tools), toolChoice: toToolChoice(request.toolChoice) ?? 'auto' }\n : {}),\n });\n\n if (request.stream === false) {\n return await result.text;\n }\n return fullStreamToAparteEvents(result.fullStream);\n },\n };\n}\n\nexport type { AparteAIProvider, AparteAIModel } from '@aparte/core';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * @aparte/provider-ai-sdk — bridge any Vercel AI SDK model into aparté.\n *\n * aparté's own wire concern is deliberately tiny: `@aparte/provider-openai-compat`\n * covers the one de-facto-standard format. EVERYTHING else (Anthropic, Google,\n * Bedrock, 25+ vendors) rides the AI SDK ecosystem through this bridge: you\n * bring your `@ai-sdk/*` package and hand its model to `createAiSdkProvider`;\n * the bridge runs `streamText` (single step — aparté's agent loop owns the\n * multi-turn) and maps `fullStream` parts to aparté's `AparteStreamEvent`s.\n *\n * ```ts\n * import { createAnthropic } from '@ai-sdk/anthropic';\n * import { createAiSdkProvider } from '@aparte/provider-ai-sdk';\n *\n * aparteGlobalConfig.registerAIProvider(createAiSdkProvider({\n * id: 'anthropic',\n * name: 'Anthropic',\n * models: [{ id: 'claude-sonnet-4-5', name: 'Claude Sonnet 4.5' }],\n * languageModel: (modelId, auth) =>\n * createAnthropic({\n * apiKey: typeof auth === 'string' ? auth : auth?.['apiKey'],\n * headers: { 'anthropic-dangerous-direct-browser-access': 'true' }, // BYOK\n * })(modelId),\n * }));\n * ```\n *\n * DEPENDENCY POLICY: `ai` is a **peerDependency pinned to the verified major**\n * (`^7`). The AI SDK moves fast (v5→v7 in about a year); this bridge is the\n * ONLY aparté module touching its types, so a breaking major costs one small\n * package bump — widened per-major after verification, never speculatively.\n *\n * The bridge is an `AparteAIProvider` with a `chat()` (it owns its I/O via the\n * SDK — same shape as `@aparte/provider-transformers`), driven by\n * `AparteDirectTransport`'s delegation branch, which forwards `ctx.signal` so a user\n * \"stop\" aborts the underlying vendor call.\n *\n * NOTE (loop contract): the bridge never sees `toolChoice: { name, input }` —\n * the agent loop (engine `runStreamAgent` / core `_streamLoop`) executes that\n * synthetic call itself and strips `toolChoice` before the transport call.\n * Only `'auto' | 'none' | { name }` reach this module.\n */\n\nimport type {\n AparteAIProvider,\n AparteAIModel,\n AparteAIProviderConfigSchema,\n AparteChatRequest,\n AparteChatResponse,\n AparteChatMessage,\n AparteStreamEvent,\n AparteUsage,\n} from '@aparte/core';\nimport { contentToText } from '@aparte/core';\nimport { streamText, jsonSchema, tool } from 'ai';\nimport type { LanguageModel, ModelMessage, ToolSet, ToolChoice } from 'ai';\n\n// ─── Options ─────────────────────────────────────────────────────────────────\n\nexport interface AiSdkProviderOptions {\n /** Provider id used across aparté (key resolution, model picker, events). */\n id: string;\n /**\n * Resolve the AI SDK model for a chat call. `auth` is the key/config the\n * aparté key-resolver produced — rebuild the vendor provider per call for\n * UI-driven BYOK, or ignore it if your factory already carries the key.\n */\n languageModel: (modelId: string, auth?: string | Record<string, string>) => LanguageModel;\n /** Display name (defaults to `id`). */\n name?: string;\n /** Brand icon (SVG string / data URI / icon-provider key). */\n icon?: string;\n /** Brand color. */\n color?: string;\n /** Short tag line. */\n description?: string;\n /** Where the user gets a key. */\n helpUrl?: string;\n /** Whether the vendor offers free models. */\n hasFreeModels?: boolean;\n /** Model runs locally (no key expected). */\n isLocal?: boolean;\n /** Model list — **consumer data** (the AI SDK has no model-listing API). */\n models?: AparteAIModel[];\n /** Override the default apiKey settings schema. */\n configSchema?: AparteAIProviderConfigSchema;\n}\n\n// ─── aparté ⇄ AI SDK shaping ─────────────────────────────────────────────────\n\n/**\n * The two roles a tool turn used to wear. `AparteChatMessage` no longer allows either, so\n * the comparison is on the role as a string: a message carrying one comes from code built\n * against an older aparté, which no type here can catch. Warned once per role, then\n * skipped — the fallthrough below maps anything unrecognised as a `user` turn, so without\n * this the model would read a tool result as something the person typed.\n */\nconst LEGACY_TOOL_ROLES = new Set(['tool_call', 'tool_result']);\nconst warnedLegacyRoles = new Set<string>();\nfunction warnLegacyToolRole(role: string): void {\n if (warnedLegacyRoles.has(role)) return;\n warnedLegacyRoles.add(role);\n console.warn(\n `[@aparte/provider-ai-sdk] Skipping a message with the removed role \"${role}\".`\n + \" A tool turn is now an assistant message carrying its calls — { role: 'assistant',\"\n + \" content: <what it said>, toolCalls } — followed by one { role: 'tool', content:\"\n + ' <result>, toolCallId, toolName } per call. This warning is removed in 0.18.',\n );\n}\n\n/**\n * AparteChatMessage[] → AI SDK ModelMessage[]. Handles a tool turn (an assistant\n * message carrying `toolCalls`, then the `tool` messages answering them); the tool\n * name for a result is the message's own `toolName`, else the call that declared it.\n */\nexport function toModelMessages(messages: AparteChatMessage[]): ModelMessage[] {\n // toolCallId → toolName, the FALLBACK for a `tool` message that names no tool of\n // its own. A hand-built history need carry no assistant turn to scan, which is\n // where the name used to become 'unknown'.\n const toolNames = new Map<string, string>();\n for (const msg of messages) {\n if (msg.role === 'assistant') {\n for (const tc of msg.toolCalls ?? []) toolNames.set(tc.id, tc.name);\n }\n }\n\n const out: ModelMessage[] = [];\n for (const msg of messages) {\n const role: string = msg.role;\n if (LEGACY_TOOL_ROLES.has(role)) {\n warnLegacyToolRole(role);\n continue;\n }\n if (msg.role === 'tool') {\n out.push({\n role: 'tool',\n content: [{\n type: 'tool-result',\n toolCallId: msg.toolCallId ?? '',\n toolName: msg.toolName ?? toolNames.get(msg.toolCallId ?? '') ?? 'unknown',\n output: { type: 'text', value: contentToText(msg.content) },\n }],\n });\n continue;\n }\n if (msg.role === 'system') {\n out.push({ role: 'system', content: contentToText(msg.content) });\n continue;\n }\n if (msg.role === 'assistant') {\n if (msg.toolCalls?.length) {\n const text = contentToText(msg.content);\n out.push({\n role: 'assistant',\n content: [\n // No empty text part: '' is what an assistant that said nothing\n // before its calls now carries, and a part saying nothing is a\n // part the model still reads.\n ...(text ? [{ type: 'text' as const, text }] : []),\n ...msg.toolCalls.map(tc => ({\n type: 'tool-call' as const,\n toolCallId: tc.id,\n toolName: tc.name,\n input: tc.input,\n })),\n ],\n });\n continue;\n }\n out.push({ role: 'assistant', content: contentToText(msg.content) });\n continue;\n }\n // user (default) — keep multimodal parts.\n if (typeof msg.content === 'string') {\n out.push({ role: 'user', content: msg.content });\n } else {\n out.push({\n role: 'user',\n // Two arms, exhaustive: a part is text or an image. A third used to answer\n // the removed `AparteFilePart` with an empty text part — a branch nothing\n // could reach, standing in for a file bridge that was never written.\n content: msg.content.map(p => (p.type === 'text'\n ? { type: 'text' as const, text: p.text }\n : { type: 'image' as const, image: p.image })),\n });\n }\n }\n return out;\n}\n\n/** AparteTool[] → AI SDK ToolSet — declaration only, NO `execute` (aparté's loop runs tools). */\nexport function toToolSet(tools: NonNullable<AparteChatRequest['tools']>): ToolSet {\n return Object.fromEntries(tools.map(t => [\n t.name,\n tool({\n description: t.description,\n inputSchema: jsonSchema(t.inputSchema as Parameters<typeof jsonSchema>[0]),\n }),\n ]));\n}\n\n/** aparté toolChoice → AI SDK toolChoice (the synthetic {name,input} never reaches here). */\nexport function toToolChoice(choice: AparteChatRequest['toolChoice']): ToolChoice<ToolSet> | undefined {\n if (choice === 'auto' || choice === 'none') return choice;\n if (choice && typeof choice === 'object') return { type: 'tool', toolName: choice.name };\n return undefined;\n}\n\n/** fullStream `finish.totalUsage` → AparteUsage. */\nfunction toAparteUsage(u: { inputTokens?: number; outputTokens?: number; totalTokens?: number; inputTokenDetails?: { cacheReadTokens?: number } }): AparteUsage {\n return {\n inputTokens: u.inputTokens ?? 0,\n outputTokens: u.outputTokens ?? 0,\n totalTokens: u.totalTokens,\n cacheReadTokens: u.inputTokenDetails?.cacheReadTokens,\n };\n}\n\n/**\n * Map the AI SDK `fullStream` to aparté's event stream:\n * `text-delta`→text · `reasoning-delta`→thinking · `tool-call`→tool_use ·\n * `finish`→done{usage} · `error`→error. Everything else (step markers,\n * tool-input deltas, sources, files) is dropped — aparté's loop consumes whole\n * tool calls, not input deltas.\n */\nexport function fullStreamToAparteEvents(\n fullStream: AsyncIterable<{ type: string } & Record<string, unknown>>,\n): ReadableStream<AparteStreamEvent> {\n // Held so `cancel()` can signal the AI SDK's iterator to stop (calling\n // `.return()` propagates cancellation the same way breaking a `for await`\n // loop would), instead of leaving `start()` draining `fullStream` to its\n // natural end after the consumer has already walked away.\n let iterator: AsyncIterator<{ type: string } & Record<string, unknown>> | undefined;\n\n return new ReadableStream<AparteStreamEvent>({\n async start(controller) {\n iterator = fullStream[Symbol.asyncIterator]();\n try {\n while (true) {\n const { value: part, done } = await iterator.next();\n if (done) break;\n\n switch (part.type) {\n case 'text-delta':\n controller.enqueue({ type: 'text', delta: part['text'] as string });\n break;\n case 'reasoning-delta':\n controller.enqueue({ type: 'thinking', delta: part['text'] as string });\n break;\n case 'tool-call':\n controller.enqueue({\n type: 'tool_use',\n id: part['toolCallId'] as string,\n name: part['toolName'] as string,\n input: (part['input'] ?? {}) as Record<string, unknown>,\n });\n break;\n case 'finish':\n controller.enqueue({ type: 'done', usage: toAparteUsage(part['totalUsage'] as Parameters<typeof toAparteUsage>[0]) });\n // Terminal: stop reading `fullStream` so a stray second\n // finish/error part (if the SDK ever emits one) can't\n // enqueue past the done event.\n return;\n case 'error': {\n const err = part['error'];\n controller.enqueue({ type: 'error', message: err instanceof Error ? err.message : String(err) });\n return;\n }\n // 'abort', step markers, tool-input-* deltas, sources… → dropped.\n }\n }\n } catch (err: unknown) {\n // AbortError surfaces here when ctx.signal fires mid-stream: the\n // consumer (agent loop) cancelled on purpose — end quietly.\n if ((err as { name?: string })?.name !== 'AbortError') {\n controller.enqueue({ type: 'error', message: (err as Error | undefined)?.message ?? 'Stream error' });\n }\n } finally {\n /*\n * Told to stop on EVERY exit, not only when the consumer cancels: the\n * `finish` and `error` branches `return` straight out of the loop, so\n * they used to reach this `finally` having said nothing to the SDK —\n * after an error part the vendor call was left to drain on its own,\n * which is the very thing `cancel()` exists to prevent. Best effort:\n * an iterator that objects to being settled must not become the\n * stream's error.\n */\n try { await iterator?.return?.(undefined); } catch { /* best effort */ }\n controller.close();\n }\n },\n async cancel(reason) {\n await iterator?.return?.(reason);\n },\n });\n}\n\n// ─── The provider factory ────────────────────────────────────────────────────\n\nconst DEFAULT_CONFIG_SCHEMA = (opts: AiSdkProviderOptions): AparteAIProviderConfigSchema => ({\n fields: opts.isLocal\n ? []\n : [{ id: 'apiKey', type: 'password', label: 'API Key', required: true }],\n});\n\n/**\n * Wrap an AI SDK model factory into an `AparteAIProvider`. The returned provider\n * owns its I/O through the SDK (`chat()` shape — `AparteDirectTransport` delegates\n * to it and forwards the abort signal).\n */\nexport function createAiSdkProvider(opts: AiSdkProviderOptions): AparteAIProvider {\n const displayName = opts.name ?? opts.id;\n\n return {\n id: opts.id,\n\n getMetadata() {\n return {\n id: opts.id,\n name: displayName,\n icon: opts.icon,\n color: opts.color,\n description: opts.description,\n helpUrl: opts.helpUrl,\n hasFreeModels: opts.hasFreeModels,\n isLocal: opts.isLocal,\n configSchema: opts.configSchema ?? DEFAULT_CONFIG_SCHEMA(opts),\n };\n },\n\n getModels(): AparteAIModel[] {\n return opts.models ?? [];\n },\n\n async chat(\n request: AparteChatRequest,\n auth?: string | Record<string, string>,\n ctx?: { providerId: string; signal?: AbortSignal },\n ): Promise<AparteChatResponse> {\n const model = opts.languageModel(request.modelId ?? '', auth);\n\n const result = streamText({\n model,\n messages: toModelMessages(request.messages),\n temperature: request.temperature,\n maxOutputTokens: request.maxTokens,\n seed: request.seed,\n abortSignal: ctx?.signal,\n ...(request.tools?.length\n ? { tools: toToolSet(request.tools), toolChoice: toToolChoice(request.toolChoice) ?? 'auto' }\n : {}),\n });\n\n if (request.stream === false) {\n return await result.text;\n }\n return fullStreamToAparteEvents(result.fullStream);\n },\n };\n}\n\nexport type { AparteAIProvider, AparteAIModel } from '@aparte/core';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aparte/provider-ai-sdk",
3
- "version": "0.16.10",
3
+ "version": "0.17.0",
4
4
  "homepage": "https://apartejs.dev/providers/ai/ai-sdk/",
5
5
  "description": "Bridge any Vercel AI SDK model into aparté — bring your own @ai-sdk/* package (Anthropic, Google, OpenAI, 25+ vendors) and aparté renders it.",
6
6
  "type": "module",
@@ -25,7 +25,7 @@
25
25
  "node": ">=18"
26
26
  },
27
27
  "peerDependencies": {
28
- "@aparte/core": ">=0.16.10 <1.0.0",
28
+ "@aparte/core": ">=0.17.0 <1.0.0",
29
29
  "ai": "^7.0.0"
30
30
  },
31
31
  "devDependencies": {
@@ -35,7 +35,7 @@
35
35
  "typescript": "^5.4.0",
36
36
  "vite": "^6.0.0",
37
37
  "zod": "^4.1.8",
38
- "@aparte/core": "0.16.10"
38
+ "@aparte/core": "0.17.0"
39
39
  },
40
40
  "keywords": [
41
41
  "ai",