@jigs.design/ai-sdk 0.3.3 → 0.3.5

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.
@@ -0,0 +1,46 @@
1
+ import { JigsErrorCode, JsonValue, MutationResult } from "@jigs.design/protocol";
2
+ //#region src/changes.d.ts
3
+ /**
4
+ * What the user changed in a jig since the model's last reply: a
5
+ * `data-jigs-change` part on their next message, which `jigsChat`'s
6
+ * `convertDataPart` writes as one sentence for the model.
7
+ */
8
+ export interface JigsChange {
9
+ /** How many calls it stands for: `addJigsChange` keeps the latest of a run. */
10
+ count: number;
11
+ /** Why the last call failed, `DECLINED` when the user said no; null on a success. */
12
+ error: JigsErrorCode | null;
13
+ /** What the last call passed, as JSON. */
14
+ input: JsonValue;
15
+ /** The block's key, `id@version`. */
16
+ key: string;
17
+ /** The mutation. */
18
+ name: string;
19
+ }
20
+ /**
21
+ * `changes` with one more settled mutation from the block `key`, as
22
+ * `JigsView`'s `onMutation` gives it. It replaces an earlier change to the
23
+ * same block, mutation and input once its number fields are left out, and
24
+ * counts it, so a field that mutates on every change sends one line. At
25
+ * most the latest ten are kept.
26
+ */
27
+ export declare function addJigsChange(changes: ReadonlyArray<JigsChange>, key: string, mutation: {
28
+ input: unknown;
29
+ name: string;
30
+ result: MutationResult;
31
+ }): Array<JigsChange>;
32
+ /**
33
+ * A change as the model reads it: one sentence for the user's message,
34
+ * before their text. `jigsChat`'s `convertDataPart` writes each
35
+ * `data-jigs-change` part with it; a chat on another stack can call it.
36
+ */
37
+ export declare function jigsChangeText(change: JigsChange): string;
38
+ /**
39
+ * The parts to send `changes` with, before the message's text:
40
+ * `sendMessage({ parts: [...jigsChangeParts(changes), { text, type: "text" }] })`.
41
+ */
42
+ export declare function jigsChangeParts(changes: ReadonlyArray<JigsChange>): Array<{
43
+ data: JigsChange;
44
+ type: "data-jigs-change";
45
+ }>;
46
+ //#endregion
@@ -0,0 +1,72 @@
1
+ //#region src/changes.ts
2
+ function isObject(value) {
3
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4
+ }
5
+ function isNumber(value) {
6
+ return typeof value === "number";
7
+ }
8
+ /**
9
+ * What makes two calls the same change: the input with its number fields
10
+ * left out, so a field stepped from 300 to 340 is one change and another
11
+ * category or row is its own.
12
+ */
13
+ function identity(input) {
14
+ if (isNumber(input)) return "";
15
+ if (!isObject(input)) return JSON.stringify(input);
16
+ return JSON.stringify(Object.keys(input).toSorted().flatMap((name) => {
17
+ const value = input[name];
18
+ return value === void 0 || isNumber(value) ? [] : [[name, value]];
19
+ }));
20
+ }
21
+ /**
22
+ * `changes` with one more settled mutation from the block `key`, as
23
+ * `JigsView`'s `onMutation` gives it. It replaces an earlier change to the
24
+ * same block, mutation and input once its number fields are left out, and
25
+ * counts it, so a field that mutates on every change sends one line. At
26
+ * most the latest ten are kept.
27
+ */
28
+ function addJigsChange(changes, key, mutation) {
29
+ let input = null;
30
+ try {
31
+ const text = JSON.stringify(mutation.input ?? null);
32
+ if (text !== void 0) input = JSON.parse(text);
33
+ } catch {
34
+ input = null;
35
+ }
36
+ const same = (change) => change.key === key && change.name === mutation.name && identity(change.input) === identity(input);
37
+ const change = {
38
+ count: (changes.find(same)?.count ?? 0) + 1,
39
+ error: mutation.result.status === "success" ? null : mutation.result.error.code,
40
+ input,
41
+ key,
42
+ name: mutation.name
43
+ };
44
+ return [...changes.filter((entry) => !same(entry)), change].slice(-10);
45
+ }
46
+ /** The most of a change's input the model reads, in characters of JSON. */
47
+ const MAX_CHANGE_INPUT_CHARS = 500;
48
+ /**
49
+ * A change as the model reads it: one sentence for the user's message,
50
+ * before their text. `jigsChat`'s `convertDataPart` writes each
51
+ * `data-jigs-change` part with it; a chat on another stack can call it.
52
+ */
53
+ function jigsChangeText(change) {
54
+ const json = JSON.stringify(change.input);
55
+ const input = json.length > MAX_CHANGE_INPUT_CHARS ? `${json.slice(0, MAX_CHANGE_INPUT_CHARS)}… (cut at ${MAX_CHANGE_INPUT_CHARS} characters)` : json;
56
+ const ran = change.count > 1 ? `ran \`${change.name}\` ${change.count} times, the last with ${input}` : `ran \`${change.name}\` with ${input}`;
57
+ const call = change.count > 1 ? "the last call" : "it";
58
+ const outcome = change.error === null ? `${call} succeeded` : change.error === "DECLINED" ? `they declined ${call} when asked to confirm` : `${call} failed with ${change.error}`;
59
+ return `Since your last reply, in the \`${change.key}\` UI the user ${ran}: ${outcome}.`;
60
+ }
61
+ /**
62
+ * The parts to send `changes` with, before the message's text:
63
+ * `sendMessage({ parts: [...jigsChangeParts(changes), { text, type: "text" }] })`.
64
+ */
65
+ function jigsChangeParts(changes) {
66
+ return changes.map((data) => ({
67
+ data,
68
+ type: "data-jigs-change"
69
+ }));
70
+ }
71
+ //#endregion
72
+ export { addJigsChange, jigsChangeParts, jigsChangeText };
package/dist/chat.d.ts CHANGED
@@ -5,7 +5,8 @@ import { InferUIMessageChunk, UIMessage, UIMessageChunk } from "ai";
5
5
  export interface JigsChat {
6
6
  /**
7
7
  * For `convertToModelMessages(messages, { convertDataPart })`: writes each
8
- * jigs back as the fenced block the model wrote, so it sees its UIs.
8
+ * jigs back as the fenced block the model wrote, so it sees its UIs, and
9
+ * each `data-jigs-change` as one sentence saying what the user changed.
9
10
  * Returns `undefined` for other data parts; chain your own after it.
10
11
  */
11
12
  convertDataPart: (part: {
package/dist/chat.js CHANGED
@@ -1,4 +1,5 @@
1
- import { storedBlock } from "./schemas.js";
1
+ import { jigsChangeText } from "./changes.js";
2
+ import { storedBlock, storedChange } from "./schemas.js";
2
3
  import { chatBlockText } from "@jigs.design/server";
3
4
  import { z } from "zod";
4
5
  //#region src/chat.ts
@@ -40,6 +41,13 @@ async function jigsChat(jigs, input) {
40
41
  });
41
42
  return {
42
43
  convertDataPart: (part) => {
44
+ if (part.type === "data-jigs-change") {
45
+ const change = storedChange.safeParse(part.data);
46
+ return change.success ? {
47
+ text: jigsChangeText(change.data),
48
+ type: "text"
49
+ } : void 0;
50
+ }
43
51
  if (part.type !== "data-jigs") return;
44
52
  const parsed = blockSource.safeParse(part.data);
45
53
  return parsed.success ? {
package/dist/client.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { JigsChange, addJigsChange, jigsChangeParts, jigsChangeText } from "./changes.js";
1
2
  import { JigsBlockData, JigsDataTypes, JigsUIMessage, StoredJigsBlock, StoredJigsUIMessage, recentMessages, withoutPrograms } from "./stored.js";
2
3
  import { ToolDataOptions, ToolPart, toolData, toolValue } from "./tool-data.js";
3
- export { type JigsBlockData, type JigsDataTypes, type JigsUIMessage, type StoredJigsBlock, type StoredJigsUIMessage, type ToolDataOptions, type ToolPart, recentMessages, toolData, toolValue, withoutPrograms };
4
+ export { type JigsBlockData, type JigsChange, type JigsDataTypes, type JigsUIMessage, type StoredJigsBlock, type StoredJigsUIMessage, type ToolDataOptions, type ToolPart, addJigsChange, jigsChangeParts, jigsChangeText, recentMessages, toolData, toolValue, withoutPrograms };
package/dist/client.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { addJigsChange, jigsChangeParts, jigsChangeText } from "./changes.js";
1
2
  import { recentMessages, withoutPrograms } from "./stored.js";
2
3
  import { toolData, toolValue } from "./tool-data.js";
3
- export { recentMessages, toolData, toolValue, withoutPrograms };
4
+ export { addJigsChange, jigsChangeParts, jigsChangeText, recentMessages, toolData, toolValue, withoutPrograms };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
+ import { JigsChange, addJigsChange, jigsChangeParts, jigsChangeText } from "./changes.js";
1
2
  import { JigsBlockData, JigsDataTypes, JigsUIMessage, StoredJigsBlock, StoredJigsUIMessage, recentMessages, withoutPrograms } from "./stored.js";
2
3
  import { ToolDataOptions, ToolPart, toolData, toolValue } from "./tool-data.js";
3
4
  import { JigsChat, jigsChat, reviveJigs } from "./chat.js";
4
5
  import { ModelSettings, aiSdkModel, cachedInstructions } from "./model.js";
5
6
  import { jigsDataSchemas } from "./schemas.js";
6
- export { type JigsBlockData, type JigsChat, type JigsDataTypes, type JigsUIMessage, type ModelSettings, type StoredJigsBlock, type StoredJigsUIMessage, type ToolDataOptions, type ToolPart, aiSdkModel, cachedInstructions, jigsChat, jigsDataSchemas, recentMessages, reviveJigs, toolData, toolValue, withoutPrograms };
7
+ export { type JigsBlockData, type JigsChange, type JigsChat, type JigsDataTypes, type JigsUIMessage, type ModelSettings, type StoredJigsBlock, type StoredJigsUIMessage, type ToolDataOptions, type ToolPart, addJigsChange, aiSdkModel, cachedInstructions, jigsChangeParts, jigsChangeText, jigsChat, jigsDataSchemas, recentMessages, reviveJigs, toolData, toolValue, withoutPrograms };
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
+ import { addJigsChange, jigsChangeParts, jigsChangeText } from "./changes.js";
1
2
  import { jigsDataSchemas } from "./schemas.js";
2
3
  import { jigsChat, reviveJigs } from "./chat.js";
3
4
  import { aiSdkModel, cachedInstructions } from "./model.js";
4
5
  import { recentMessages, withoutPrograms } from "./stored.js";
5
6
  import { toolData, toolValue } from "./tool-data.js";
6
- export { aiSdkModel, cachedInstructions, jigsChat, jigsDataSchemas, recentMessages, reviveJigs, toolData, toolValue, withoutPrograms };
7
+ export { addJigsChange, aiSdkModel, cachedInstructions, jigsChangeParts, jigsChangeText, jigsChat, jigsDataSchemas, recentMessages, reviveJigs, toolData, toolValue, withoutPrograms };
package/dist/model.d.ts CHANGED
@@ -4,18 +4,22 @@ import { Instructions, LanguageModel, streamText } from "ai";
4
4
  /** `streamText` settings that apply to every call, such as `temperature`. */
5
5
  export type ModelSettings = Omit<Parameters<typeof streamText>[0], "abortSignal" | "instructions" | "messages" | "model" | "prompt" | "system">;
6
6
  /**
7
- * `system` as instructions whose first part, `prefix`, a provider may cache:
8
- * two system messages, the first marked as a cache breakpoint for providers
9
- * that need one (Anthropic). Providers that cache a repeated prefix on their
10
- * own (OpenAI, DeepSeek, Google) read the two as one. Without a prefix that
11
- * `system` starts with, `system` alone.
7
+ * `system` as instructions a provider may cache: two system messages, its
8
+ * first part `prefix` and the rest, each marked as a cache breakpoint for
9
+ * providers that need one (Anthropic). The first mark keeps the prefix
10
+ * cached when the rest changes; the second caches the rest too while it
11
+ * does not, as it does not for a host whose procedures and instructions
12
+ * are fixed, so a turn reads the whole prompt from the cache. Two of
13
+ * Anthropic's four breakpoints. Providers that cache a repeated prefix on
14
+ * their own (OpenAI, DeepSeek, Google) read the two as one. Without a
15
+ * prefix that `system` starts with, `system` alone.
12
16
  */
13
17
  export declare function cachedInstructions(system: string, prefix: string): Instructions;
14
18
  /**
15
19
  * A `model` for `withModel` from an AI SDK model: document-mode
16
20
  * sessions and chat repairs stream through `streamText`, and token usage
17
- * reaches `onTurn`. The prompt's stable start is marked for the provider's
18
- * cache (`cachedInstructions`).
21
+ * reaches `onTurn`. The prompt's stable start and its end are marked for
22
+ * the provider's cache (`cachedInstructions`).
19
23
  */
20
24
  export declare function aiSdkModel(model: LanguageModel, settings?: ModelSettings): ModelFunction<unknown, unknown>;
21
25
  //#endregion
package/dist/model.js CHANGED
@@ -1,28 +1,32 @@
1
1
  import { streamText } from "ai";
2
2
  //#region src/model.ts
3
+ /** A system message marked as an Anthropic cache breakpoint. */
4
+ const cachedMessage = (content) => ({
5
+ content,
6
+ providerOptions: { anthropic: { cacheControl: { type: "ephemeral" } } },
7
+ role: "system"
8
+ });
3
9
  /**
4
- * `system` as instructions whose first part, `prefix`, a provider may cache:
5
- * two system messages, the first marked as a cache breakpoint for providers
6
- * that need one (Anthropic). Providers that cache a repeated prefix on their
7
- * own (OpenAI, DeepSeek, Google) read the two as one. Without a prefix that
8
- * `system` starts with, `system` alone.
10
+ * `system` as instructions a provider may cache: two system messages, its
11
+ * first part `prefix` and the rest, each marked as a cache breakpoint for
12
+ * providers that need one (Anthropic). The first mark keeps the prefix
13
+ * cached when the rest changes; the second caches the rest too while it
14
+ * does not, as it does not for a host whose procedures and instructions
15
+ * are fixed, so a turn reads the whole prompt from the cache. Two of
16
+ * Anthropic's four breakpoints. Providers that cache a repeated prefix on
17
+ * their own (OpenAI, DeepSeek, Google) read the two as one. Without a
18
+ * prefix that `system` starts with, `system` alone.
9
19
  */
10
20
  function cachedInstructions(system, prefix) {
11
21
  if (prefix === "" || !system.startsWith(prefix)) return system;
12
- return [{
13
- content: prefix,
14
- providerOptions: { anthropic: { cacheControl: { type: "ephemeral" } } },
15
- role: "system"
16
- }, {
17
- content: system.slice(prefix.length),
18
- role: "system"
19
- }];
22
+ const rest = system.slice(prefix.length);
23
+ return rest === "" ? [cachedMessage(prefix)] : [cachedMessage(prefix), cachedMessage(rest)];
20
24
  }
21
25
  /**
22
26
  * A `model` for `withModel` from an AI SDK model: document-mode
23
27
  * sessions and chat repairs stream through `streamText`, and token usage
24
- * reaches `onTurn`. The prompt's stable start is marked for the provider's
25
- * cache (`cachedInstructions`).
28
+ * reaches `onTurn`. The prompt's stable start and its end are marked for
29
+ * the provider's cache (`cachedInstructions`).
26
30
  */
27
31
  function aiSdkModel(model, settings = {}) {
28
32
  return async function* (request) {
package/dist/schemas.d.ts CHANGED
@@ -66,5 +66,24 @@ export declare const jigsDataSchemas: {
66
66
  toolKeys: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodLiteral<"all">]>>;
67
67
  version: z.ZodNumber;
68
68
  }, z.core.$strip>;
69
+ "jigs-change": z.ZodObject<{
70
+ count: z.ZodNumber;
71
+ error: z.ZodNullable<z.ZodEnum<{
72
+ BAD_INPUT: "BAD_INPUT";
73
+ CONFLICT: "CONFLICT";
74
+ DECLINED: "DECLINED";
75
+ FORBIDDEN: "FORBIDDEN";
76
+ INTERNAL: "INTERNAL";
77
+ NETWORK: "NETWORK";
78
+ NOT_FOUND: "NOT_FOUND";
79
+ RATE_LIMITED: "RATE_LIMITED";
80
+ UNAUTHORIZED: "UNAUTHORIZED";
81
+ UNAVAILABLE: "UNAVAILABLE";
82
+ UNKNOWN_PROCEDURE: "UNKNOWN_PROCEDURE";
83
+ }>>;
84
+ input: z.ZodJSONSchema;
85
+ key: z.ZodString;
86
+ name: z.ZodString;
87
+ }, z.core.$strip>;
69
88
  };
70
89
  //#endregion
package/dist/schemas.js CHANGED
@@ -44,12 +44,23 @@ const storedBlock = z.object({
44
44
  toolKeys: z.union([z.array(z.string()), z.literal("all")]).exactOptional(),
45
45
  version: z.number()
46
46
  });
47
+ /** A `data-jigs-change` part: what the user changed in a jig. */
48
+ const storedChange = z.object({
49
+ count: z.number().int().min(1),
50
+ error: z.enum(jigsErrorCodes).nullable(),
51
+ input: z.json(),
52
+ key: z.string(),
53
+ name: z.string()
54
+ });
47
55
  /**
48
56
  * Schemas for `validateUIMessages<StoredJigsUIMessage>({ messages,
49
57
  * dataSchemas })`, to check a conversation the browser sent or one read
50
58
  * from storage. A jig's program is dropped, never checked: the server
51
59
  * reads only `name` and `source`, and a source is only ever compiled.
52
60
  */
53
- const jigsDataSchemas = { jigs: storedBlock };
61
+ const jigsDataSchemas = {
62
+ jigs: storedBlock,
63
+ "jigs-change": storedChange
64
+ };
54
65
  //#endregion
55
- export { jigsDataSchemas, storedBlock };
66
+ export { jigsDataSchemas, storedBlock, storedChange };
package/dist/stored.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { JigsChange } from "./changes.js";
1
2
  import { ChatBlock } from "@jigs.design/protocol";
2
3
  import { UIMessage } from "ai";
3
4
  //#region src/stored.d.ts
@@ -10,11 +11,13 @@ export type JigsBlockData = ChatBlock;
10
11
  */
11
12
  export type StoredJigsBlock = Omit<JigsBlockData, "program">;
12
13
  /**
13
- * The data parts chat mode adds to a message. A type, not an interface: the
14
- * AI SDK's data types need an implicit index signature.
14
+ * The data parts chat mode adds to a message: jigs on a reply, and what the
15
+ * user changed in them on the next user message. A type, not an interface:
16
+ * the AI SDK's data types need an implicit index signature.
15
17
  */
16
18
  export type JigsDataTypes = {
17
19
  jigs: JigsBlockData;
20
+ "jigs-change": JigsChange;
18
21
  };
19
22
  /** A `useChat` message whose replies may hold jigs. */
20
23
  export type JigsUIMessage<TMetadata = unknown> = UIMessage<TMetadata, JigsDataTypes>;
@@ -25,6 +28,7 @@ export type JigsUIMessage<TMetadata = unknown> = UIMessage<TMetadata, JigsDataTy
25
28
  */
26
29
  export type StoredJigsUIMessage<TMetadata = unknown> = UIMessage<TMetadata, {
27
30
  jigs: StoredJigsBlock;
31
+ "jigs-change": JigsChange;
28
32
  }>;
29
33
  /** A message part, with a `data-jigs` part's data replaced by `TBlock`. */
30
34
  type WithBlock<TPart, TBlock> = TPart extends {
@@ -37,7 +37,9 @@ export interface ToolDataOptions {
37
37
  * reply that wrote it; else its previous version's value; else the latest
38
38
  * value earlier in the conversation. A failed or refused call in that reply
39
39
  * removes the tool's entry, so the block shows its empty state rather than
40
- * an older result. A tool called twice in one step leaves the last result.
40
+ * an older result. Each call is also under its number among that tool's
41
+ * calls in the latest reply that called it, `searchFlights#2` for the
42
+ * second, so blocks of a reply that called a tool twice read one each.
41
43
  * While a block's results are the same, it gets the same object, so the view
42
44
  * does not compare them again.
43
45
  */
package/dist/tool-data.js CHANGED
@@ -76,13 +76,20 @@ function toolValue(part) {
76
76
  values.set(part, value ?? null);
77
77
  return value;
78
78
  }
79
- /** What a finished tool part does to a snapshot: sets its tool's value, or removes it. */
80
- function apply(snapshot, part, value) {
81
- const name = toolNameOf(part) ?? "";
82
- if (value === void 0) snapshot.delete(name);
83
- else snapshot.set(name, {
84
- id: `${part.toolCallId}:${part.state}`,
85
- value
79
+ /**
80
+ * What a settled call does to a snapshot: sets or removes its tool's
81
+ * latest value and that of its numbered key, `name#n`. The first to settle
82
+ * of a message's calls of a tool drops the numbered keys an earlier reply
83
+ * left, so `name#n` is always the latest reply's.
84
+ */
85
+ function apply(snapshot, call) {
86
+ if (call.first) {
87
+ for (const key of snapshot.keys()) if (key.startsWith(`${call.name}#`)) snapshot.delete(key);
88
+ }
89
+ for (const key of [call.name, `${call.name}#${call.ordinal}`]) if (call.value === void 0) snapshot.delete(key);
90
+ else snapshot.set(key, {
91
+ id: `${call.part.toolCallId}:${call.part.state}`,
92
+ value: call.value
86
93
  });
87
94
  }
88
95
  /** Whether a part settles its tool's value: a final output, an error or a refusal. */
@@ -118,7 +125,9 @@ const DEFAULT_VALUE = {};
118
125
  * reply that wrote it; else its previous version's value; else the latest
119
126
  * value earlier in the conversation. A failed or refused call in that reply
120
127
  * removes the tool's entry, so the block shows its empty state rather than
121
- * an older result. A tool called twice in one step leaves the last result.
128
+ * an older result. Each call is also under its number among that tool's
129
+ * calls in the latest reply that called it, `searchFlights#2` for the
130
+ * second, so blocks of a reply that called a tool twice read one each.
122
131
  * While a block's results are the same, it gets the same object, so the view
123
132
  * does not compare them again.
124
133
  */
@@ -134,21 +143,26 @@ function toolData(messages, options = {}) {
134
143
  const before = new Map(conversation);
135
144
  /** The settled tool calls of this message so far, in order. */
136
145
  const settled = [];
146
+ /** The calls of each tool in this message so far, settled or not. */
147
+ const counts = /* @__PURE__ */ new Map();
137
148
  for (const part of message.parts) {
138
149
  if (isToolPart(part)) {
139
- if (settles(part)) {
140
- const value = valueOf === void 0 ? toolValue(part) : valueOf(toolNameOf(part) ?? "", part);
141
- settled.push({
142
- part,
143
- value
144
- });
145
- }
150
+ const name = toolNameOf(part) ?? "";
151
+ const ordinal = (counts.get(name) ?? 0) + 1;
152
+ counts.set(name, ordinal);
153
+ if (settles(part)) settled.push({
154
+ first: !settled.some((call) => call.name === name),
155
+ name,
156
+ ordinal,
157
+ part,
158
+ value: valueOf === void 0 ? toolValue(part) : valueOf(name, part)
159
+ });
146
160
  continue;
147
161
  }
148
162
  if (!isBlockPart(part)) continue;
149
163
  const block = part.data;
150
164
  const snapshot = new Map(versions.get(block.name) ?? before);
151
- for (const entry of settled) apply(snapshot, entry.part, entry.value);
165
+ for (const call of settled) apply(snapshot, call);
152
166
  versions.set(block.name, snapshot);
153
167
  if (block.toolKeys === void 0) continue;
154
168
  const projected = project(snapshot, block.toolKeys);
@@ -164,7 +178,7 @@ function toolData(messages, options = {}) {
164
178
  });
165
179
  result.set(block.key, data);
166
180
  }
167
- for (const entry of settled) apply(conversation, entry.part, entry.value);
181
+ for (const call of settled) apply(conversation, call);
168
182
  }
169
183
  return result;
170
184
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jigs.design/ai-sdk",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "description": "Jigs on the AI SDK: a model function for createJigsServer, and chat mode for useChat.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -29,8 +29,8 @@
29
29
  "access": "public"
30
30
  },
31
31
  "dependencies": {
32
- "@jigs.design/protocol": "0.3.3",
33
- "@jigs.design/server": "0.3.3"
32
+ "@jigs.design/protocol": "0.3.5",
33
+ "@jigs.design/server": "0.3.5"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "ai": "^7.0.0",
@@ -40,7 +40,7 @@
40
40
  "@ai-sdk/provider": "4.0.27",
41
41
  "ai": "7.0.140",
42
42
  "zod": "4.6.7",
43
- "@jigs.design/catalog": "0.3.3",
44
- "@jigs.design/host": "0.3.3"
43
+ "@jigs.design/catalog": "0.3.5",
44
+ "@jigs.design/host": "0.3.5"
45
45
  }
46
46
  }