Expand description
Durable applications over caller-owned storage and configured agents.
Start with AppConfig and App::open, create a Workspace, then select
a workflow::Workflow. The local example runs with
caller-created embedded Lance StateStore and no Agent value or external service.
workflow contains definitions, execution controls, state operations,
graph inspection, immutable checkpoints, and the five concrete App behavior
seams. AgentSpec transfers an already-built Agent; App never constructs
providers, tools or lower storage from declarations. Exact associated lower
Workspace, Conversation and StateTransaction types remain attached.
Call App::shutdown while the captured Tokio runtime and lower runtimes
are alive and driven. Run handles observe accepted work; workflow::Execution
owns lazy advancement. Dropping an execution can revoke uncommitted work,
while observation loss cannot revoke an admitted native commit.
Public supporting types live under workflow. The state serialization
registry stores only field/tag codecs; it is not a runtime behavior registry.
§Choose a workflow
- Application builders: the local workflow, explicit execution and retained history, then durable reopen and migration prerequisites.
- Custom implementers: configure concrete behavior
with the five workflow traits. Their examples run locally; lower
agents_kit::AgentBackendandstorage_kit::StateStoreBackendimplementations remain direct, statically selected values. - Agent-backed workflows: transfer already-built values through
AgentSpec. App owns eventual consuming Agent shutdown, without rebuilding credentials, tools, Providers or persistence from declarations.
§Local workflow
use agents_kit::Agent;
use app_kit::{App, AppConfig, Shutdown, WorkspaceConfig};
use app_kit::workflow::{ExecutionOptions, RunStatus, WorkflowDefinition};
use storage_kit::{StateStore, state::config::{LanceStateStoreConfig, StateStoreConfig}};
let store = StateStore::connect(StateStoreConfig::lance(LanceStateStoreConfig::memory())).await?;
let definition = WorkflowDefinition::parse(r#"{
"schema":"app-kit.workflow/v2", "id":"counter", "revision":"r1",
"state":{"count":0}, "required":["count"],
"reducers":{"count":"reject_concurrent"}, "entry":"increment",
"nodes":[{"id":"increment","step":{"kind":"state","mutations":[
{"kind":"increment","target":"count","value":{"kind":"literal","value":1}}
]}}], "routes":{}
}"#)?;
let mut app = App::open(AppConfig::<_, Agent>::new(store, Vec::new(), vec![definition])).await?;
let outcome = async {
let workspace = app.create_workspace(WorkspaceConfig {
name: Some("local counter".into()), root: std::env::current_dir()?,
}).await?;
let workflow = workspace.workflow("counter".parse()?).await?;
let run = workflow.start(ExecutionOptions::default()).await?;
Ok::<_, Box<dyn std::error::Error>>(run.wait().await?)
}.await;
let cleanup = app.shutdown(Shutdown::CancelAndDrain {
timeout: std::time::Duration::from_secs(5),
}).await;
if let Err(error) = &cleanup { eprintln!("App shutdown: {error}"); }
let snapshot = outcome?; // Preserve the operation error after attempting shutdown.
cleanup?;
assert!(matches!(snapshot.status, RunStatus::Succeeded));
assert_eq!(snapshot.state.values()["count"], 1);Modules§
- workflow
- Opaque workflow definitions and runtime handles. Workflow authoring, execution, immutable state, and retained history.
Structs§
- Agent
Spec - Declares one configured lower agent.
- App
- An open application generation.
- AppConfig
- Complete application configuration.
- Workspace
- An application workspace handle.
- Workspace
Config - Complete caller-authored workspace configuration.
- Workspace
Id - A validated application workspace identity.
- Workspace
Snapshot - The current caller-visible workspace truth.