Awaken
Production AI agent runtime for Rust — type-safe state, multi-protocol serving, plugin extensibility.
Published on crates.io as awaken-agent; keep importing it in Rust as awaken.
The workspace uses Rust 1.93.0 for development; the crate MSRV is 1.85.
Docs: GitHub Pages | Chinese docs
Highlights
- Rust-first agent runtime: typed tools, generated JSON Schema, typed state keys, scoped snapshots, and atomic state commits.
- One runtime, many clients: HTTP/SSE run API, AI SDK v6, AG-UI/CopilotKit, A2A, and MCP JSON-RPC from the same backend.
- Configuration-first optimization: choose models/providers, tune prompts, reminders, permissions, generative UI, and deferred tools through
/v1/config/*,/v1/capabilities, and the admin console. - Production control paths: mailbox-backed background runs, HITL decisions, cancellation/interrupt, SSE replay, retries, fallback models, circuit breakers, metrics, and health probes.
- Plugin surface: permission gates, reminders, OpenTelemetry, MCP tools, skills, generative UI, and deferred tool loading with an explicit probability model.
30-second mental model
- Tools — implement
Tooldirectly orTypedToolwithschemars-generated JSON Schema - Agents — each agent has a system prompt, a model, and a set of allowed tools; the LLM drives orchestration through natural language — no predefined graphs
- State — typed run/thread state plus persistent profile/shared state for cross-thread or cross-agent coordination
- Plugins — lifecycle hooks for permissions, observability, context management, skills, MCP, and more
Your agent picks tools, calls them, reads and updates state, and repeats — all orchestrated by the runtime through 9 typed phases, including a pure ToolGate before tool execution. Every state change is committed atomically after the gather phase.
Try it in 5 minutes
Prerequisites: Rust 1.85+ for the published crate, or the pinned rust-toolchain.toml
toolchain when working from this repository, plus an LLM provider API key.
- Rust 1.85 or newer. This repository pins Rust 1.93.0 for local development.
- An OpenAI-compatible API key.
[]
= { = "awaken-agent", = "0.2" }
= { = "1.51.0", = ["full"] }
= "0.1.89"
= "1.0.149"
Copy this into src/main.rs and run cargo run:
use Arc;
use ;
use async_trait;
use ;
use Message;
use GenaiExecutor;
use AgentSpec;
use ModelBinding;
use ;
;
async
The quickstart path is covered without network access:
Live provider validation is opt-in so CI does not depend on external model services:
OPENAI_API_KEY=<your-key> cargo
Serve over any protocol
Start the built-in server and connect from React, Next.js, or another agent — no code changes:
use *;
use ;
use Arc;
let store = new;
let runtime = new;
let mailbox = new;
let state = new;
serve.await?;
Frontend protocols
| Protocol | Endpoint | Frontend |
|---|---|---|
| AI SDK v6 | POST /v1/ai-sdk/chat |
React useChat() |
| AG-UI | POST /v1/ag-ui/run |
CopilotKit <CopilotKit> |
| A2A | POST /v1/a2a/message:send |
Other agents |
| MCP | POST /v1/mcp |
JSON-RPC 2.0 |
The optional admin console uses /v1/capabilities and /v1/config/* to edit
agents, models, providers, MCP servers, and plugin config sections in the
browser. Plugins expose JSON Schema through the same typed PluginConfigKey
path used by runtime hooks, so saving an agent section such as permission,
reminder, generative-ui, or deferred_tools publishes a new registry
snapshot and applies to subsequent /v1/runs requests. OpenAI-compatible
providers, including BigModel, use the openai adapter with a provider-specific
base_url.
The design intent is that agent optimization stays data-driven: model choice, provider endpoints, base prompts, system reminders, generated-UI instructions, permission policy, and tool-loading policy should be configured through the same schema-backed path rather than hard-coded into the agent loop.
| Tuning surface | Configuration path |
|---|---|
| Base prompt | AgentSpec.system_prompt on the agent entry |
| Model and provider routing | AgentSpec.model_id, /v1/config/models, /v1/config/providers |
| System reminders and prompt context injection | reminder plugin section, using system or suffix_system targets |
| Generative UI prompt guidance | generative-ui plugin section (catalog_id, examples, or full instructions) |
| Tool policy and context cost | permission and deferred_tools plugin sections |
| Prompt semantic hooks | Not a built-in plugin yet; add them as typed PluginConfigKey sections with schema-backed hooks |
React + AI SDK v6:
import { useChat } from "ai/react";
const { messages, input, handleSubmit } = useChat({
api: "http://localhost:3000/v1/ai-sdk/chat",
});
Next.js + CopilotKit:
import { CopilotKit } from "@copilotkit/react-core";
<CopilotKit runtimeUrl="http://localhost:3000/v1/ag-ui/run">
<YourApp />
</CopilotKit>
Managed configuration
Wire a ConfigStore into AppState to manage agents, models, providers, and MCP servers through /v1/config/*. Use the configuration-driven tuning guide to tune providers, model bindings, tools, and plugin sections. The Admin Console in apps/admin-console uses the same API and reads VITE_BACKEND_URL for the server base URL.
Built-in plugins
Facade features are enabled by default via the full feature. Use
default-features = false to opt out. Workspace extension crates that are not
re-exported by the facade, such as deferred tools, are added as direct
dependencies.
| Plugin | What it does | Feature flag |
|---|---|---|
| Permission | Firewall-style tool access control with Deny/Allow/Ask rules, glob/regex matching, and HITL suspension via mailbox. | permission |
| Reminder | Injects system or conversation-level context messages when tool calls match configured patterns. | reminder |
| Observability | OpenTelemetry telemetry aligned with GenAI Semantic Conventions; supports OTLP, file, and in-memory export. | observability |
| MCP | Connects to external MCP servers and registers their tools as native Awaken tools. | mcp |
| Skills | Discovers skill packages and injects a catalog before inference so the LLM can activate skills on demand. | skills |
| Generative UI | Streams declarative UI components to frontends via A2UI, JSON Render, and OpenUI Lang integrations. | generative-ui |
| Deferred Tools | Hides large tool schemas behind ToolSearch, then uses a discounted Beta probability model to re-defer idle promoted tools. |
direct crate: awaken-ext-deferred-tools |
Deferred tools are configured through the deferred_tools agent section when
the ext-deferred-tools plugin is registered. See
Use Deferred Tools for setup,
the activation heuristic, and the DiscBeta probability model.
Custom interception hooks should use ToolGateHook via PluginRegistrar::register_tool_gate_hook(). BeforeToolExecute is reserved for execution-time hooks that run only when a tool is actually about to execute.
Why Awaken
- One backend serves multiple protocols: AI SDK v6, AG-UI, A2A, MCP, plus native HTTP/SSE routes.
- Configuration is the control plane: model/provider routing, prompts, reminders, permissions, and tool-loading policy use schema-backed config that can be validated and applied at runtime.
- The LLM orchestrates: define the agent identity, model binding, and tool access; no hand-coded DAG is required.
- Runtime-managed configuration updates agents, model bindings, providers, and MCP servers through the Config API or Admin Console.
- Plugin extension points are typed: 9 lifecycle phases,
PhaseHook,ToolGateHook, scheduled actions, effects, request transforms, and plugin-provided tools. - State is type-safe:
StateKeybinds each key to Rust value/update types, scopes it to run/thread/profile, and applies declared merge strategies before commit. - Operational surfaces are built in: LLM retry/backoff, per-model circuit breaker, request timeout, graceful shutdown, Prometheus metrics, health probes, and mailbox retry/backoff.
- Zero
unsafe— the entire workspace forbidsunsafeand relies on the Rust compiler for memory safety.
When to use Awaken
- You want a Rust backend for AI agents with compile-time safety
- You need to serve multiple frontend or agent protocols from one backend
- Your tools need to safely share state during concurrent execution
- You need auditable thread history, checkpoints, and resumable control paths
- You are comfortable wiring your own tools, providers, and model registry instead of relying on batteries-included defaults
When NOT to use Awaken
- You need built-in file/shell/web tools out of the box — consider OpenAI Agents SDK, Dify, or CrewAI
- You want a visual workflow builder — consider Dify, LangGraph Studio
- You want Python and rapid prototyping — consider LangGraph, AG2, PydanticAI
- You need a stable, slow-moving surface area more than an evolving runtime platform
- You need LLM-managed memory (agent decides what to remember) — consider Letta
Architecture
Awaken is split into three runtime layers. awaken-contract defines the shared contracts: agent specs, model/provider specs, tools, events, transport traits, and the typed state model. awaken-runtime resolves an AgentSpec into ResolvedExecution: local agents become a ResolvedAgent with an ExecutionEnv built from plugins, while endpoint-backed agents run through an ExecutionBackend. It also executes the phase loop and manages active runs plus external control such as cancellation and HITL decisions. awaken-server exposes that same runtime through HTTP routes, SSE replay, mailbox-backed background execution, and protocol adapters for AI SDK v6, AG-UI, A2A, and MCP.
Around those layers sit storage and extensions. awaken-stores provides memory, file, and PostgreSQL persistence for threads and runs; memory, file, and PostgreSQL config stores; memory and SQLite mailbox stores; and memory/file profile stores. awaken-ext-* crates extend the runtime at phase and tool boundaries.
awaken Facade crate with feature flags
├─ awaken-contract Contracts: specs, tools, events, transport, state model
├─ awaken-runtime Resolver, phase engine, loop runner, runtime control
├─ awaken-server Routes, mailbox, SSE transport, protocol adapters
├─ awaken-stores Memory, file, PostgreSQL, and SQLite-backed stores
├─ awaken-tool-pattern Glob/regex matching used by extensions
└─ awaken-ext-* Optional runtime extensions
Examples and learning paths
| Example | What it shows |
|---|---|
live_test |
Basic LLM integration |
multi_turn |
Multi-turn with persistent threads |
tool_call_live |
Tool calling with calculator |
ai-sdk-starter |
React + AI SDK v6 full-stack |
copilotkit-starter |
Next.js + CopilotKit full-stack |
openui-chat |
OpenUI Lang chat frontend |
admin-console |
Config API management UI |
&& &&
# Terminal 1: starter backend for admin console
AWAKEN_STORAGE_DIR=./target/admin-sessions
# Terminal 2: admin console
| Goal | Start with | Then |
|---|---|---|
| Build your first agent | Get Started | Build Agents |
| See a full-stack app | AI SDK starter | CopilotKit starter |
| Manage runtime config | Admin Console | Configure Agent Behavior |
| Explore the API | Reference docs | cargo doc --workspace --no-deps --open |
| Understand the runtime | Architecture | Run Lifecycle and Phases |
| Migrate from tirea | Migration guide |
Contributing
See CONTRIBUTING.md and DEVELOPMENT.md for setup details.
Good first issues are a great entry point. Quick contribution flow: fork → create a branch → write tests → open a PR.
Areas where contributions are especially welcome:
- Additional mailbox, config, and storage backends beyond the built-in memory/file/PostgreSQL/SQLite options
- Built-in tool implementations (file read/write, web search)
- Token cost tracking and budget enforcement
- Model fallback/degradation chains
Join the conversation on GitHub Discussions.
Awaken is a ground-up rewrite of tirea; it is not backwards-compatible. The tirea 0.5 codebase is archived on the tirea-0.5 branch.
License
Dual-licensed under MIT or Apache-2.0.