{"id":49336231,"url":"https://github.com/awakenworks/awaken","last_synced_at":"2026-04-27T01:01:56.793Z","repository":{"id":339874589,"uuid":"1163697946","full_name":"awakenworks/awaken","owner":"awakenworks","description":"AI agent runtime for Rust — type-safe state, multi-protocol serving, plugin extensibility.","archived":false,"fork":false,"pushed_at":"2026-04-25T07:49:47.000Z","size":257063,"stargazers_count":67,"open_issues_count":27,"forks_count":5,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-25T16:13:19.707Z","etag":null,"topics":["a2a","a2ui","acp","ag-ui","agent-framework","ai","ai-agent","ai-sdk-v6","copilotkit","human-in-the-loop","llm","mcp","multi-agent","opentelemetry","openui","rust"],"latest_commit_sha":null,"homepage":"https://awakenworks.github.io/awaken/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/awakenworks.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-02-22T02:10:57.000Z","updated_at":"2026-04-25T07:49:46.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/awakenworks/awaken","commit_stats":null,"previous_names":["tirea-ai/tirea","awakenworks/tirea","awakenworks/awaken"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/awakenworks/awaken","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awakenworks%2Fawaken","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awakenworks%2Fawaken/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awakenworks%2Fawaken/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awakenworks%2Fawaken/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/awakenworks","download_url":"https://codeload.github.com/awakenworks/awaken/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awakenworks%2Fawaken/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32318417,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T23:26:28.701Z","status":"ssl_error","status_checked_at":"2026-04-26T23:26:25.802Z","response_time":129,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["a2a","a2ui","acp","ag-ui","agent-framework","ai","ai-agent","ai-sdk-v6","copilotkit","human-in-the-loop","llm","mcp","multi-agent","opentelemetry","openui","rust"],"created_at":"2026-04-27T01:01:55.761Z","updated_at":"2026-04-27T01:01:56.780Z","avatar_url":"https://github.com/awakenworks.png","language":"Rust","funding_links":[],"categories":["Libraries","⚙️ Implementations \u0026 Libraries"],"sub_categories":["Artificial Intelligence"],"readme":"# Awaken\n\n[English](./README.md) | [中文](./README.zh-CN.md)\n\n[![CI](https://github.com/AwakenWorks/awaken/actions/workflows/test.yml/badge.svg)](https://github.com/AwakenWorks/awaken/actions/workflows/test.yml) [![crates.io awaken](https://img.shields.io/crates/v/awaken.svg?label=awaken)](https://crates.io/crates/awaken) [![crates.io awaken-agent](https://img.shields.io/crates/v/awaken-agent.svg?label=awaken-agent)](https://crates.io/crates/awaken-agent) [![Changelog](https://img.shields.io/badge/changelog-0.4.0-informational)](./CHANGELOG.md) ![License](https://img.shields.io/badge/license-MIT%2FApache--2.0-blue) ![MSRV](https://img.shields.io/badge/MSRV-1.93-orange)\n\nA Rust agent runtime that serves AI SDK, CopilotKit, A2A, and MCP from the same backend, recovers from mid-stream LLM failures, and treats configuration as the control plane.\n\n`awaken` is the canonical crate (transferred to this project from\n[@brayniac](https://github.com/brayniac); see the acknowledgement below).\n`awaken-agent` is a thin compatibility republish from when the project shipped\nunder that name. Import path is `awaken` either way. MSRV: Rust 1.93.\n\nDocs: [GitHub Pages](https://awakenworks.github.io/awaken/) · [Chinese docs](https://awakenworks.github.io/awaken/zh-CN/) · [Changelog](./CHANGELOG.md)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./docs/assets/demo.svg\" alt=\"Awaken demo — tool call + LLM streaming\" width=\"800\"\u003e\n\u003c/p\u003e\n\n## What you get in 0.4\n\n- **Multi-protocol from one backend.** A single runtime serves AI SDK v6, AG-UI / CopilotKit, A2A, and MCP. The same `/v1/runs` powers all of them.\n- **Streaming LLM calls survive transient failures.** Mid-stream interruptions and idle stalls are detected and recovered through four explicit plans (continue text, replay completed tool calls, restart with a cancelled-tool hint, or whole restart). `Retry-After` is honored. A `StreamCheckpointStore` contract extends the same recovery across process restarts. ([details](./docs/book/src/how-to/recover-streaming-llms.md))\n- **Threads have a parent-child lineage.** Sub-agent runs create child threads; deletion is explicit (`reject` / `detach` / `cascade`). Filters and cursors on `/v1/threads` make hierarchical UIs straightforward.\n- **Secrets stay redacted.** `ProviderSpec.api_key`, admin and A2A bearer tokens are wrapped in `RedactedString` — `Debug`/`Display` print `***`, the buffer is zeroized on drop, and the JSON wire format is unchanged.\n- **Configuration is the control plane.** Models, providers, prompts, reminders, permissions, and tool-loading policy live behind `/v1/config/*` and `/v1/capabilities`. Apply bursts can be debounced and provider executors are reused across unchanged specs.\n- **Type-safe state and tools.** Typed `StateKey`s with merge strategies, generated JSON Schema for `TypedTool`, atomic batched commits after each phase. `unsafe_code = \"forbid\"` workspace-wide.\n\n## Mental model\n\n1. **Tools** — implement `Tool` directly, or `TypedTool` with `schemars`-generated JSON Schema.\n2. **Agents** — system prompt, model binding, allowed tools. The LLM orchestrates through natural language; there is no DAG.\n3. **State** — typed run/thread state plus persistent profile and shared state for cross-thread or cross-agent coordination.\n4. **Plugins** — lifecycle hooks for permission, observability, context management, skills, MCP, generative UI.\n\nThe runtime drives 9 typed phases per round, including a pure `ToolGate` before tool execution. State mutations are batched and committed atomically.\n\n## Quickstart\n\nPrerequisites: Rust 1.93+ and an OpenAI-compatible API key.\n\n```toml\n[dependencies]\nawaken = { version = \"0.4.0\" }\ntokio = { version = \"1.51.0\", features = [\"full\"] }\nasync-trait = \"0.1.89\"\nserde_json = \"1.0.149\"\n```\n\n```bash\nexport OPENAI_API_KEY=\u003cyour-key\u003e\n```\n\nCopy this into `src/main.rs` and run `cargo run`:\n\n```rust,no_run\nuse std::sync::Arc;\nuse serde_json::{json, Value};\nuse async_trait::async_trait;\nuse awaken::contract::tool::{Tool, ToolDescriptor, ToolResult, ToolOutput, ToolError, ToolCallContext};\nuse awaken::contract::message::Message;\nuse awaken::engine::GenaiExecutor;\nuse awaken::registry_spec::AgentSpec;\nuse awaken::registry::ModelBinding;\nuse awaken::{AgentRuntimeBuilder, RunRequest};\n\nstruct EchoTool;\n\n#[async_trait]\nimpl Tool for EchoTool {\n    fn descriptor(\u0026self) -\u003e ToolDescriptor {\n        ToolDescriptor::new(\"echo\", \"Echo\", \"Echo input back to the caller\")\n            .with_parameters(json!({\n                \"type\": \"object\",\n                \"properties\": { \"text\": { \"type\": \"string\" } },\n                \"required\": [\"text\"]\n            }))\n    }\n\n    async fn execute(\u0026self, args: Value, _ctx: \u0026ToolCallContext) -\u003e Result\u003cToolOutput, ToolError\u003e {\n        let text = args[\"text\"].as_str().unwrap_or_default();\n        Ok(ToolResult::success(\"echo\", json!({ \"echoed\": text })).into())\n    }\n}\n\n#[tokio::main]\nasync fn main() -\u003e Result\u003c(), Box\u003cdyn std::error::Error\u003e\u003e {\n    let agent_spec = AgentSpec::new(\"assistant\")\n        .with_model_id(\"gpt-4o-mini\")\n        .with_system_prompt(\"You are a helpful assistant. Use the echo tool when asked.\")\n        .with_max_rounds(5);\n\n    let runtime = AgentRuntimeBuilder::new()\n        .with_agent_spec(agent_spec)\n        .with_tool(\"echo\", Arc::new(EchoTool))\n        .with_provider(\"openai\", Arc::new(GenaiExecutor::new()))\n        .with_model_binding(\"gpt-4o-mini\", ModelBinding {\n            provider_id: \"openai\".into(),\n            upstream_model: \"gpt-4o-mini\".into(),\n        })\n        .build()?;\n\n    let request = RunRequest::new(\n        \"thread-1\",\n        vec![Message::user(\"Say hello using the echo tool\")],\n    )\n    .with_agent_id(\"assistant\");\n\n    // The quickstart only needs the final result. Use run(..., sink) when\n    // streaming events to SSE, WebSocket, protocol adapters, or tests.\n    let result = runtime.run_to_completion(request).await?;\n    println!(\"response: {}\", result.response);\n    println!(\"termination: {:?}\", result.termination);\n\n    Ok(())\n}\n```\n\nThe quickstart path is covered without network access:\n\n```bash\ncargo test -p awaken --test readme_quickstart\n```\n\nLive provider validation is opt-in so CI does not depend on external model services:\n\n```bash\nOPENAI_API_KEY=\u003cyour-key\u003e cargo test -p awaken --test readme_live_provider -- --ignored\n```\n\n## Serve over any protocol\n\nStart the built-in server and connect from React, Next.js, or another agent — no code changes:\n\n```rust,no_run\nuse awaken::prelude::*;\nuse awaken::stores::{InMemoryMailboxStore, InMemoryStore};\nuse std::sync::Arc;\n\nlet store = Arc::new(InMemoryStore::new());\nlet runtime = Arc::new(runtime);\nlet mailbox = Arc::new(Mailbox::new(\n    runtime.clone(),\n    Arc::new(InMemoryMailboxStore::new()),\n    store.clone(),\n    \"default-consumer\".into(),\n    MailboxConfig::default(),\n));\n\nlet state = AppState::new(\n    runtime.clone(),\n    mailbox,\n    store,\n    runtime.resolver_arc(),\n    ServerConfig::default(),\n);\nserve(state).await?;\n```\n\n#### Frontend protocols\n\n| Protocol | Endpoint | Frontend |\n|---|---|---|\n| AI SDK v6 | `POST /v1/ai-sdk/chat` | React `useChat()` |\n| AG-UI | `POST /v1/ag-ui/run` | CopilotKit `\u003cCopilotKit\u003e` |\n| A2A | `POST /v1/a2a/message:send` | Other agents |\n| MCP | `POST /v1/mcp` | JSON-RPC 2.0 |\n\nThe optional admin console reads `/v1/capabilities` and writes through\n`/v1/config/*` to manage agents, models, providers, MCP servers, and plugin\nconfig sections. Plugins expose their schema via the same typed\n`PluginConfigKey` used at runtime, so saving an agent's `permission`,\n`reminder`, `generative-ui`, or `deferred_tools` section publishes a new\nregistry snapshot that takes effect on the next `/v1/runs` request.\nOpenAI-compatible providers (including BigModel) use the `openai` adapter\nwith their own `base_url`; non-secret extras go in `ProviderSpec.adapter_options`.\n\n| Tuning surface | Where it lives |\n|---|---|\n| Base prompt | `AgentSpec.system_prompt` |\n| Model and provider routing | `AgentSpec.model_id` + `/v1/config/models` + `/v1/config/providers` |\n| System reminders and prompt injection | `reminder` plugin section |\n| Generative UI prompt guidance | `generative-ui` plugin section |\n| Tool policy and context cost | `permission` and `deferred_tools` plugin sections |\n\n**React + AI SDK v6:**\n\n```typescript\nimport { useChat } from \"@ai-sdk/react\";\nimport { DefaultChatTransport } from \"ai\";\n\nconst { messages, sendMessage } = useChat({\n  transport: new DefaultChatTransport({\n    api: \"http://localhost:3000/v1/ai-sdk/chat\",\n  }),\n});\n```\n\n**Next.js + CopilotKit:**\n\n```typescript\nimport { CopilotKit } from \"@copilotkit/react-core\";\n\n\u003cCopilotKit runtimeUrl=\"http://localhost:3000/v1/ag-ui/run\"\u003e\n  \u003cYourApp /\u003e\n\u003c/CopilotKit\u003e\n```\n\n#### Managed configuration\n\nWire a `ConfigStore` into `AppState` to manage agents, models, providers, and MCP servers through `/v1/config/*`. Use the [configuration-driven tuning guide](https://awakenworks.github.io/awaken/how-to/configure-agent-behavior.html) to tune providers, model bindings, tools, and plugin sections. The Admin Console in [`apps/admin-console`](./apps/admin-console/) uses the same API and reads `VITE_BACKEND_URL` for the server base URL.\n\n## Built-in plugins\n\nThe facade `full` feature pulls in the plugins below. Use\n`default-features = false` to opt out. `awaken-ext-deferred-tools` is not\nre-exported by the facade and is added as a direct dependency.\n\n| Plugin | What it does | Feature flag |\n|---|---|---|\n| **Permission** | Allow/Deny/Ask rules with glob and regex matching on tool name and arguments. Deny beats Allow beats Ask; Ask suspends the run via the mailbox for HITL. | `permission` |\n| **Reminder** | Injects system or conversation-level context messages when a tool call matches a configured pattern. | `reminder` |\n| **Observability** | OpenTelemetry traces and metrics aligned with the GenAI Semantic Conventions; OTLP, file, and in-memory exports. | `observability` |\n| **MCP** | Connects to external MCP servers and registers their tools as native Awaken tools. | `mcp` |\n| **Skills** | Discovers skill packages and injects a catalog before inference so the LLM can activate skills on demand. | `skills` |\n| **Generative UI** | Streams declarative UI components to frontends via A2UI, JSON Render, and OpenUI Lang integrations. | `generative-ui` |\n| **Deferred Tools** | Hides large tool schemas behind a `ToolSearch` step, then re-defers tools that have been idle for a configurable number of turns using a discounted Beta usage model. | direct crate: `awaken-ext-deferred-tools` |\n\nCustom tool interception goes through `ToolGateHook` via\n`PluginRegistrar::register_tool_gate_hook()`. `BeforeToolExecute` is reserved\nfor execution-time hooks that only run when a tool is actually about to execute.\n\n## When this fits\n\n- You want a **Rust backend** for AI agents with compile-time guarantees.\n- You need to serve **AI SDK, CopilotKit, A2A, and/or MCP** from a single backend.\n- Tools need to **share state safely** during concurrent execution, and runs need **auditable history** with checkpoints and resume.\n- You're comfortable registering your own tools and providers instead of relying on batteries-included defaults.\n\n## When it doesn't\n\n- You need **built-in file/shell/web tools** out of the box — consider OpenAI Agents SDK, Dify, or CrewAI.\n- You want a **visual workflow builder** — consider Dify or LangGraph Studio.\n- You want **Python** and rapid prototyping — consider LangGraph, AG2, or PydanticAI.\n- You need an **LLM-managed memory** subsystem where the agent decides what to remember — consider Letta.\n\n## Architecture\n\nAwaken 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.\n\nAround 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.\n\n```text\nawaken                   Facade crate with feature flags\n├─ awaken-contract       Contracts: specs, tools, events, transport, state model\n├─ awaken-runtime        Resolver, phase engine, loop runner, runtime control\n├─ awaken-server         Routes, mailbox, SSE transport, protocol adapters\n├─ awaken-stores         Memory, file, PostgreSQL, and SQLite-backed stores\n├─ awaken-tool-pattern   Glob/regex matching used by extensions\n└─ awaken-ext-*          Optional runtime extensions\n```\n\n## Examples and learning paths\n\n| Example | What it shows |\n|---|---|\n| [`live_test`](./crates/awaken/examples/live_test.rs) | Basic LLM integration |\n| [`multi_turn`](./crates/awaken/examples/multi_turn.rs) | Multi-turn with persistent threads |\n| [`tool_call_live`](./crates/awaken/examples/tool_call_live.rs) | Tool calling with calculator |\n| [`ai-sdk-starter`](./examples/ai-sdk-starter/) | React + AI SDK v6 full-stack |\n| [`copilotkit-starter`](./examples/copilotkit-starter/) | Next.js + CopilotKit full-stack |\n| [`openui-chat`](./examples/openui-chat/) | OpenUI Lang chat frontend |\n| [`admin-console`](./apps/admin-console/) | Config API management UI |\n\n```bash\nexport OPENAI_API_KEY=\u003cyour-key\u003e\ncargo run --package awaken --example multi_turn\n\ncd examples/ai-sdk-starter \u0026\u0026 npm install \u0026\u0026 npm run dev\n\n# Terminal 1: starter backend for admin console\nAWAKEN_STORAGE_DIR=./target/admin-sessions cargo run -p ai-sdk-starter-agent\n\n# Terminal 2: admin console\nnpm --prefix apps/admin-console install\nnpm --prefix apps/admin-console run dev\n```\n\n| Goal | Start with | Then |\n|---|---|---|\n| Build your first agent | [Get Started](https://awakenworks.github.io/awaken/get-started.html) | [Build Agents](https://awakenworks.github.io/awaken/build-agents.html) |\n| See a full-stack app | [AI SDK starter](./examples/ai-sdk-starter/) | [CopilotKit starter](./examples/copilotkit-starter/) |\n| Manage runtime config | [Admin Console](./apps/admin-console/) | [Configure Agent Behavior](https://awakenworks.github.io/awaken/how-to/configure-agent-behavior.html) |\n| Explore the API | [Reference docs](https://awakenworks.github.io/awaken/reference/overview.html) | `cargo doc --workspace --no-deps --open` |\n| Understand the runtime | [Architecture](https://awakenworks.github.io/awaken/explanation/architecture.html) | [Run Lifecycle and Phases](https://awakenworks.github.io/awaken/explanation/run-lifecycle-and-phases.html) |\n| Migrate from tirea | [Migration guide](https://awakenworks.github.io/awaken/appendix/migration-from-tirea.html) | |\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md) and [DEVELOPMENT.md](./DEVELOPMENT.md) for setup details.\n\n[Good first issues](https://github.com/AwakenWorks/awaken/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) are a great entry point. Quick contribution flow: fork → create a branch → write tests → open a PR.\n\nAreas where contributions are especially welcome:\n\n- Additional mailbox, config, and storage backends beyond the built-in memory/file/PostgreSQL/SQLite options\n- Built-in tool implementations (file read/write, web search)\n- Token cost tracking and budget enforcement\n- Model fallback/degradation chains\n\nJoin the conversation on [GitHub Discussions](https://github.com/AwakenWorks/awaken/discussions).\n\n## Acknowledgement\n\nThe `awaken` crate name on crates.io was generously transferred from\n[@brayniac](https://github.com/brayniac), who maintained an earlier crate\nunder the same name and offered to hand it over so this project could publish\ncanonically. Versions `0.1`–`0.3` of `awaken` on crates.io belong to that\nearlier project; this codebase resumes the line that previously shipped as\n`awaken-agent 0.2.x` and starts at `0.4.0` to skip past the prior versions.\nThank you.\n\nAwaken is also a ground-up rewrite of [tirea](../../tree/tirea-0.5) and is not\nbackwards-compatible with it. The tirea 0.5 codebase remains archived on the\n[`tirea-0.5`](../../tree/tirea-0.5) branch.\n\n## License\n\nDual-licensed under [MIT](./LICENSE-MIT) or [Apache-2.0](./LICENSE-APACHE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawakenworks%2Fawaken","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fawakenworks%2Fawaken","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawakenworks%2Fawaken/lists"}