@4djs/assistant
v0.4.0
Published
Headless chat assistant: OpenAI-compatible LLM streaming, tool-calling, chat history, and composer helpers. **The host owns all UI.**
Readme
@4djs/assistant
Headless chat assistant: OpenAI-compatible LLM streaming, tool-calling, chat history, and composer helpers. The host owns all UI.
Peer dependencies: react and react-dom (^18 or ^19). React is not bundled.
Package exports
| Path | Role |
| --- | --- |
| @4djs/assistant | AssistantProvider, AssistantBootstrap, store/composer hooks, labels |
| @4djs/assistant/core | Zustand store, LLM client, commands, mentions, activity helpers |
| @4djs/assistant/tools | Datastore/method tool registration |
Quick start
import {
AssistantBootstrap,
AssistantProvider,
useAssistant,
useAssistantActions,
type AssistantConfig,
} from "@4djs/assistant";
const config: AssistantConfig = {
llm: {
enabled: true,
baseUrl: "https://api.openai.com/v1",
apiKey: null,
model: "gpt-4o-mini",
systemPrompt: "You are a helpful assistant with access to tools.",
},
storageKeys: {
history: "my-app-chat-history",
llmSettings: "my-app-llm-settings",
},
welcomeMessage: ({ llmEnabled, model }) => ({
id: "welcome",
role: "assistant",
content: llmEnabled
? `Hello! Using **${model ?? "LLM"}**.`
: "Connect an LLM to start chatting.",
timestamp: Date.now(),
}),
toolRegistry: myRegistry,
};
function Chat() {
const messages = useAssistant((s) => s.messages);
const { sendChat, stopChat } = useAssistantActions();
return (
<ul>
{messages.map((m) => (
<li key={m.id}>{m.content}</li>
))}
</ul>
);
}
export function MyAssistant() {
return (
<AssistantProvider config={config}>
<AssistantBootstrap>
<Chat />
</AssistantBootstrap>
</AssistantProvider>
);
}Use useComposerCommands and useComposerMentions for slash-command and @ mention menus in your composer.
Core without React
import { createAssistantStore, runLlmAgent } from "@4djs/assistant/core";Useful for server routes, tests, or a non-React host.
