feat(web): add harness event runtime bridge
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
import { useExternalStoreRuntime, type AppendMessage } from "@assistant-ui/react";
|
||||
import { useMemo, useSyncExternalStore } from "react";
|
||||
import type { MessageInput } from "@agent-studio/shared";
|
||||
import { toThreadMessageLike } from "./message-mapper.js";
|
||||
import type { HarnessClientState } from "../store/reducer.js";
|
||||
|
||||
export type HarnessRuntimeStore = {
|
||||
getSnapshot(): HarnessClientState;
|
||||
subscribe(subscriber: () => void): () => void;
|
||||
sendMessage(input: MessageInput): Promise<unknown>;
|
||||
cancel(): Promise<unknown>;
|
||||
};
|
||||
|
||||
export function useHarnessRuntime(store: HarnessRuntimeStore) {
|
||||
const snapshot = useSyncExternalStore(
|
||||
(subscriber) => store.subscribe(subscriber),
|
||||
() => store.getSnapshot(),
|
||||
() => store.getSnapshot(),
|
||||
);
|
||||
const messages = useMemo(
|
||||
() => snapshot.messageOrder.flatMap((id) => {
|
||||
const message = snapshot.messages[id];
|
||||
if (message === undefined) return [];
|
||||
const tools = Object.values(snapshot.tools).filter((tool) => tool.runId === message.runId);
|
||||
return [toThreadMessageLike(message, tools)];
|
||||
}),
|
||||
[snapshot.messageOrder, snapshot.messages, snapshot.tools],
|
||||
);
|
||||
const isRunning = Object.values(snapshot.runs).some((run) => run.status === "running");
|
||||
|
||||
return useExternalStoreRuntime({
|
||||
messages,
|
||||
convertMessage: (message) => message,
|
||||
isRunning,
|
||||
onNew: async (message) => {
|
||||
await store.sendMessage(extractMessageInput(message));
|
||||
},
|
||||
onCancel: async () => {
|
||||
await store.cancel();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function extractMessageInput(message: AppendMessage): MessageInput {
|
||||
const text = message.content
|
||||
.filter((part) => part.type === "text")
|
||||
.map((part) => part.text)
|
||||
.join("\n")
|
||||
.trim();
|
||||
const attachmentIds = (message.attachments ?? [])
|
||||
.map((attachment) => attachment.id)
|
||||
.filter((id) => /^att_[a-zA-Z0-9_-]+$/.test(id));
|
||||
return { text, attachmentIds: [...new Set(attachmentIds)] };
|
||||
}
|
||||
Reference in New Issue
Block a user