Skip to content

Latest commit

 

History

170 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

ClawSeed

An on-device Android AI agent powered by Rust.

Download the latest Android APK

License Rust Edition 2024 CI English | 中文


ClawSeed is a mobile AI agent you can run on your Android phone. The app runs the Rust gateway, agent loop, memory, and tools on-device, then connects to the LLM provider you choose. It is also an open-source runtime and SDK for building your own agents and Android integrations.

Try ClawSeed on Android

Download the latest APK and install it on an Android device. Open the app, configure a provider and model in Settings, then start a conversation. Published APKs and release notes are available on the GitHub Releases page.

The Android app includes:

  • Streaming Markdown chat with images, PDF, DOCX, Markdown, text, and CSV attachments
  • Personas with their own personality, model, thinking mode, memory, tools, and skills
  • User profiles, conversation memory, scheduled prompts, and optional speech output
  • Device tools such as device information and location
  • Tools supplied by other Android apps through the CETP protocol
  • Provider presets for DeepSeek, Qwen, OpenAI-compatible APIs, Anthropic, Ollama, and more
  • Light, dark, and OLED themes, session management, regeneration, and usage metrics

The agent stack runs on the phone; the selected LLM provider is normally reached over the network. See the Android guide for setup details and the attachment guide for supported formats and limits.

What is ClawSeed?

ClawSeed is both a ready-to-use Android application and a Rust AI agent runtime. The application is the quickest way to try it. The runtime provides stable traits and reusable crates for developers who want to build a CLI, bot, mobile client, or embedded agent of their own.

NEWS

  • 2026-09-11: ClawSeed Android 2.0.0 brings image and file conversations: attach images, PDF, DOCX, Markdown, text, and CSV files; browse recent photos or choose Camera, Gallery, and Files from the attachment picker; and share images and files from other Android apps into a new conversation draft. This update also improves photo preview and upload performance, chat scrolling, session resource usage, and LLM usage metrics. See the attachment guide for supported formats and limits.
  • 2026-07-03: ClawSeed now officially supports personas.

Runtime for developers

An agent runtime should do three things: receive messages, call an LLM, and execute tools. Everything else — channels, dashboards, and integrations — belongs to the application layer. ClawSeed provides crates with stable traits; applications compose them.

# A Discord bot application
[dependencies]
clawseed-agent = "0.7"
clawseed-providers = "0.7"
serenity = "0.12"          # App chooses its own SDK

# An Android application
[dependencies]
clawseed-gateway = "0.7"
clawseed-agent = "0.7"

# A CLI tool
[dependencies]
clawseed-agent = "0.7"
clawseed-tools = "0.7"

In the included Android app, the gateway and agent run on the device. In other deployments, the agent can run on a server while Android, iOS, or another client registers device tools over WebSocket. When the agent calls one of these tools, the gateway forwards the request to the client for execution.

ClawSeed borrows its trait-based architecture from ZeroClaw, with a smaller scope and a different positioning: ZeroClaw bundles channels, dashboards, hardware, and SOP into one application; ClawSeed provides crates for applications to assemble. ClawSeed also adds an Android app, extended thinking support, and a modular prompt builder.

Architecture

┌──────────────────────────────────────────────────────────┐
│                  gateway (REST / WebSocket)               │
│                       ↓                                   │
│  ┌──────────────────────────────────────────────────┐    │
│  │              Agent (stable core)                  │    │
│  │     turn → LLM → dispatch → execute → loop       │    │
│  └──┬──────────┬──────────┬──────────┬─────────────┘    │
│     │          │          │          │                    │
│  provider    tools      memory    hooks                  │
│  (dyn)     (dyn)       (dyn)    (pipeline)               │
│     │          │          │          │                    │
│  Anthropic   25+        SQLite   security                │
│  Gemini      built-in   vector   audit                   │
│  Bedrock                search   approval                │
│  OpenAI*     + remote ──→ mobile client                  │
│  Ollama                                                  │
│  DeepSeek                                                │
│  Groq                                                    │
└──────────────────────────────────────────────────────────┘
   * and any OpenAI-compatible endpoint

