stasis-rs 0.2.0

Durable AI orchestration framework with runtime jobs, lineage, and memory integration
Documentation

# Stasis

<div align="center">
    
<img width="416" height="388" alt="image" src="https://github.com/user-attachments/assets/fd3f91cd-e248-4f8d-9b1e-14a648c99af6" />
</div>

---

Stasis is a Rust framework for building long-running AI systems that behave like distributed applications.

It provides durable runtime orchestration, background workflows, recurring scheduling, multi-agent coordination, memory integration, and cluster-aware control plane primitives while still scaling down cleanly to simple chat-style agent execution.

Unlike prompt orchestration frameworks focused primarily on request/response composition, Stasis is designed for operational reliability:

- durable execution    
- queue ownership and worker coordination    
- endpoint routing    
- runtime observability    
- scheduling and retries
- typed tool contracts
- distributed runtime control

## Quick Start

```rust
use stasis::sdk_prelude::{InvokeAgentRequest, InMemoryAgentRepository, RegisterAgentRequest, StasisSdk};
use stasis::sdk_prelude_ext::GenaiLlmGateway;

#[tokio::main]
async fn main() -> stasis::domain::errors::Result<()> {
    let repo = InMemoryAgentRepository::default();
    let llm = GenaiLlmGateway::from_env();
    let sdk = StasisSdk::new(repo, llm);

    sdk.register_agent(RegisterAgentRequest {
        id: "planner".into(),
        name: "Planner".into(),
        system_prompt: "Break tasks into steps".into(),
    })
    .await?;

    let out = sdk
        .invoke_agent(InvokeAgentRequest {
            agent_id: "planner".into(),
            user_prompt: "Plan a sprint kickoff".into(),
        })
        .await?;

    println!("{}", out.completion);
    Ok(())
}
```

In this example:

- Agents are stored in-memory.
- Prompt execution uses the configured provider gateway from environment variables.
- Runtime state is local and ephemeral.
- No external infrastructure is required.
- This is `StasisSdk`-only mode (the simplest operating model).

For a deterministic local smoke test (no provider dependency), use [examples/simple_agent.rs](examples/simple_agent.rs).

Prelude tiers:

- `stasis::prelude`: minimal, stable default imports.
- `stasis::prelude_ext`: extended runtime/memory/control-plane imports.
- `stasis::sdk_prelude`: minimal SDK-first imports for app code.

To use a real provider via `genai`, set a provider key (for example `OPENAI_API_KEY`) and optionally configure model/provider routing:

```bash
export STASIS_LLM_PROVIDER=openai
export STASIS_LLM_MODEL=gpt-4o-mini
```

You can also set a Stasis-scoped fallback key:

```bash
export STASIS_LLM_API_KEY=...
```

Provider-specific overrides are supported:

- `STASIS_OPENAI_API_KEY`
- `STASIS_ANTHROPIC_API_KEY`
- `STASIS_OLLAMA_API_KEY`

Runtime examples are available in [examples](examples).

**Package note:** the crates.io package is `stasis-rs` while Rust imports use `stasis`.

### Tool Macro (Signature-Driven)

`StasisTool` can be generated from a typed async function using `#[stasis_tool(...)]`:

```rust
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use stasis::domain::errors::Result;
use stasis::stasis_tool;

#[derive(Debug, Clone, Deserialize, JsonSchema)]
struct SearchInput {
    query: String,
}

#[derive(Debug, Clone, Serialize, JsonSchema)]
struct SearchOutput {
    summary: String,
}

#[stasis_tool(
    name = "search_docs",
    description = "Searches internal docs",
    output_schema = true
)]
async fn search_docs(input: SearchInput) -> Result<SearchOutput> {
    Ok(SearchOutput {
        summary: format!("query={}", input.query),
    })
}

// Generated symbols:
// - struct SearchDocsTool;
// - fn search_docs_tool() -> SearchDocsTool;
```

This avoids repetitive manual trait implementations while preserving strict JSON-schema-based validation.

Macro contract:

- Function must be `async` and take exactly one typed input argument.
- Return type must be `Result<OutputType>`.
- Input type must implement `Deserialize + JsonSchema`.
- Output type must implement `Serialize`.
- When `output_schema = true`, output type must also implement `JsonSchema`.

Production-focused entry points:

- [examples/simple_agent_production.rs]examples/simple_agent_production.rs: minimal real-provider invocation.
- [examples/agentic_workflows_production.rs]examples/agentic_workflows_production.rs: full workflow set with `STASIS_EXAMPLE_TEAM_PROFILE` (`all|sre|product|support`), `STASIS_EXAMPLE_RUNTIME_BACKEND` (`in-memory|surreal-mem|surreal-ws|surreal-kv`), and `STASIS_EXAMPLE_DRY_RUN=1` for provider-safe smoke runs.
- [examples/runtime_backends_profiles.rs]examples/runtime_backends_profiles.rs: backend profile bootstrap for in-memory, Surreal websocket, and Surreal KV modes.
- [examples/team_role_workflows.rs]examples/team_role_workflows.rs: role-specific scenario packs for SRE incident, product planning, and support triage loops.


## Embedded Dashboard

You can embed the dashboard into your existing Axum app behind an optional feature flag.

### Main View
<img width="1920" height="1080" alt="image" src="https://github.com/user-attachments/assets/b1a083f5-79b9-4a7b-ae4b-70310da81840" />

### Grapheme Workflow Builder
<img width="1920" height="1080" alt="image" src="https://github.com/user-attachments/assets/e74345fc-cbf3-4c4e-80cb-6f0a5b779c25" />

