@assistant-ui/react
Version:
TypeScript/React library for AI Chat
96 lines • 4.1 kB
JavaScript
import { tapMemo, resource, tapInlineResource, tapResource, } from "@assistant-ui/tap";
import { Tools } from "../model-context/index.js";
import { asStore, tapApi } from "../utils/tap-store/index.js";
import { useResource } from "@assistant-ui/tap/react";
import { useMemo } from "react";
import { checkEventScope, normalizeEventSelector, } from "../types/EventTypes.js";
import { EventManager } from "../legacy-runtime/client/EventManagerRuntimeClient.js";
import { createAssistantApiField, useAssistantApiImpl, extendApi, } from "../context/react/AssistantApiContext.js";
import { withEventsProvider } from "./EventContext.js";
import { withModelContextProvider } from "./ModelContext.js";
import { ModelContext as ModelContextResource } from "./ModelContextClient.js";
const AssistantStore = resource(({ threads: threadsEl, modelContext: modelContextEl, tools: toolsEl, }) => {
const events = tapInlineResource(EventManager());
const { threads, tools, modelContext } = withEventsProvider(events, () => {
const modelContextResource = tapResource(modelContextEl ?? ModelContextResource(), [modelContextEl]);
return withModelContextProvider(modelContextResource.api, () => {
return {
modelContext: modelContextResource,
tools: tapResource(toolsEl ?? Tools({}), [toolsEl]),
threads: tapResource(threadsEl, [threadsEl]),
};
});
});
const state = tapMemo(() => ({
threads: threads.state,
tools: tools.state,
modelContext: modelContext.state,
}), [threads.state, tools.state, modelContext.state]);
return tapApi({
getState: () => state,
threads: threads.api,
tools: tools.api,
modelContext: modelContext.api,
on: events.on,
});
});
const getClientFromStore = (client) => {
const getItem = () => {
return client.getState().api.threads.item("main");
};
return {
threads: createAssistantApiField({
source: "root",
query: {},
get: () => client.getState().api.threads,
}),
tools: createAssistantApiField({
source: "root",
query: {},
get: () => client.getState().api.tools,
}),
modelContext: createAssistantApiField({
source: "root",
query: {},
get: () => client.getState().api.modelContext,
}),
thread: createAssistantApiField({
source: "threads",
query: { type: "main" },
get: () => client.getState().api.threads.thread("main"),
}),
threadListItem: createAssistantApiField({
source: "threads",
query: { type: "main" },
get: () => getItem(),
}),
composer: createAssistantApiField({
source: "thread",
query: {},
get: () => client.getState().api.threads.thread("main").composer,
}),
on(selector, callback) {
const { event, scope } = normalizeEventSelector(selector);
if (scope === "*")
return client.getState().api.on(event, callback);
if (checkEventScope("thread", scope, event) ||
checkEventScope("thread-list-item", scope, event) ||
checkEventScope("composer", scope, event)) {
return client.getState().api.on(event, (e) => {
if (e.threadId !== getItem().getState().id)
return;
callback(e);
});
}
throw new Error(`Event scope is not available in this component: ${scope}`);
},
subscribe: client.subscribe,
};
};
export const useAssistantClient = (props) => {
const api = useAssistantApiImpl();
const client = useResource(asStore(AssistantStore(props)));
const clientApi = useMemo(() => getClientFromStore(client), [client]);
return useMemo(() => extendApi(api, clientApi), [api, clientApi]);
};
//# sourceMappingURL=AssistantClient.js.map