Dependency flow is one-way: api ← agent ← tools / providers / memory ← gateway. Nothing points back up. Note that at runtime, Agent::from_config_with_registry() directly instantiates provider, memory, and tools — the agent crate is not a pure orchestration layer, it also owns runtime assembly. In the gateway, Agent::from_config_with_shared_components() reuses shared AppState components (provider, memory, observer, BuiltIn tool instances) across connections instead of creating new ones per connection.

Remote tool calls

Mobile clients register tool specs when they connect over WebSocket. The gateway wraps each spec as a RemoteTool — a Tool trait implementation that bridges execution to the client:

┌──────────────┐     register_tools       ┌──────────────┐
│   Mobile     │ ───────────────────────→ │   Gateway    │
│   Client     │                          │              │
│              │ ←── tool_call_request ── │   Agent      │
│  (executes   │ ──── tool_result ──────→ │   calls it   │
│   on device) │                          │   like any   │
│              │ ←── result_acknowledged─ │   other tool │
└──────────────┘                          └──────────────┘

Flow:

  1. Client connects and sends register_tools with tool specs (name, description, JSON Schema)
  2. Gateway creates a RemoteTool for each spec, registers to shared AppState.tool_registry (for /api/tools visibility) and injects into the per-connection Agent's tool registry (for actual execution)
  3. Agent calls the tool; RemoteTool::execute() sends tool_call_request to client over WebSocket
  4. Client executes locally, responds with tool_result or tool_error
  5. Gateway correlates response by call ID (30s timeout), returns result to agent
  6. On disconnect, gateway removes the session's remote tools from the shared registry via unregister_by_source()

The agent loop has no branching for remote vs. local tools — both implement the Tool trait. Remote tools do not use ToolContext (no access to server-side memory, security policy, or other capabilities).

Note: There are two independent tool registries at runtime — AppState.tool_registry (gateway-wide, for /api/tools endpoint visibility) and Agent.tool_registry (per-connection, for actual tool dispatch). In single-connection scenarios they stay in sync, but with multiple concurrent connections, /api/tools may show tools that a given agent cannot actually invoke.

Android SDK

val client = ClawseedClient(
    gatewayUrl = "ws://localhost:3000/ws/chat",
    tools = listOf(
        ToolSpec("local_contacts", "Query phone contacts", contactsSchema),
        ToolSpec("camera", "Take a photo", cameraSchema),
    )
) { request ->
    when (request.name) {
        "local_contacts" -> ToolCallResult.Success(queryContacts(request.args))
        "camera" -> ToolCallResult.Success(takePhoto(request.args))
        else -> ToolCallResult.Failure("unknown tool")
    }
}
client.connect()

The SDK also runs the gateway binary on-device as a foreground service — the entire agent stack runs on the Android device, with the LLM provider accessed over the network.

Android Demo App

A full-featured Android chat client is included at clients/android/. It runs the clawseed gateway natively (compiled as .so), providing:

  • Real-time streaming chat with Markdown rendering (headings, code blocks, tables, bold/italic)
  • Extended thinking display — collapsible cards showing the model's chain-of-thought
  • Session management (create, resume, rename, delete, auto-naming)
  • Regenerate — re-generate last assistant response with a single tap
  • On-device tools: device_info, get_location (WGS84 to GCJ-02 with reverse geocoding)
  • Scheduled background tasks — AlarmManager-based prompts with repeat modes (daily/weekday/once)
  • Soul customization — in-app personality editor for workspace SOUL.md
  • Appearance settings — light/dark/system theme with OLED mode
  • LLM configuration UI with 11 provider presets (DeepSeek, Qwen, OpenAI, Anthropic, Ollama, etc.)
  • Thinking mode toggle for models that support extended thinking (e.g. DeepSeek V4)
  • Debug mode showing full LLM prompt and token estimates

See clients/android/README.md for architecture details.

Crates

Crate Role Depends on api Depends on agent
clawseed-api Trait definitions only — —
clawseed-agent Agent loop, hooks, dispatch, parsing, runtime assembly yes —
clawseed-tools 25+ built-in tools yes no
clawseed-providers LLM provider implementations yes no
clawseed-memory SQLite-backed memory + vector search yes no
clawseed-config TOML config schema and loading yes no
clawseed-gateway Axum HTTP/WS server + remote tool bridge yes yes
clawseed Binary (CLI) — —

