AI UI
In-process Claude tool-use loop — make a holon callable in natural language
Status: early —
@holons/ai-uiis at0.1.0. The agent loop and tool conversion are stable; the command registry currently lives as a fallback in this package and will move to@holons/core/commandsupstream. Expect the import path for shared commands to change.
@holons/ai-ui is an in-process natural-language interpreter for Holons. It runs a Claude tool-use loop against the @holons/core commands so a user can say "log two hours on the garden task" and the agent translates it into the right sequence of @holons/core calls. It is what makes a Claude model embedded inside the holon's own infrastructure, rather than orchestrating it from outside.
This is the sibling of the MCP server: both expose @holons/core to AI agents, but they sit at different layers.
@holons/ai-ui
@holons/mcp-ui
Process model
In-process — embeds Claude SDK inside the running app
Out-of-process — MCP server reached by external clients
Entry point
holons-ai CLI (or library import)
stdio / SSE over HTTP
Caller
A holon's own scripts, cron jobs, bot handlers
Claude Desktop, IDE integrations, other MCP-aware tools
Best for
Embedding intelligence into the holon
Letting external agents participate in the holon
The two are not redundant—they support different deployment patterns. A holon can run both.
What it is
Name:
@holons/ai-uiLocation:
harvest/packages/ai-ui/Binary:
holons-aiSDK:
@anthropic-ai/sdkDefault model:
claude-sonnet-4-6(override viaHOLONS_AI_MODEL)
Using the CLI
Environment:
ANTHROPIC_API_KEY
Claude API auth
Yes
HOLONS_AI_MODEL
Override the default model
No
The CLI prints the agent's final text answer to stdout; everything else goes to stderr.
How the loop works
The loop terminates when the model emits stop_reason: 'end_turn' or produces no further tool_use blocks. Defensive cap: maxIterations (default 10), to prevent runaway loops.
Per-call defaults:
maxTokens= 4096maxIterations= 10
Prompt caching
The system prompt and tool definitions don't change across turns within a session, so they're sent with a single cache_control: { type: 'ephemeral' } breakpoint on the system block. Anthropic's render order is tools → system → messages, so a breakpoint on the system block caches both tools and system together. This:
keeps the implementation well under the 4-breakpoint cache cap,
avoids unnecessary cache writes,
makes multi-turn sessions cheap.
The same pattern is recommended for any tool-use loop calling Claude — see the agent.ts source for the exact wiring.
Tool definitions
Tools are derived from a CommandRegistry. Each registered command has:
At load time, every command is converted to an Anthropic Tool with a JSON Schema generated from its params. Required-param enforcement, type coercion, and side effects all live inside the command's own execute() — so the same registry powers both the AI loop and the text UI CLI.
Currently the registry lives at packages/ai-ui/src/commands.ts as a fallback (identical to the text-ui copy), designed so that when @holons/core/commands is extracted upstream, the package can switch to the shared registry with a no-op rename.
System prompt
The default system prompt is intentionally narrow:
You are the Holons assistant. You help users manage tasks, hours, and shopping lists across their holons by calling the available tools. Always call a tool when the user requests an action; never fabricate results. After tools complete, summarize what was done in one sentence.
Two principles worth noting:
Always call a tool when the user requests an action. The agent is not asked to be clever about when to act—if the user wants an action, an action happens.
Never fabricate results. Tool calls are the source of truth; the model's job is to dispatch and summarize, not to invent.
Callers can override the system prompt by passing system to runAgent().
Programmatic use
runAgent() is the library entry point — usable wherever a holon wants to embed natural-language intelligence (a bot handler, a webhook, a scheduled job):
The returned AgentResult includes the final text, the iteration count, the last stop reason, and the full message transcript—useful for debugging or for feeding back into another loop.
Testing
packages/ai-ui/src/tools.test.ts covers the command→tool conversion and the registry fallback. The agent loop is testable by injecting a pre-built Anthropic client into runAgent({ client })—no network needed for unit tests.
When to use it
Pick @holons/ai-ui when:
A holon's own code (a bot, a cron job, a script) wants to interpret natural-language input.
You're comfortable shipping the Anthropic SDK as part of your holon's runtime.
The agent should run on behalf of the holon, not as a separate user identity.
Pick the MCP server when:
An external client (Claude Desktop, an IDE) should be able to drive the holon.
Multiple AI agents may connect concurrently with different actor identities.
The integration should follow the standard MCP protocol rather than a Holons-specific API.
See also
MCP Server — the out-of-process complement
Harvest — the monorepo
@holons/ai-uiis part ofHolonsBot — a natural place to embed an in-process agent loop
Glossary — vocabulary for the protocol concepts the agent acts on
Last updated
Was this helpful?