### Job Scheduler
<img width="1920" height="1080" alt="image" src="https://github.com/user-attachments/assets/38fd383b-874f-4ecf-a40c-866dda5c6ea6" />


Enable feature:

```bash
cargo add stasis-rs --features dashboard-embedded
```

Mount dashboard routes in your app code:

```rust
use std::sync::Arc;

use axum::Router;
use stasis::dashboard::{DashboardRouterExt, RuntimeDashboardQueryService};

fn app(service: Arc<RuntimeDashboardQueryService>) -> Router {
    Router::new().add_dashboard_with(service, |state| {
        state
            .with_action_auth_bearer_token("replace-me")
            .with_action_required_role("scheduler.admin")
    })
}
```

The standalone `stasis_dashboard` binary remains available for separate operations workflows.

Dashboard runtime backend selection (for `stasis_dashboard`):

- `STASIS_DASHBOARD_RUNTIME_BACKEND=in-memory|surreal-mem|surreal-ws|surreal-kv`
- `STASIS_DASHBOARD_SURREAL_NAMESPACE` (default: `stasis`)
- `STASIS_DASHBOARD_SURREAL_DATABASE` (default: `runtime`)
- `STASIS_DASHBOARD_SURREAL_ENDPOINT` (required for `surreal-ws`)
- `STASIS_DASHBOARD_SURREAL_KV_PATH` (required for `surreal-kv`)

Demo seeding remains opt-in and only applies to in-memory mode:

- `STASIS_DASHBOARD_DEMO_SEED=true`


## Why Stasis?

Most AI frameworks optimize for prompt composition. Stasis optimizes for production runtime behavior:

- Durable execution across backend choices.
- Orchestration reliability with explicit queues, workers, and policies.
- Runtime observability and operational diagnostics.
- Cluster coordination and endpoint routing support.
- Typed tool contracts with schema-aware invocation.
- Built-In WASM Compatible Workflow Engine with no code builder. Powered by [Grapheme]https://github.com/EntasisLabs/grapheme 
- Memory-aware workflows with recall, store, aggregate, and rollup paths. Powered by [Locus]https://github.com/EntasisLabs/locus

## Architecture

- `domain`: Runtime models, policies, events, and error contracts.
- `application`: Use-cases, orchestration pipelines, and runtime handlers.
- `ports`: Stable inbound/outbound interfaces.
- `infrastructure`: Adapters for in-memory, SurrealDB, networking, and providers.
- `sdk`: Consumer-facing facades (`StasisSdk`, `RuntimeSdk`, `ControlPlaneSdk`).

### Layout

```text
Client App
    |
    v
StasisSdk / RuntimeSdk / ControlPlaneSdk
    |
    v
Application Runtime + Orchestration
    |
    v
Ports
    |
    v
Infrastructure Adapters (LLM, memory, storage, transport, workflow engine)
    |
    v
Providers / Surreal Backends / Cluster Integrations
```

### Process Flow

```text
Request/Trigger
Workflow Runtime
Durable Job Queue
Workers / Agents
Memory + Tool + LLM Adapters
```

## SDK Surface

- `StasisSdk`: agent registration and prompt invocation flows.
- `RuntimeSdk`: enqueue, process, publish, recurring materialization, runtime stats.
- `ControlPlaneSdk`: endpoint and cluster coordination commands.

## When To Use Which SDK

Use this as a practical selection guide:

- `StasisSdk`:
    - Best for chat-style assistants, lightweight copilots, and direct request/response flows.
    - Start here when you do not need background workers, scheduling, or queue durability.
- `RuntimeSdk`:
    - Add when work must run asynchronously, survive retries/failures, or execute on schedules.
    - Use for workflow pipelines, outbox delivery, and operational runtime visibility.
- `ControlPlaneSdk`:
    - Add when orchestration is distributed across nodes/endpoints and needs coordination commands.
    - Use for endpoint routing, cluster ownership, and control-plane driven operations.

Typical adoption path:

1. Start with `StasisSdk` for simple chat and agent prompts.
2. Add `RuntimeSdk` when workloads become asynchronous or policy-driven.
3. Add `ControlPlaneSdk` when operating multi-node or cluster-aware deployments.

## Runtime Capabilities

- Durable backend options for queue/thread state (`surreal-ws` / `surreal-kv`), with `in-memory` for local runs.
- Retry and failure-policy aware job execution with bounded attempts.
- Recurring schedule materialization and worker-driven queue processing.
- Outbox publication workflows for delivery and endpoint diagnostics.
- Runtime stats snapshots for enqueued/running/succeeded/failed/dead-letter visibility.
- Cluster/control-plane primitives for node and endpoint coordination.


## Documentation

- Docs index: [docs/README.md]docs/README.md
- Runtime design: [docs/design/job-runtime-design.md]docs/design/job-runtime-design.md
- Architecture overview: [docs/architecture/overview.md]docs/architecture/overview.md
- ADR index: [docs/adr/README.md]docs/adr/README.md

## mdBook

- Book root: [docs-book]docs-book
- Table of contents: [docs-book/src/SUMMARY.md]docs-book/src/SUMMARY.md

Build locally:

```bash
mdbook build docs-book
```

Serve locally:

```bash
mdbook serve docs-book --open
```

## Codebase Health Analysis Provided by ACC
<img width="1854" height="838" alt="image" src="https://github.com/user-attachments/assets/d8e74f74-d5f8-4b25-b327-7aa415d0b847" />