Quick start

git clone https://github.com/lzx1413/clawseed.git
cd clawseed
cargo build --release

# Run the gateway (HTTP/WebSocket server for mobile clients)
./target/release/clawseed gateway --host 0.0.0.0 --port 3000

# Or start a local interactive chat session (no server needed)
./target/release/clawseed chat
./target/release/clawseed chat --model gpt-4o --temperature 0.5

# Build and install the Android demo app (requires NDK)
./tools/build-clawseed-android.sh aarch64 build
cd clients/android && ./gradlew assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk

Both modes read ~/.clawseed/clawseed.toml by default. Minimal config:

workspace_dir = "/home/user/workspace"

[providers]
fallback = "anthropic"

[providers.models.anthropic]
model = "claude-sonnet-4-20250514"
api_key = "${ANTHROPIC_API_KEY}"

Extending ClawSeed

Add a tool

Implement the Tool trait in clawseed-tools, register in all_tools():

pub struct MyTool;

impl Tool for MyTool {
    fn name(&self) -> &str { "my_tool" }
    fn description(&self) -> &str { "Does something useful" }
    fn parameters_schema(&self) -> Value { /* JSON Schema */ }
    async fn execute(&self, args: Value, ctx: &dyn ToolContext) -> Result<ToolResult> {
        let workspace = ctx.workspace_dir();
        // ...
    }
}

Add a hook

Implement the Hook trait to intercept tool calls:

pub struct AuditHook;

impl Hook for AuditHook {
    fn before_tool_call(&self, call: &mut ToolCall) -> HookResult {
        log::info!("tool {} called", call.name);
        HookResult::Continue
    }

    fn after_tool_call(&self, result: &ToolExecutionResult) -> HookResult {
        log::info!("tool {} → {:?}", result.name, result.status);
        HookResult::Continue
    }
}

HookResult has three variants: Continue, Cancel(String), Modify(ToolCall).

Add a provider

Implement the Provider trait in clawseed-providers, add to the factory. Supports native tool calling, streaming, vision, and prompt caching.

Add a hook

File operations — read, write, edit, glob search, content search Web — HTTP request, web fetch, web search (DuckDuckGo) Memory — store, recall, forget, purge, export Automation — cron add / list / remove / run / update Development — shell, background commands (run/status/cancel), git operations, PDF read Utilities — calculator, LLM sub-task, knowledge base, model routing, backup

Tools that the agent doesn't need are excluded by allowed_tools in config — they don't register, don't consume tokens.

Security

  • Autonomy levels — ReadOnly / Supervised / Full, configured per deployment
  • SecurityPolicy — implements the Hook trait to globally intercept tool calls before execution
  • Command allowlists — allowed_commands in SecurityPolicy validates shell commands
  • Path guards — forbidden_path_argument() blocks sensitive paths (/etc/passwd, /root/.ssh, etc.)
  • Rate limiting — max_actions_per_hour limits total actions per session
  • Hook pipeline — Hook::before_tool_call() can cancel or modify any tool call before execution

Design principles

  1. Explicit over implicit — all_tools() lists every tool; the full capability set is visible at a glance
  2. Declarative over imperative — config drives composition, not code changes
  3. Traits at boundaries — core depends on abstractions; implementations live outside
  4. Graceful degradation — failed memory → NoneMemory fallback; flaky provider → ReliableProvider retries

Acknowledgments

ClawSeed's trait-based architecture and provider/tool/memory abstraction patterns are derived from ZeroClaw.

The key difference is positioning: ZeroClaw is an application (channels, dashboards, hardware, and SOP bundled into one binary); ClawSeed is a runtime (crates that applications assemble). This means:

  • No bundled channels — applications integrate their own messaging SDKs
  • No bundled dashboard — applications build their own UI (e.g. the Android demo app)
  • Added native remote tool calls for mobile clients
  • Added unified Hook trait for tool call interception
  • Added ProviderFactory registry for platform-specific provider sets (Android/embedded)
  • Added extended thinking support with reasoning content round-trip for tool calls
  • Added Android demo app running the full agent stack on-device

License

Dual-licensed: MIT OR Apache 2.0. You may choose either.

About

Rust runtime for mobile and edge AI agents with remote tool execution over WebSocket.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages