@assistant-ui/react
Version:
TypeScript/React library for AI Chat
90 lines • 3.45 kB
JavaScript
"use client";
import { jsx as _jsx } from "react/jsx-runtime";
import { useEffect, useRef, forwardRef, useId, createContext, useContext, } from "react";
import { useAssistantApi } from "../context/react/AssistantApiContext.js";
import { useComposedRefs } from "@radix-ui/react-compose-refs";
import { tool } from "./tool.js";
const click = tool({
parameters: {
type: "object",
properties: {
clickId: {
type: "string",
},
},
required: ["clickId"],
},
execute: async ({ clickId }) => {
const escapedClickId = CSS.escape(clickId);
const el = document.querySelector(`[data-click-id='${escapedClickId}']`);
if (el instanceof HTMLElement) {
el.click();
// todo make adjustable
await new Promise((resolve) => setTimeout(resolve, 2000));
return {};
}
else {
return "Element not found";
}
},
});
const edit = tool({
parameters: {
type: "object",
properties: {
editId: {
type: "string",
},
value: {
type: "string",
},
},
required: ["editId", "value"],
},
execute: async ({ editId, value }) => {
const escapedEditId = CSS.escape(editId);
const el = document.querySelector(`[data-edit-id='${escapedEditId}']`);
if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
el.value = value;
el.dispatchEvent(new Event("input", { bubbles: true }));
el.dispatchEvent(new Event("change", { bubbles: true }));
// todo make adjustable
await new Promise((resolve) => setTimeout(resolve, 2000));
return {};
}
else {
return "Element not found";
}
},
});
const ReadableContext = createContext(false);
export const makeAssistantVisible = (Component, config) => {
const ReadableComponent = forwardRef((props, outerRef) => {
const isNestedReadable = useContext(ReadableContext);
const clickId = useId();
const componentRef = useRef(null);
const api = useAssistantApi();
const { clickable, editable } = config ?? {};
useEffect(() => {
return api.modelContext().register({
getModelContext: () => {
return {
tools: {
...(clickable ? { click } : {}),
...(editable ? { edit } : {}),
},
system: !isNestedReadable // only pass content if this readable isn't nested in another readable
? componentRef.current?.outerHTML
: undefined,
};
},
});
}, [isNestedReadable, api, clickable, editable]);
const ref = useComposedRefs(componentRef, outerRef);
return (_jsx(ReadableContext.Provider, { value: true, children: _jsx(Component, { ...props, ...(config?.clickable ? { "data-click-id": clickId } : {}), ...(config?.editable ? { "data-edit-id": clickId } : {}), ref: ref }) }));
});
ReadableComponent.displayName = Component.displayName;
return ReadableComponent;
};
export default makeAssistantVisible;
//# sourceMappingURL=makeAssistantVisible.js.map