semiconductor
v0.0.0-alpha.3
Published
Agent and tool runner with portable custom agent UI
Readme
WIP agent runner with portable custom agent UI
Install
$ npm install semiconductor @semiconductor/api @semiconductor/connectBasic setup
import { Semiconductor } from 'semiconductor';
import type { Agent } from '@semiconductor/api';
class MyAgent implements Agent {
id = 'default';
prompt({ host, thread, reason, response }) {
// reason.newUserMessage is the new user prompt
// (or reason.toolCompleted when tool(s) finish)
// ... call LLM here ...
response.markdown(`You're absolutely right!`);
response.ui(<button onclick={...} />);
// ... or call registered UI-ready tools with response.tool()
}
}
const semiconductor = new Semiconductor();
semiconductor.registerAgent(new MyAgent());
semiconductor.registerAgent(/* additional agents */);
semiconductor.registerTool(/* register tools that use rich UI */);
let session = semiconductor.newSession();
session.on('change', changes => { /* re-render session */ });
await session.prompt('hello');Serve over WebSocket
import { WebSocketServer } from "ws";
import { Semiconductor } from "semiconductor";
import { serveClient } from "@semiconductor/connect";
// ... set up semiconductor here
const wss = new WebSocketServer({ port: 8080 });
wss.on("connection", (ws) => {
let clientId = crypto.randomUUID();
serveClient(semiconductor, clientId, ({ receive, close }) => {
ws.on("message", (data) => receive(String(data)));
ws.on("close", () => close());
return { send: (payload) => ws.send(payload) };
});
});
console.log("WebSocket server running on ws://localhost:8080");React client
import { useSemiconductorClient, SemiconductorThread } from '@semiconductor/react';
export function App() {
const socket = useSocket('wss://…'); // use your favorite hook to get a WebSocket
// get a semiconductor instance
const semiconductor = useSemiconductorClient(({ receive, close }) => {
if (!socket) return false;
socket.addEventListener("message", (event) => receive(String(event.data)));
socket.addEventListener("close", () => close());
return { send: (payload) => socket.send(payload) };
}, [socket]);
return <>
<Button onClick={() => semiconductor.newSession()}>New Thread</Button>
{semiconductor.thread && (
<SemiconductorThread thread={semiconductor.thread}
client={semiconductor}
customComponents={{ /* customize basic UI components */ }}
customToolComponents={{ /* customize portable UI renderers */ }}
/>
)}
<PromptBox onPrompt={prompt => semiconductor?.prompt(prompt)} />
</>;
}