@jigs.design/ai-sdk 0.3.5 → 0.3.7

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/chat.d.ts CHANGED
@@ -16,13 +16,21 @@ export interface JigsChat {
16
16
  text: string;
17
17
  type: "text";
18
18
  } | undefined;
19
- /** The chat-mode prompt for the server's host. Add your instructions to it. */
19
+ /**
20
+ * The chat-mode prompt for this request: the server's host, then the
21
+ * caller's saved tags (`systemTail`). Add your instructions to it.
22
+ */
20
23
  system: string;
21
24
  /**
22
- * The start of `system` that is the same on every turn. Pass both to
23
- * `cachedInstructions` so the provider caches it.
25
+ * The start of `system` that is the same on every turn. Pass it, with
26
+ * `systemTail`, to `cachedInstructions` so the provider caches it.
24
27
  */
25
28
  systemPrefix: string;
29
+ /**
30
+ * The end of `system` that differs per user: the `## Saved tags` section
31
+ * when the server's `resolveTags` returned any, or "".
32
+ */
33
+ systemTail: string;
26
34
  /**
27
35
  * Turns a UI message stream, e.g. `result.toUIMessageStream()`, into one
28
36
  * where jigs are `data-jigs` parts. Prose stays in text parts, in the
@@ -54,6 +62,8 @@ export declare function jigsChat<TContext, TPageName extends string>(jigs: JigsM
54
62
  * back from storage. Other parts and the metadata pass through as they are,
55
63
  * so a `StoredJigsUIMessage<Metadata>`, or the stored form of your own
56
64
  * message type, comes back with `JigsBlockData` in its `data-jigs` parts.
65
+ * Pass `jigs.forUser({ ctx })` rather than the server to compile in the
66
+ * caller's scope, so blocks that use their saved tags draw them.
57
67
  */
58
68
  export declare function reviveJigs<TMessage extends UIMessage>(jigs: Pick<JigsServer<unknown>, "compile">, messages: ReadonlyArray<TMessage>): Promise<Array<WithJigsBlocks<TMessage, JigsBlockData>>>;
59
69
  //#endregion
package/dist/chat.js CHANGED
@@ -57,6 +57,7 @@ async function jigsChat(jigs, input) {
57
57
  },
58
58
  system: turn.system,
59
59
  systemPrefix: turn.systemPrefix,
60
+ systemTail: turn.systemTail,
60
61
  toUIMessageStream: (stream) => transform(turn, stream, stop),
61
62
  turn
62
63
  };
