@sschepis/oboto-agent
v0.2.7
Published
Event-driven dual-LLM orchestration library for autonomous AI agents
Maintainers
Readme
oboto-agent
Event-driven dual-LLM orchestration library for autonomous AI agents.
oboto-agent is a lightweight TypeScript library that acts as the central nervous system for AI agents. It binds three specialized primitives together through a typed event bus:
- lmscript — LLM I/O, structured output, provider abstraction
- swiss-army-tool — Hierarchical tool execution
- as-agent — Session state and conversation history
Key Features
- Dual-LLM architecture — Fast local model (Ollama/LMStudio) for triage, powerful cloud model (Anthropic/OpenAI/Gemini) for complex tasks
- Automatic triage — Local model classifies each input and only escalates when needed
- Event-driven — All state transitions emit typed events for CLI, web, or daemon integration
- Context management — Automatic summarization when context window fills up
- Interruption handling — Users can redirect the agent mid-execution
- Platform-agnostic — No Node.js-specific APIs; works in browser, Deno, and Bun
- Headless — No UI framework dependency; bring your own interface
Installation
npm install @sschepis/oboto-agent
# Peer dependencies
npm install @sschepis/lmscript @sschepis/swiss-army-tool @sschepis/as-agent zodQuick Start
import { ObotoAgent } from "@sschepis/oboto-agent";
import { OllamaProvider, AnthropicProvider } from "@sschepis/lmscript";
import { TreeBuilder, Router, SessionManager } from "@sschepis/swiss-army-tool";
// Build tools
const builder = new TreeBuilder();
builder.leaf("time", "Get current time", {}, () => new Date().toISOString());
builder.leaf("greet", "Say hello", { name: "string" }, (args) => `Hello, ${args.name}!`);
const { root } = builder.build();
const router = new Router(root, new SessionManager("s1"));
// Create agent
const agent = new ObotoAgent({
localModel: new OllamaProvider({ baseUrl: "http://localhost:11434" }),
remoteModel: new AnthropicProvider({ apiKey: process.env.ANTHROPIC_API_KEY! }),
localModelName: "llama3:8b",
remoteModelName: "claude-sonnet-4-20250514",
router,
});
// Listen to events
agent.on("agent_thought", (e) => console.log(e.payload.text));
agent.on("tool_execution_complete", (e) => console.log("Tool:", e.payload.result));
agent.on("error", (e) => console.error(e.payload.message));
// Run
await agent.submitInput("What time is it?");Architecture
User Input
│
▼
┌──────────────────────────┐
│ ObotoAgent │
│ │
│ ┌─────────┐ ┌────────┐ │
│ │ Event │ │Context │ │
│ │ Bus │ │Manager │ │
│ └─────────┘ └────────┘ │
│ │
│ Triage (local LLM) │
│ ├── Simple → respond │
│ └── Complex → escalate │
│ │
│ AgentLoop (remote LLM) │
│ └── Tool calls → Router│
└──────────────────────────┘
│ │ │
▼ ▼ ▼
as-agent lmscript swiss-army-tool
(state) (LLM I/O) (tools)Execution Flow
- Input — User submits text via
submitInput() - Record — Message appended to session (as-agent) and context window (lmscript ContextStack)
- Triage — Local LLM classifies: simple or complex?
- Direct response — If simple, local model responds immediately
- Escalate — If complex, remote model runs with tool access via AgentLoop
- Tool execution — LLM calls tools through the swiss-army-tool Router
- Turn complete — Response recorded, events emitted
Events
| Event | Description |
|---|---|
| user_input | User submitted text |
| triage_result | Local LLM classified the input |
| agent_thought | LLM produced text output |
| tool_execution_start | Tool call began |
| tool_execution_complete | Tool call finished |
| state_updated | Session or context changed |
| interruption | User interrupted mid-execution |
| error | Something failed |
| turn_complete | Full turn finished |
API
ObotoAgent
const agent = new ObotoAgent(config: ObotoAgentConfig);
await agent.submitInput(text); // Submit user input
agent.interrupt(newDirectives?); // Halt and redirect
agent.on(event, handler); // Subscribe (returns unsub fn)
agent.once(event, handler); // One-time subscribe
agent.getSession(); // Get session state
agent.processing; // Is currently executing?
agent.removeAllListeners(); // Clear all subscriptionsConfiguration
interface ObotoAgentConfig {
localModel: LLMProvider; // Fast local model
remoteModel: LLMProvider; // Powerful cloud model
localModelName: string; // e.g. "llama3:8b"
remoteModelName: string; // e.g. "claude-sonnet-4-20250514"
router: Router; // swiss-army-tool Router
session?: Session; // Resume existing session
maxContextTokens?: number; // Default: 8192
maxIterations?: number; // Default: 10
systemPrompt?: string; // Custom system prompt
}Utility Exports
// Adapters
createRouterTool(router, root?) // Router → lmscript ToolDefinition
toChat(msg) // as-agent → lmscript message
fromChat(msg) // lmscript → as-agent message
sessionToHistory(session) // Session → ChatMessage[]
createEmptySession() // Fresh empty session
// Components
AgentEventBus // Standalone event emitter
ContextManager // Context window manager
createTriageFunction(modelName) // Triage LScriptFunction
TriageSchema // Zod schema for triage outputExamples
See the examples/ directory:
- basic-cli.ts — Interactive CLI agent with triage
- custom-tools.ts — Rich file system tool tree
- event-monitoring.ts — Log all agent events with colors
- session-persistence.ts — Save/restore sessions across restarts
Documentation
- Architecture — System design, data flow, adapter layer
- API Reference — Complete API documentation
- Guides — How-to guides for common tasks
Development
npm install # Install dependencies
npm run build # Build with tsup
npm test # Run tests with vitest
npm run typecheck # Type-check without emitting
npm run dev # Watch mode buildSupported Providers
Any lmscript provider works as either the local or remote model:
| Provider | Package | Typical Role |
|---|---|---|
| Ollama | OllamaProvider | Local |
| LM Studio | LMStudioProvider | Local |
| Anthropic | AnthropicProvider | Remote |
| OpenAI | OpenAIProvider | Remote |
| Google Gemini | GeminiProvider | Remote |
| OpenRouter | OpenRouterProvider | Remote |
| DeepSeek | DeepSeekProvider | Remote |
| AWS Bedrock | VertexAnthropicProvider | Remote |
License
MIT
