81 lines
2.6 KiB
TypeScript
81 lines
2.6 KiB
TypeScript
// @vitest-environment jsdom
|
|
|
|
import { act, createElement } from "react";
|
|
import { createRoot } from "react-dom/client";
|
|
import type { ChatModelAdapter, ThreadMessageLike } from "@assistant-ui/react";
|
|
import { defineToolkit, MessagePrimitive, ThreadPrimitive, useLocalRuntime } from "@assistant-ui/react";
|
|
import { afterEach, describe, expect, test } from "vitest";
|
|
import { z } from "zod/v4";
|
|
|
|
import { AssistantRuntimeProviderWithTools } from "./assistant-runtime-provider";
|
|
|
|
(globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
|
|
|
|
const noOpAdapter: ChatModelAdapter = { async *run() {} };
|
|
const toolkit = defineToolkit({
|
|
ask_user: {
|
|
type: "human",
|
|
display: "standalone",
|
|
parameters: z.object({ question: z.string() }),
|
|
render: ({ args }) => createElement("div", { "data-testid": "ask-user-ui" }, `Question: ${args.question}`),
|
|
},
|
|
});
|
|
const messages: ThreadMessageLike[] = [
|
|
{
|
|
role: "assistant",
|
|
content: [
|
|
{
|
|
type: "tool-call",
|
|
toolCallId: "ask-1",
|
|
toolName: "ask_user",
|
|
args: { question: "Which board?" },
|
|
argsText: JSON.stringify({ question: "Which board?" }),
|
|
},
|
|
],
|
|
status: { type: "requires-action", reason: "tool-calls" },
|
|
},
|
|
];
|
|
|
|
const Message = () =>
|
|
createElement(MessagePrimitive.Parts, {
|
|
components: {
|
|
tools: {
|
|
Fallback: () => createElement("div", { "data-testid": "fallback-tool-ui" }, "Fallback"),
|
|
},
|
|
},
|
|
});
|
|
|
|
const TestAssistant = () => {
|
|
const runtime = useLocalRuntime(noOpAdapter, { initialMessages: messages });
|
|
return createElement(
|
|
AssistantRuntimeProviderWithTools,
|
|
{ runtime, toolkit },
|
|
createElement(ThreadPrimitive.Messages, { components: { Message } }),
|
|
);
|
|
};
|
|
|
|
const containers: HTMLDivElement[] = [];
|
|
|
|
afterEach(() => {
|
|
for (const container of containers.splice(0)) container.remove();
|
|
});
|
|
|
|
describe("AssistantRuntimeProviderWithTools", () => {
|
|
test("makes the registered human-tool renderer available to message parts", async () => {
|
|
const container = document.createElement("div");
|
|
containers.push(container);
|
|
document.body.append(container);
|
|
const root = createRoot(container);
|
|
|
|
await act(async () => {
|
|
root.render(createElement(TestAssistant));
|
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
});
|
|
|
|
expect(container.querySelector('[data-testid="ask-user-ui"]')?.textContent).toBe("Question: Which board?");
|
|
expect(container.querySelector('[data-testid="fallback-tool-ui"]')).toBeNull();
|
|
|
|
await act(async () => root.unmount());
|
|
});
|
|
});
|