{"id":"afe952a4-000c-40da-8e2c-a66c72bb9f00","slug":"agui-framework","kind":"mcp","name":"agui-framework","summary":"A TypeScript SDK for building AI agent-powered applications. agui-framework provides a complete toolkit for creating, orchestrating, and deploying LLM-based agents with multi-provider support, real-ti","owner":"fab679","repoUrl":"https://github.com/fab679/agui-framework","license":"MIT","licenseTier":"permissive","trust":"community","stars":2,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-07-21T09:30:53.000Z","addedAt":"2026-10-21T21:33:55.815Z","logoUrl":"https://avatars.githubusercontent.com/u/23230459?u=2a56c6a626317e7114c929a518a991bc564f179f&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["developer-tools","design-media","utilities"],"tags":[],"runtime":"node","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-25T22:42:16.616Z","sample":false,"url":"https://conduits.dev/tools/agui-framework","language":"JavaScript","transports":["stdio"],"install":{"npm":"agui-framework"},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# agui-framework\n\n<p align=\"center\">\n  <img src=\"docs/logo.svg\" alt=\"agui-framework\" width=\"200\"/>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://fab679.github.io/agui-framework\">\n    <img src=\"https://img.shields.io/badge/docs-mkdocs%20material-blue?style=for-the-badge\" alt=\"Documentation\">\n  </a>\n  <a href=\"https://www.npmjs.com/package/agui-framework\">\n    <img src=\"https://img.shields.io/npm/v/agui-framework?style=for-the-badge\" alt=\"npm\">\n  </a>\n  <a href=\"https://github.com/fab679/agui-framework/blob/main/LICENSE\">\n    <img src=\"https://img.shields.io/github/license/fab679/agui-framework?style=for-the-badge\" alt=\"MIT License\">\n  </a>\n</p>\n\nA TypeScript SDK for building AI agent-powered applications. agui-framework provides a complete toolkit for creating, orchestrating, and deploying LLM-based agents with multi-provider support, real-time streaming, state management, persistence, and the AG-UI protocol for frontend communication.\n\n## Features\n\n- **Agent class** -- Central orchestrator for LLM interactions with run/stream/resume execution modes\n- **Multi-LLM providers** -- OpenAI, Anthropic, Ollama, and Fireworks support with a common abstraction\n- **Real-time streaming** -- AsyncGenerator-based streaming with event callbacks\n- **Event system** -- Publish/subscribe EventBus with history, compaction, and piping\n- **Structured output** -- JSON Schema-enforced responses via `response_format`\n- **State management** -- Thread-isolated SharedState with versioning, diffing, merging, and conflict resolution; agents can autonomously read/write global shared state via built-in setState/getState/deleteState tools\n- **Long-term memory** -- Optional RDF-based semantic store (Oxigraph) with self-managing remember/recall/forget tools\n- **AG-UI protocol** -- Full SSE-based protocol encoding, validation, and event compaction\n- **MCP (Model Context Protocol)** -- Connect to any MCP-compatible tool server via stdio or streamable HTTP; tools are auto-discovered and registered\n- **Multi-agent patterns** -- Delegation, cyclic handoff, capability routing, and directed graph workflows\n- **Middleware pipeline** -- Composable event interception and transformation\n- **Persistence** -- Memory, Redis, and Postgres thread stores\n- **HTTP/WebSocket server** -- Express route handlers, WebSocket agent communication, model catalog API\n- **Model catalog** -- 44 models across 4 providers with pricing, context windows, and capabilities\n- **Cost & usage tracking** -- Per-run token usage, cost calculation, cumulative thread cost, budget limits\n- **WebSocket client** -- Full-duplex agent communication with run/stream/resume/capabilities\n- **React client hooks** -- useStream, useThread, useInterrupts, useCoAgent, useWebSocket, useAgentState, useRunningAgents, useLiveState, and more\n- **State REST API** -- Server endpoints for reading/writing agent shared state; AguiClient methods and React hooks included\n- **Type safety** -- Full TypeScript with strict types across all modules\n\n## Installation\n\n```bash\nnpm install agui-framework\n```\n\nRequires Node.js 18+ for native `fetch` and `ReadableStream` support.\n\nOptional persistence dependencies:\n\n```bash\nnpm install ioredis          # RedisThreadStore\nnpm install pg               # PostgresThreadStore\n```\n\nOptional long-term memory:\n\n```bash\nnpm install oxigraph         # OxigraphSemanticStore\n```\n\n## Quick Start\n\n### 1. Basic Agent\n\n```typescript\nimport { Agent } from \"agui-framework\";\n\nconst agent = new Agent({\n  model: \"gpt-4o\",\n  provider: \"openai\",\n  instructions: \"You are a helpful assistant.\",\n});\n\nconst response = await agent.run(\"What is the capital of France?\");\nconsole.log(response);\n```\n\nSet `OPENAI_API_KEY` in your environment.\n\n### 2. Streaming Response\n\n```typescript\nimport { Agent } from \"agui-framework\";\n\nconst agent = new Agent({\n  model: \"gpt-4o\",\n  provider: \"openai\",\n  instructions: \"Tell a detailed story.\",\n});\n\nfor await (const chunk of agent.stream(\"Tell me about space exploration\")) {\n  process.stdout.write(chunk);\n}\n```\n\n### 3. Agent with Tools\n\n```typescript\nimport { Agent } from \"agui-framework\";\nimport type { ToolConfig } from \"agui-framework\";\n\nconst weatherTool: ToolConfig = {\n  name: \"get_weather\",\n  description: \"Get current weather for a city\",\n  parameters: {\n    type: \"object\",\n    properties: { city: { type: \"string\", description: \"City name\" } },\n    required: [\"city\"],\n  },\n  handler: async ({ city }) => ({ city, temperature: 22, conditions: \"sunny\" }),\n};\n\nconst agent = new Agent({\n  model: \"gpt-4o\",\n  provider: \"openai\",\n  instructions: \"Use the weather tool when asked about weather.\",\n  tools: [weatherTool],\n});\n\nconst response = await agent.run(\"What is the weather in Paris?\");\nconsole.log(response);\n```\n\n### 4. Structured Output\n\n```typescript\nimport { Agent } from \"agui-framework\";\n\nconst agent = new Agent({\n  model: \"gpt-4o\",\n  provider: \"openai\",\n  instructions: \"Extract structured data from text.\",\n  structuredOutput: true,\n  outputSchema: {\n    name: \"extract_person\",\n    schema: {\n      type: \"object\",\n      properties: {\n        name: { type: \"string\" },\n        age: { type: \"number\" },\n        occupation: { type: \"string\" },\n      },\n      required: [\"name\", \"occupation\"],\n    },\n  },\n});\n\nconst response = await agent.run(\"Alice is a 30-year-old engineer.\");\nconsole.log(response); // JSON string: { \"name\": \"Alice\", \"age\": 30, \"occupation\": \"engineer\" }\n```\n\n### 5. Global Shared State\n\nA `SharedState` instance can be passed to one or more agents. The agent automatically registers `setState`/`getState`/`deleteState` tools that read and write the shared state — no thread scoping required.\n\n```typescript\nimport { Agent, SharedState } from \"agui-framework\";\n\nconst shared = new SharedState({ theme: \"dark\", maxRetries: 3 });\n\nconst agent = new Agent({\n  model: \"gpt-4o\",\n  provider: \"openai\",\n  instructions: \"You are a helpful assistant. Use setState to remember user preferences.\",\n  sharedState: shared,  // enables setState/getState/deleteState tools\n});\n\nconst response = await agent.run(\"Remember my favorite color is blue.\");\n// The agent calls setState(\"favoriteColor\", \"blue\") autonomously\nconsole.log(shared.get(\"favoriteColor\")); // \"blue\"\n\n// Multiple agents or users can share the same state:\nconst agent2 = new Agent({\n  model: \"gpt-4o\",\n  provider: \"openai\",\n  instructions: \"You know the user's preferences.\",\n  sharedState: shared,\n});\n\nconst reply = await agent2.run(\"What is my favorite color?\");\n// The agent calls getState(\"favoriteColor\") and responds \"blue\"\n```\n\n### 6. MCP (Model Context Protocol)\n\nConnect any MCP-compatible tool server and use its tools automatically:\n\n```typescript\nimport { Agent } from \"agui-framework\";\n\nconst agent = new Agent({\n  model: \"gpt-4o\",\n  provider: \"openai\",\n  instructions: \"You have access to MCP tools.\",\n  mcpServers: [\n    // Local subprocess via stdio\n    { transport: \"stdio\", command: \"node\", args: [\"path/to/mcp-server.js\"] },\n    // Remote server via streamable HTTP\n    { transport: \"streamable-http\", url: \"https://mcp.example.com/tools\" },\n  ],\n});\n\n// MCP tools are auto-discovered and merged into the agent's tool list\nconst tools = agent.getTools(); // includes MCP tools + any configured tools\n\n// Tools are available during run/stream execution\nconst response = await agent.run(\"Use the connected MCP tools.\");\n```\n\n### 7. Multi-Provider Configuration\n\n```typescript\nimport { Agent } from \"agui-framework\";\n\n// Anthropic\nconst agent = new Agent({\n  model: \"claude-3-5-sonnet-20240620\",\n  provider: \"anthropic\",\n  instructions: \"You are helpful.\",\n});\n\n// Ollama (local)\nconst localAgent = new Agent({\n  model: \"llama3\",\n  provider: \"ollama\",\n  instructions: \"You are helpful.\",\n  baseUrl: \"http://localhost:11434/v1\",\n});\n\n// Fireworks\nconst fwAgent = new Agent({\n  model: \"accounts/fireworks/models/deepseek-v4-flash\",\n  provider: \"fireworks\",\n  instructions: \"You are helpful.\",\n});\n```\n\n### 8. Long-Term Memory\n\n```typescript\nimport { Agent, OxigraphSemanticStore, createLTMMiddleware } from \"agui-framework\";\n\nconst store = new OxigraphSemanticStore();\nconst agent = new Agent({\n  model: \"gpt-4o\",\n  provider: \"openai\",\n  instructions: \"You are a helpful assistant.\",\n});\n\nagent.use(createLTMMiddleware(store));\n\n// The agent autonomously calls remember/recall/forget tools\nconst reply = await agent.run(\n  \"Remember I prefer short answers.\",\n  { userId: \"alice\" },\n);\n```\n\n### 9. Environment-Based Configuration\n\n```env\nAGUI_PROVIDER=openai\nAGUI_MODEL=gpt-4o\nAGUI_INSTRUCTIONS=You are a helpful assistant.\nAGUI_MAX_TOKENS=1024\n```\n\n```typescript\nimport \"dotenv/config\";\nimport { Agent } from \"agui-framework\";\n\nconst agent = Agent.createFromEnv();\nconst reply = await agent.run(\"Tell me a joke\");\nconsole.log(reply);\n```\n\n## Configuration\n\n### AgentConfig\n\n| Option                   | Type                      | Default          | Description                                                                                   |\n| ------------------------ | ------------------------- | ---------------- | --------------------------------------------------------------------------------------------- |\n| `name`                   | `string`                  | undefined        | Display name for the agent                                                                    |\n| `model`                  | `string`                  | required         | LLM model identifier                                                                          |\n| `provider`               | `ProviderType`            | required         | `openai`, `anthropic`, `ollama`, `fireworks`                                                  |\n| `instructions`           | `string`                  | required         | System prompt                                                                                 |\n| `tools`                  | `ToolConfig[]`            | `[]`             | Tool definitions                                                                              |\n| `maxTokens`              | `number`                  | `1024`           | Maximum output tokens                                                                         |\n| `temperature`            | `number`                  | `0.7`            | Sampling temperature (0-2)                                                                    |\n| `topP`                   | `number`                  | undefined        | Nucleus sampling                                                                              |\n| `stream`                 | `boolean`                 | `false`          | Enable streaming by default                                                                   |\n| `apiKey`                 | `string`                  | env var          | API key for the provider                                                                      |\n| `baseUrl`                | `string`                  | provider default | Custom API endpoint                                                                           |\n| `store`                  | `ThreadStore`             | undefined        | Persistence backend                                                                           |\n| `autoPersist`            | `boolean`                 | `true`           | Auto-save to store after runs                                                                 |\n| `capabilities`           | `string[]`                | `[]`             | Custom capability flags                                                                       |\n| `maxIterations`          | `number`                  | `10`             | Execution iteration limit                                                                     |\n| `maxExecutionTime`       | `number`                  | `30000`          | Max wall-clock time in ms                                                                     |\n| `structuredOutput`       | `boolean`                 | `false`          | JSON schema output support                                                                    |\n| `outputSchema`           | `Record<string, unknown>` | `undefined`      | JSON Schema for enforced structured output                                                    |\n| `supportedMimeTypes`     | `string[]`                | `['text/plain']` | Output MIME types                                                                             |\n| `parallelCalls`          | `boolean`                 | `false`          | Parallel tool calls                                                                           |\n| `clientProvidedTools`    | `boolean`                 | `false`          | Client-injectable tools                                                                       |\n| `websocket`              | `boolean`                 | `false`          | WebSocket transport                                                                           |\n| `codeExecution`          | `boolean`                 | `false`          | Declares an externally isolated code-execution capability; no in-process executor is supplied |\n| `sandboxed`              | `boolean`                 | `false`          | Metadata for an externally sandboxed tool                                                     |\n| `reasoningEncrypted`     | `boolean`                 | `false`          | Requires `reasoningEncryptionKey`; uses AES-256-GCM                                           |\n| `reasoningEncryptionKey` | `string`                  | undefined        | Base64-encoded 32-byte AES-256-GCM key                                                        |\n| `humanInterventions`     | `boolean`                 | `false`          | Mid-run intervention                                                                          |\n| `humanFeedback`          | `boolean`                 | `false`          | Human feedback (ratings)                                                                      |\n| `approveWithEdits`       | `boolean`                 | `false`          | Approve with edits                                                                            |\n| `sharedState`            | `SharedState`             | `undefined`      | Global SharedState instance; registers setState/getState/deleteState tools on the agent       |\n| `mcpServers`             | `MCPServerConfig[]`       | `undefined`      | MCP server configurations; connects on init and registers auto-discovered tools                |\n\n### Environment Variables\n\n| Provider  | Variable            | AGUI prefix alternative                                                                   |\n| --------- | ------------------- | ----------------------------------------------------------------------------------------- |\n| OpenAI    | `OPENAI_API_KEY`    | `AGUI_PROVIDER`, `AGUI_MODEL`, `AGUI_INSTRUCTIONS`, `AGUI_MAX_TOKENS`, `AGUI_TEMPERATURE` |\n| Anthropic | `ANTHROPIC_API_KEY` |                                                                                           |\n| Ollama    | `OLLAMA_API_KEY`    |                                                                                           |\n| Fireworks | `FIREWORKS_API_KEY` |                                                                                           |\n\n## Architecture Overview\n\n```\nagui-framework\n  Agent            -- Orchestrates LLM calls, tools, events, state, persistence\n  EventBus         -- In-process pub/sub with history and compaction\n  StateManager     -- Thread-isolated SharedState instances\n  SharedState      -- Global key-value store passed to agents via sharedState config; accessed via built-in setState/getState/deleteState tools\n  MCPClientManager -- Connects to MCP servers, discovers tools, and registers them as ToolConfig entries\n  ProtocolEncoder  -- Event serialization and SSE encoding\n  ProtocolValidator-- Input and event validation\n  BaseLLMProvider  -- Abstract LLM provider (OpenAI, Anthropic, Ollama, Fireworks)\n  MiddlewareChain  -- Composable middleware pipeline\n  MultiAgentManager-- Agent delegation, cyclic handoff, capability routing, graph execution\n  AgentGraph       -- Directed graph of agent nodes\n  ThreadStore      -- Persistence interface (Memory, Redis, Postgres)\n  SemanticStore    -- RDF-based long-term memory interface (Oxigraph)\n  LTMiddleware     -- Self-managing remember/recall/forget middleware\n  AguiClient       -- HTTP client for remote agent execution\n  React hooks      -- useStream, useThread, useInterrupts, useCoAgent\n```\n\n## Documentation\n\n| Document                                                          | Description                                       |\n| ----------------------------------------------------------------- | ------------------------------------------------- |\n| [Getting Started](docs/ag-ui-framworks-docs/getting-started.md)   | Installation, prerequisites, first agent          |\n| [Agents](docs/ag-ui-framworks-docs/agents.md)                     | Agent class deep dive: config, tools, execution   |\n| [Events](docs/ag-ui-framworks-docs/events.md)                     | EventBus API, event types, subscriptions          |\n| [State Management](docs/ag-ui-framworks-docs/state-management.md) | SharedState, StateManager, thread isolation, global agent state tools |\n| [Protocol](docs/ag-ui-framworks-docs/protocol.md)                 | ProtocolEncoder, SSE, validation                  |\n| [Providers](docs/ag-ui-framworks-docs/providers.md)               | Provider architecture, custom providers           |\n| [Tools](docs/ag-ui-framworks-docs/tools.md)                       | ToolConfig, handlers, interrupts, delegation      |\n| [Architecture](docs/ag-ui-framworks-docs/architecture.md)         | Module relationships, data flow, extension points |\n| [API Reference](docs/ag-ui-framworks-docs/api-reference.md)       | Complete API reference organized by module        |\n| [Future Integrations](docs/future-integrations.md)                | Draft proposals for router, meta events, GAI      |\n| [Examples](docs/ag-ui-framworks-docs/examples.md)                 | Multi-agent, graph, persistence, React, Express   |\n| [AG-UI Agents](docs/ag-ui/Agents.md)                              | AG-UI protocol agent implementation               |\n| [AG-UI Events](docs/ag-ui/Events.md)                              | AG-UI event format and types implementation       |\n\n## API Overview\n\n### Agent\n\n```typescript\nclass Agent {\n  constructor(config: AgentConfig);\n  run(prompt: string, context?: Partial<RunContext>): Promise<string>;\n  stream(\n    prompt: string,\n    context?: Partial<RunContext>,\n    options?: StreamingOptions,\n  ): AsyncGenerator<string>;\n  resume(\n    interruptId: string,\n    payload?: unknown,\n    status?: \"resolved\" | \"cancelled\",\n  ): Promise<string>;\n  addTool(tool: ToolConfig): this;\n  addCapability(capability: string): this;\n  use(...middlewares: MiddlewareFunction[]): this;\n  delegate(\n    subAgent: Agent,\n    prompt: string,\n    config?: DelegationConfig,\n  ): Promise<string>;\n  createDelegationTool(\n    toolName: string,\n    description: string,\n    subAgent: Agent,\n  ): ToolConfig;\n  createHandoffTool(\n    toolName: string,\n    description: string,\n    targetAgent: Agent,\n  ): ToolConfig;\n  clone(): Agent;\n  getCapabilities(\n    peerDescriptors?: Map<string, AgentDescriptor>,\n  ): AgentCapabilities;\n  loadThread(threadId: string): Promise<void>;\n  saveThread(threadId: string): Promise<void>;\n  toJSON(): string;\n  fromJSON(json: string): this;\n  static create(config: AgentConfig): Agent;\n  static createFromEnv(): Agent;\n}\n\ninterface AgentConfig {\n  name?: string;\n  model: string;\n  provider: ProviderType;\n  instructions: string;\n  tools?: ToolConfig[];\n  maxTokens?: number;\n  temperature?: number;\n  topP?: number;\n  stream?: boolean;\n  modelSettings?: Record<string, unknown>;\n  capabilities?: string[];\n  apiKey?: string;\n  baseUrl?: string;\n  store?: ThreadStore;\n  autoPersist?: boolean;\n  maxIterations?: number;\n  maxExecutionTime?: number;\n  structuredOutput?: boolean;\n  supportedMimeTypes?: string[];\n  parallelCalls?: boolean;\n  clientProvidedTools?: boolean;\n  websocket?: boolean;\n  codeExecution?: boolean;\n  sandboxed?: boolean;\n  reasoningEncrypted?: boolean;\n  humanInterventions?: boolean;\n  humanFeedback?: boolean;\n  approveWithEdits?: boolean;\n  sharedState?: SharedState;\n  mcpServers?: MCPServerConfig[];\n  multimodalInput?: {\n    image?: boolean;\n    audio?: boolean;\n    video?: boolean;\n    pdf?: boolean;\n    file?: boolean;\n  };\n  multimodalOutput?: { image?: boolean; audio?: boolean };\n}\n```\n\n### EventBus\n\n```typescript\nclass EventBus {\n  constructor(maxHistory?: number);\n  emit(event: AgentEvent): void;\n  on(type: EventType | \"*\", listener: EventListener): () => void;\n  once(type: EventType | \"*\", listener: EventListener): void;\n  clear(): void;\n  getHistory(): BaseEvent[];\n  compact(): void;\n  pipe(transform: (event: AgentEvent) => AgentEvent | null): EventBus;\n  toJSON(): string;\n  fromJSON(json: string): void;\n}\n```\n\n### StateManager / SharedState\n\n```typescript\nclass StateManager {\n  constructor(defaultState?: SharedState);\n  getOrCreateState(threadId: string): SharedState;\n  updateState(threadId: string, updates: Partial<StateData>): SharedState;\n  deleteState(threadId: string): void;\n  hasState(threadId: string): boolean;\n  getAllThreads(): string[];\n  clearAll(): void;\n  exportState(threadId: string): StateSnapshot | null;\n  importState(threadId: string, snapshot: StateSnapshot): SharedState;\n  subscribe(subscription: StateSubscription): () => void;\n}\n\nclass SharedState {\n  constructor(\n    initialData?: StateData,\n    options?: StateOptions,\n    threadId?: string,\n  );\n  get<T>(key: string, defaultValue?: T): T;\n  set(key: string, value: unknown): this;\n  update(updates: Partial<StateData>): this;\n  delete(key: string): this;\n  has(key: string): boolean;\n  clear(): void;\n  takeSnapshot(label?: string): void;\n  getSnapshot(): StateSnapshot;\n  getHistory(limit?: number): StateSnapshot[];\n  diff(other: SharedState): StateDiff;\n  merge(\n    other: SharedState,\n    strategy?: StateMergeStrategy,\n    conflictHandler?: Function,\n  ): StateData;\n  computePatch(): JsonPatchOperation[];\n  getVersion(): string;\n  subscribe(subscription: StateSubscription): () => void;\n  toJSON(): string;\n  fromJSON(json: string): this;\n}\n```\n\n### Provider Types\n\n```typescript\ntype ProviderType = \"openai\" | \"anthropic\" | \"ollama\" | \"fireworks\";\n\nabstract class BaseLLMProvider {\n  readonly type: ProviderType;\n  config: ProviderConfig;\n  chatCompletion(\n    request: ChatCompletionRequest,\n  ): Promise<ChatCompletionResponse>;\n  streamChatCompletion(\n    request: ChatCompletionRequest,\n  ): AsyncGenerator<StreamChunk>;\n  prepareMessages(\n    systemPrompt: string,\n    messages: Array<{ role: string; content: string }>,\n  ): ChatMessage[];\n}\n```\n\n### ThreadStore Interface\n\n```typescript\ninterface ThreadStore {\n  connect(): Promise<void>;\n  disconnect(): Promise<void>;\n  createThread(\n    threadId: string,\n    metadata?: Record<string, unknown>,\n    agentId?: string,\n    ownerId?: string,\n  ): Promise<ThreadData>;\n  getThread(threadId: string): Promise<ThreadData | null>;\n  listThreads(limit?: number, offset?: number, agentId?: string, userId?: string): Promise<ThreadData[]>;\n  deleteThread(threadId: string): Promise<void>;\n  appendMessages(threadId: string, messages: Message[]): Promise<void>;\n  getMessages(\n    threadId: string,\n    limit?: number,\n    offset?: number,\n  ): Promise<Message[]>;\n  saveState(threadId: string, state: Record<string, unknown>): Promise<void>;\n  getState(threadId: string): Promise<Record<string, unknown> | null>;\n  saveRun(runId: string, threadId: string, data: RunData): Promise<void>;\n  getRun(runId: string): Promise<RunData | null>;\n  searchMessages(\n    threadId: string,\n    query: string,\n    limit?: number,\n  ): Promise<Message[]>;\n}\n```\n\nImplementations: `MemoryThreadStore`, `RedisThreadStore`, `PostgresThreadStore`.\n\n### SemanticStore (Long-Term Memory)\n\n```typescript\nimport { OxigraphSemanticStore } from \"agui-framework\";\n\nconst store = new OxigraphSemanticStore();\nawait store.remember(\"alice\", [\n  { subject: \"alice\", predicate: \"prefersModel\", object: \"gpt-4o\", timestamp: Date.now() },\n]);\nconst facts = await store.recall(\"alice\"); // returns all facts for alice\nawait store.forget(\"alice\", \"prefersModel\"); // delete specific fact\n```\n\nThe `createLTMMiddleware` wraps this store into the agent's execution pipeline, injecting `remember`/`recall`/`forget` tools so the agent manages its own memory. Each user's facts live in isolated named RDF graphs.\n\n### Model Catalog & Cost Tracking\n\n```typescript\nimport {\n  getModel,\n  calculateCost,\n  formatCost,\n  modelCatalog,\n} from \"agui-framework\";\n\n// Look up a model's pricing and capabilities\nconst model = getModel(\"gpt-5.6-luna\");\nconsole.log(model?.pricing); // { input: 1.00, output: 6.00, cachedInput: 0.10 }\n\n// Calculate cost from token usage\nconst cost = calculateCost(\"deepseek-v4-flash\", {\n  promptTokens: 5000,\n  completionTokens: 1200,\n  totalTokens: 6200,\n});\nconsole.log(formatCost(cost!.totalCost)); // \"$0.0010\"\n\n// Check context window limits\nconst { exceeds, limit } = exceedsContextWindow(\"llama-3.2-3b\", 200_000);\nconsole.log(exceeds); // true, limit is 128000\n\n// Query from server\nconst client = new AguiClient(\"http://localhost:4124\");\nconst models = await client.models();\nconst gptModel = await client.model(\"gpt-5.6-terra\");\n```\n\nCosts are automatically tracked per run and accumulated per thread when a store is configured:\n\n```\nGET /api/threads              → includes totalCost, runCount, lastModelId\nGET /api/threads/:id/runs     → includes usage + cost per run\n```\n\n### React Hooks\n\n```typescript\n// From 'agui-framework/client/react'\nfunction useStream(): { start; stop; isLoading; error; result };\nfunction useThread(options: UseThreadOptions): {\n  threads;\n  messages;\n  loadMessages;\n  createThread;\n  currentThreadId;\n};\nfunction useInterrupts(): { interrupts; handleInterrupt; resolve; clear };\nfunction useCoAgent(options: UseCoAgentOptions): UseCoAgentReturn;\nfunction useCoAction(\n  toolDef: ToolConfig & { handler: Function },\n): UseCoActionReturn;\nfunction useAgentState(\n  agentId: string,\n  baseUrl: string,\n): { state; setState; deleteState; loading; error; refetch };\nfunction useCapabilities(\n  agentId: string,\n  baseUrl: string,\n): { caps; loading; error; refetch };\nfunction useAgent(\n  agentId: string,\n  baseUrl: string,\n): { meta; loading; error; refetch };\nfunction useWebSocket(\n  baseUrl: string,\n  agentId: string,\n): { connected; caps; connect; disconnect; on; off; run; resume };\n```\n\n## Event Types\n\n| Category       | Events                                                                                            |\n| -------------- | ------------------------------------------------------------------------------------------------- |\n| Run lifecycle  | `RUN_STARTED`, `RUN_FINISHED`, `RUN_ERROR`                                                        |\n| Steps          | `STEP_STARTED`, `STEP_FINISHED`                                                                   |\n| Text messages  | `TEXT_MESSAGE_START`, `TEXT_MESSAGE_CONTENT`, `TEXT_MESSAGE_END`                                  |\n| Tool calls     | `TOOL_CALL_START`, `TOOL_CALL_ARGS`, `TOOL_CALL_END`, `TOOL_CALL_RESULT`                          |\n| State          | `STATE_SNAPSHOT`, `STATE_DELTA`, `MESSAGES_SNAPSHOT`                                              |\n| Activity       | `ACTIVITY_SNAPSHOT`, `ACTIVITY_DELTA`                                                             |\n| Reasoning      | `REASONING_START`, `REASONING_END`, `REASONING_MESSAGE_*`, `REASONING_ENCRYPTED_VALUE`            |\n| Multi-agent    | `AGENT_DELEGATION_START`, `AGENT_DELEGATION_END`, `AGENT_HANDOFF_REQUEST`, `AGENT_HANDOFF_RESULT` |\n| Human-in-loop  | `HUMAN_INTERVENTION_REQUEST`, `HUMAN_INTERVENTION_RESULT`, `HUMAN_FEEDBACK`                       |\n| Code execution | `CODE_EXECUTION_START`, `CODE_EXECUTION_RESULT`                                                   |\n| Memory         | `MEMORY_SUMMARY`                                                                                  |\n| Usage & cost   | `USAGE_UPDATE`                                                                                    |\n| Custom         | `RAW`, `CUSTOM`                                                                                   |\n\n## License\n\nMIT\n"}