@@ -206,6 +207,8 @@ function transform(turn, stream, stop) {
206
207
  * back from storage. Other parts and the metadata pass through as they are,
207
208
  * so a `StoredJigsUIMessage<Metadata>`, or the stored form of your own
208
209
  * message type, comes back with `JigsBlockData` in its `data-jigs` parts.
210
+ * Pass `jigs.forUser({ ctx })` rather than the server to compile in the
211
+ * caller's scope, so blocks that use their saved tags draw them.
209
212
  */
210
213
  async function reviveJigs(jigs, messages) {
211
214
  return await Promise.all(messages.map(async (message) => ({
package/dist/model.d.ts CHANGED
@@ -4,22 +4,25 @@ 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 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.
7
+ * `system` as instructions a provider may cache: its first part `prefix`,
8
+ * the rest, and with a `tail` the end that differs per user, each a system
9
+ * message marked as a cache breakpoint for providers that need one
10
+ * (Anthropic). The first mark keeps the prefix cached when the rest
11
+ * changes; the second caches the rest too while it does not, as it does
12
+ * not for a host whose procedures and instructions are fixed; the third,
13
+ * one user's saved tags (`systemTail`), keeps the host's part before it the
14
+ * same for every user. Two of Anthropic's four breakpoints, or three with a
15
+ * tail. Providers that cache a repeated prefix on their own (OpenAI,
16
+ * DeepSeek, Google) read them as one. Without a prefix that `system` starts
17
+ * with, `system` alone; a tail it does not end with is part of the rest.
16
18
  */
17
- export declare function cachedInstructions(system: string, prefix: string): Instructions;
19
+ export declare function cachedInstructions(system: string, prefix: string, tail?: string): Instructions;
18
20
  /**
19
21
  * A `model` for `withModel` from an AI SDK model: document-mode
20
22
  * sessions and chat repairs stream through `streamText`, and token usage
21
- * reaches `onTurn`. The prompt's stable start and its end are marked for
22
- * the provider's cache (`cachedInstructions`).
23
+ * reaches `onTurn`. The prompt's stable start, the host's rest and the
24
+ * caller's saved tags are marked for the provider's cache
25
+ * (`cachedInstructions`).
23
26
  */
24
27
  export declare function aiSdkModel(model: LanguageModel, settings?: ModelSettings): ModelFunction<unknown, unknown>;
25
28
  //#endregion
package/dist/model.js CHANGED
@@ -7,33 +7,42 @@ const cachedMessage = (content) => ({
7
7
  role: "system"
8
8
  });
9
9
  /**
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.
10
+ * `system` as instructions a provider may cache: its first part `prefix`,
11
+ * the rest, and with a `tail` the end that differs per user, each a system
12
+ * message marked as a cache breakpoint for providers that need one
13
+ * (Anthropic). The first mark keeps the prefix cached when the rest
14
+ * changes; the second caches the rest too while it does not, as it does
15
+ * not for a host whose procedures and instructions are fixed; the third,
16
+ * one user's saved tags (`systemTail`), keeps the host's part before it the
17
+ * same for every user. Two of Anthropic's four breakpoints, or three with a
18
+ * tail. Providers that cache a repeated prefix on their own (OpenAI,
19
+ * DeepSeek, Google) read them as one. Without a prefix that `system` starts
20
+ * with, `system` alone; a tail it does not end with is part of the rest.
19
21
  */
20
- function cachedInstructions(system, prefix) {
22
+ function cachedInstructions(system, prefix, tail = "") {
21
23
  if (prefix === "" || !system.startsWith(prefix)) return system;
22
- const rest = system.slice(prefix.length);
23
- return rest === "" ? [cachedMessage(prefix)] : [cachedMessage(prefix), cachedMessage(rest)];
24
+ const ending = tail === "" ? "" : `\n\n${tail}`;
25
+ const tailed = ending !== "" && system.endsWith(ending) && system.length >= prefix.length + ending.length;
26
+ const rest = system.slice(prefix.length, tailed ? system.length - ending.length : system.length);
27
+ return [
28
+ cachedMessage(prefix),
29
+ ...rest === "" ? [] : [cachedMessage(rest)],
30
+ ...tailed ? [cachedMessage(ending)] : []
31
+ ];
24
32
  }
25
33
  /**
26
34
  * A `model` for `withModel` from an AI SDK model: document-mode
27
35
  * sessions and chat repairs stream through `streamText`, and token usage
28
- * reaches `onTurn`. The prompt's stable start and its end are marked for
29
- * the provider's cache (`cachedInstructions`).
36
+ * reaches `onTurn`. The prompt's stable start, the host's rest and the
37
+ * caller's saved tags are marked for the provider's cache
38
+ * (`cachedInstructions`).
30
39
  */
31
40
  function aiSdkModel(model, settings = {}) {
32
41
  return async function* (request) {
33
42
  const result = streamText({
34
43
  ...settings,
35
44
  abortSignal: request.signal,
36
- instructions: cachedInstructions(request.system, request.systemPrefix),
45
+ instructions: cachedInstructions(request.system, request.systemPrefix, request.systemTail),
37
46
  messages: request.messages.map((message) => ({
38
47
  content: message.content,
39
48
  role: message.role
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jigs.design/ai-sdk",
3
- "version": "0.3.5",
3
+ "version": "0.3.7",
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.5",
33
- "@jigs.design/server": "0.3.5"
32
+ "@jigs.design/protocol": "0.3.7",
33
+ "@jigs.design/server": "0.3.7"
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.5",
44
- "@jigs.design/host": "0.3.5"
43
+ "@jigs.design/catalog": "0.3.7",
44
+ "@jigs.design/host": "0.3.7"
45
45
  }
46
46
  }