@gram-ai/elements 1.37.1 → 1.38.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/components/Markdown.d.ts +7 -0
- package/dist/components/MessageContent.d.ts +4 -0
- package/dist/components/ui/tool-ui.d.ts +52 -3
- package/dist/elements.cjs +1 -1
- package/dist/elements.css +1 -1
- package/dist/elements.js +26 -22
- package/dist/hooks/useMCPTools.d.ts +1 -1
- package/dist/{index-BdBraSNn.js → index--UMkUr53.js} +27921 -22336
- package/dist/index--UMkUr53.js.map +1 -0
- package/dist/index-Cz9y5YHw.cjs +222 -0
- package/dist/index-Cz9y5YHw.cjs.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/lib/messageConverter.d.ts +2 -0
- package/dist/{profiler-Cl-9cG3B.js → profiler-BHXyuGiY.js} +2 -2
- package/dist/{profiler-Cl-9cG3B.js.map → profiler-BHXyuGiY.js.map} +1 -1
- package/dist/{profiler-ttCkbP-N.cjs → profiler-jAEvoPXB.cjs} +2 -2
- package/dist/{profiler-ttCkbP-N.cjs.map → profiler-jAEvoPXB.cjs.map} +1 -1
- package/dist/{startRecording-C41DbnxY.js → startRecording-D8IbKhJo.js} +2 -2
- package/dist/{startRecording-C41DbnxY.js.map → startRecording-D8IbKhJo.js.map} +1 -1
- package/dist/{startRecording-DLCeKyz9.cjs → startRecording-Dw4aGDrV.cjs} +2 -2
- package/dist/{startRecording-DLCeKyz9.cjs.map → startRecording-Dw4aGDrV.cjs.map} +1 -1
- package/package.json +11 -13
- package/src/components/Markdown.tsx +210 -0
- package/src/components/MessageContent.tsx +9 -0
- package/src/components/ui/tool-ui.tsx +360 -7
- package/src/contexts/ElementsProvider.tsx +2 -1
- package/src/hooks/useGramThreadListAdapter.tsx +63 -17
- package/src/hooks/useMCPTools.ts +1 -1
- package/src/index.ts +18 -0
- package/src/lib/messageConverter.ts +5 -0
- package/src/lib/tools.test.ts +24 -12
- package/dist/index-BdBraSNn.js.map +0 -1
- package/dist/index-Bl5cH0sz.cjs +0 -194
- package/dist/index-Bl5cH0sz.cjs.map +0 -1
package/src/lib/tools.test.ts
CHANGED
|
@@ -11,12 +11,12 @@ import {
|
|
|
11
11
|
type UIMessage,
|
|
12
12
|
type UIMessagePart,
|
|
13
13
|
} from "ai";
|
|
14
|
-
import {
|
|
14
|
+
import { MockLanguageModelV3 } from "ai/test";
|
|
15
15
|
|
|
16
16
|
type MockStream = Extract<
|
|
17
17
|
NonNullable<
|
|
18
18
|
NonNullable<
|
|
19
|
-
ConstructorParameters<typeof
|
|
19
|
+
ConstructorParameters<typeof MockLanguageModelV3>[0]
|
|
20
20
|
>["doStream"]
|
|
21
21
|
>,
|
|
22
22
|
(...a: never[]) => PromiseLike<{ stream: ReadableStream<unknown> }>
|
|
@@ -70,8 +70,16 @@ function toolCallChunks(opts: {
|
|
|
70
70
|
},
|
|
71
71
|
{
|
|
72
72
|
type: "finish",
|
|
73
|
-
finishReason: "tool-calls",
|
|
74
|
-
usage: {
|
|
73
|
+
finishReason: { unified: "tool-calls", raw: undefined },
|
|
74
|
+
usage: {
|
|
75
|
+
inputTokens: {
|
|
76
|
+
total: 1,
|
|
77
|
+
noCache: 1,
|
|
78
|
+
cacheRead: undefined,
|
|
79
|
+
cacheWrite: undefined,
|
|
80
|
+
},
|
|
81
|
+
outputTokens: { total: 1, text: 1, reasoning: undefined },
|
|
82
|
+
},
|
|
75
83
|
},
|
|
76
84
|
];
|
|
77
85
|
}
|
|
@@ -118,7 +126,7 @@ async function streamToolCallOnly(toolCallId: string): Promise<UIMessage[]> {
|
|
|
118
126
|
},
|
|
119
127
|
} as unknown as ToolSet;
|
|
120
128
|
|
|
121
|
-
const model = new
|
|
129
|
+
const model = new MockLanguageModelV3({
|
|
122
130
|
doStream: async () => ({
|
|
123
131
|
stream: makeStream([
|
|
124
132
|
...toolCallChunks({
|
|
@@ -174,10 +182,13 @@ describe("frontend tool Skip flow (sendAutomaticallyWhen fix)", () => {
|
|
|
174
182
|
false,
|
|
175
183
|
);
|
|
176
184
|
|
|
177
|
-
//
|
|
178
|
-
//
|
|
179
|
-
//
|
|
180
|
-
|
|
185
|
+
// The resulting model-message sequence has an assistant `tool-call` with no
|
|
186
|
+
// matching tool result. (In ai v5 `convertToModelMessages` fabricated a
|
|
187
|
+
// bogus empty `role: "tool"` message here; ai v6 instead drops the
|
|
188
|
+
// unresolved call entirely and the next turn is the follow-up user message.)
|
|
189
|
+
// Either way the sequence is invalid — a tool-call with no result — which is
|
|
190
|
+
// exactly the state the `sendAutomaticallyWhen` fix prevents.
|
|
191
|
+
const modelMsgs = await convertToModelMessages(follow);
|
|
181
192
|
const assistantIdx = modelMsgs.findIndex(
|
|
182
193
|
(m) =>
|
|
183
194
|
m.role === "assistant" &&
|
|
@@ -187,8 +198,9 @@ describe("frontend tool Skip flow (sendAutomaticallyWhen fix)", () => {
|
|
|
187
198
|
),
|
|
188
199
|
);
|
|
189
200
|
expect(assistantIdx).toBeGreaterThanOrEqual(0);
|
|
190
|
-
|
|
191
|
-
expect(modelMsgs
|
|
201
|
+
// No valid tool result was produced for the unresolved tool-call.
|
|
202
|
+
expect(modelMsgs.some((m) => m.role === "tool")).toBe(false);
|
|
203
|
+
expect(modelMsgs[assistantIdx + 1]?.role).not.toBe("tool");
|
|
192
204
|
});
|
|
193
205
|
|
|
194
206
|
it("once the tool-result is patched onto the message, sendAutomaticallyWhen fires and the sequence is valid", async () => {
|
|
@@ -237,7 +249,7 @@ describe("frontend tool Skip flow (sendAutomaticallyWhen fix)", () => {
|
|
|
237
249
|
|
|
238
250
|
// And the sequence handed to the model is well-formed (assistant
|
|
239
251
|
// tool-call is followed by a real role:"tool" message with a result).
|
|
240
|
-
const modelMsgs = convertToModelMessages(patched);
|
|
252
|
+
const modelMsgs = await convertToModelMessages(patched);
|
|
241
253
|
const assistantIdx = modelMsgs.findIndex(
|
|
242
254
|
(m) =>
|
|
243
255
|
m.role === "assistant" &&
|