Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
899b51a
feat(flows): store flow and delegation checkpoints on the storage bac…
senamakel Oct 9, 2026
3d703bc
chore(deps): add tinyflows-drivers to the app lockfile
senamakel Oct 9, 2026
2425e09
build(deps): make tinyflows-drivers schedule feature unconditional
senamakel Oct 9, 2026
c4218be
feat(storage): add block_on_anyhow helper
senamakel Oct 9, 2026
5dd68b4
feat(cron): route cron store through document backend when configured
senamakel Oct 9, 2026
db6eb10
chore(deps): bump tinyflows and add driver dependencies
senamakel Oct 9, 2026
37a1ef0
fix(cron): avoid shadowing job id in remove_job
senamakel Oct 9, 2026
f659182
feat(flows): route catalog operations through the document backend
senamakel Oct 9, 2026
c6be041
refactor(flows): drop documents lookup from flows dir
senamakel Oct 9, 2026
6e08491
refactor(tinyflows): route flow state through FlowState wrapper
senamakel Oct 9, 2026
a122c4a
chore(flows): add tinyflows-drivers test fixtures and reformat call s…
senamakel Oct 9, 2026
c31b984
test(cli): register storage_flows_e2e as its own test binary
senamakel Oct 9, 2026
c1e0289
test(storage): exercise flow state through the catalog kv
senamakel Oct 9, 2026
be3fabe
chore(deps): update tinyflows lockfile dependencies
senamakel Oct 9, 2026
c85d724
chore(vendor): bump tinyflows submodule
senamakel Oct 9, 2026
737ccb9
Merge remote-tracking branch 'upstream/main' into storage-cron-flows
senamakel Oct 9, 2026
50ddade
chore(vendor): bump tinyagents submodule
senamakel Oct 9, 2026
654eaf5
docs(storage): document tinyflows stores on the storage backend
senamakel Oct 9, 2026
a32c633
Merge remote-tracking branch 'upstream/main' into storage-cron-flows
senamakel Oct 9, 2026
df4e9ee
chore(vendor): bump tinymcp, tinysearch and tinyskills
senamakel Oct 9, 2026
20342e9
chore(vendor): bump tinymcp and tinysearch submodules
senamakel Oct 9, 2026
bbcd917
fix(vendor): restore tinymcp, tinysearch and tinyskills pins to upstr…
senamakel Oct 9, 2026
f40fb22
chore(vendor): bump tinyflows submodule
senamakel Oct 9, 2026
084ed21
Merge upstream/main into storage-cron-flows; bump tinyflows to fe508cad
senamakel Oct 9, 2026
bb7be5b
Merge upstream/main into storage-cron-flows
senamakel Oct 9, 2026
db0783b
Merge remote storage-cron-flows
senamakel Oct 9, 2026
bea4da3
chore(vendor): bump tinyflows submodule
senamakel Oct 9, 2026
7df8d51
chore(vendor): keep tinyflows at fe508cad
senamakel Oct 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions crates/openhuman-app/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions crates/openhuman-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ path = "../../tests/storage_approvals_e2e.rs"
name = "storage_domains_e2e"
path = "../../tests/storage_domains_e2e.rs"

[[test]]
Comment thread
senamakel marked this conversation as resolved.
# Its own binary: it installs a storage backend into the process-wide slot.
name = "storage_flows_e2e"
Comment thread
senamakel marked this conversation as resolved.
path = "../../tests/storage_flows_e2e.rs"
Comment thread
senamakel marked this conversation as resolved.
Comment thread
senamakel marked this conversation as resolved.

[[test]]
# Its own binary: it installs a storage backend into the process-wide slot and
# sets the keyring master-key environment.
Expand Down
11 changes: 10 additions & 1 deletion crates/openhuman-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ tinyflows-catalog = { path = "../../vendor/tinyflows/crates/tinyflows-catalog",
# The cron job/run store half (`schedule`) is unconditional, so `tinyflows-sqlite`
# is too; only its `catalog` half (which needs the engine) rides the `flows` gate.
tinyflows-sqlite = { path = "../../vendor/tinyflows/crates/tinyflows-sqlite", default-features = false, features = ["schedule"] }
# tinyflows' stores on the storage ports, used instead of the SQLite files when
# a storage backend is configured (`storage`). The cron half (`schedule`) is
# unconditional like cron itself; the catalog, flow state and checkpointer
# (`catalog`, which needs the engine) ride the `flows` gate.
tinyflows-drivers = { path = "../../vendor/tinyflows/crates/tinyflows-drivers", default-features = false, features = ["schedule"] }
# The authoring copilot's words: the `workflow_builder` / `flow_discovery`
# standing archetypes and the turn brief that opens a builder turn. Harness-free
# by construction — it names no tool trait and no model client — so this host
Expand Down Expand Up @@ -147,6 +152,7 @@ tinyagents-definition = { path = "../../vendor/tinyagents/crates/tinyagents-defi
tinyagents-live = { path = "../../vendor/tinyagents/crates/tinyagents-live", optional = true }
tinyagents-graph = { path = "../../vendor/tinyagents/crates/tinyagents-graph", features = [
"sqlite",
"storage-drivers",
] }
tinyagents-registry = { path = "../../vendor/tinyagents/crates/tinyagents-registry" }
tinyagents-session = { path = "../../vendor/tinyagents/crates/tinyagents-session", features = ["storage-drivers"] }
Expand Down Expand Up @@ -632,6 +638,9 @@ tinymemory-api = { path = "../../vendor/tinymemory/crates/tinymemory-api", featu
# write path can produce. Declared here rather than in `[dependencies]` so the
# shipped binary never carries those two writers.
tinyflows-sqlite = { path = "../../vendor/tinyflows/crates/tinyflows-sqlite", features = ["test-fixtures"] }
# The document catalog's `*_for_test` fixtures, which the flows store forwards
# in test builds.
tinyflows-drivers = { path = "../../vendor/tinyflows/crates/tinyflows-drivers", default-features = false, features = ["schedule", "test-fixtures"] }
# Test fixtures derive a known account from the BIP-39 vector phrase. Production
# does not derive at all — see the note on the main `tinywallet` entry. Cargo
# does not link dev-dependency features into the shipped binary, so enabling
Expand Down Expand Up @@ -914,7 +923,7 @@ media = ["tinyagents-harness/media"]
# runtime `DomainSet::flows` flag (#4796): the feature narrows the compile-time
# surface, `DomainSet` gates it at runtime.
# NOTE: this gate does NOT drop `tinyagents` itself — 26+ domains consume it.
flows = ["dep:tinyflows", "dep:tinyflows-catalog", "dep:tinyflows-copilot", "tinyflows-sqlite/catalog"]
flows = ["dep:tinyflows", "dep:tinyflows-catalog", "dep:tinyflows-copilot", "tinyflows-drivers/catalog", "tinyflows-sqlite/catalog"]
# Skills domains: `openhuman::skills` (metadata/discovery/install),
# `openhuman::skill_runtime` (SKILL.md execution + the skill_executor agent),
# and `openhuman::skill_registry` (remote catalogs + the skill_setup agent).
Expand Down
25 changes: 20 additions & 5 deletions crates/openhuman-core/src/agent/orchestration/delegation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,26 @@ pub(crate) async fn run_subagent_delegation_with_parent_context(
// durable graphs simply expire (orphaned tasks are reconciled at boot per
// 07.2). Checkpoint metadata (thread/checkpoint/parent/run ids) stays
// inspectable through the crate `Checkpointer` API.
let checkpoint_db = config.workspace_dir.join("graph_checkpoints.db");
let checkpointer: Arc<dyn Checkpointer<DelegationState>> = Arc::new(
SqliteCheckpointer::<DelegationState>::open(&checkpoint_db)
.map_err(|e| format!("open durable graph checkpoint store: {e}"))?,
);
//
// With a storage backend configured (`crate::storage`) the checkpoints
// live there instead, in the acting agent's scope.
let checkpointer: Arc<dyn Checkpointer<DelegationState>> =
match crate::storage::current_scoped()
.map_err(|e| format!("resolve the storage scope for graph checkpoints: {e}"))?
{
Comment thread
senamakel marked this conversation as resolved.
Some(scoped) => Arc::new(tinyagents_graph::checkpoint::DriverCheckpointer::<
Comment thread
senamakel marked this conversation as resolved.
Comment thread
senamakel marked this conversation as resolved.
Comment thread
senamakel marked this conversation as resolved.
Comment thread
senamakel marked this conversation as resolved.
DelegationState,
>::with_prefix(
Arc::clone(scoped.documents()), "delegation_graph"
)),
None => {
let checkpoint_db = config.workspace_dir.join("graph_checkpoints.db");
Arc::new(
SqliteCheckpointer::<DelegationState>::open(&checkpoint_db)
.map_err(|e| format!("open durable graph checkpoint store: {e}"))?,
)
}
};

tracing::info!(
target: LOG_TARGET,
Expand Down
10 changes: 10 additions & 0 deletions crates/openhuman-core/src/cron/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,16 @@ missing row, reschedules a drifted one, and removes the retired
`memory_context_refresh` row. It runs from [`core/runtime/services.rs`](../core/runtime/services.rs) and from
[`security/credentials/ops/user_scope.rs`](../security/credentials/ops/user_scope.rs).

### On a storage backend

With a storage backend configured (`OPENHUMAN_STORAGE_URL` / `[storage] url`,
see `crate::storage`), every `store` function is served by
`tinyflows_drivers::schedule::CronDocuments` instead of `cron/jobs.db`: the
same jobs and runs on the document port, in the acting agent's storage scope,
with the same history cap and due-job batch size. `reschedule_after_run`
advances a job only if its stored schedule still matches the job that fired,
so two processes sharing one database don't double-advance it.

## Layout

| Path | What it does |
Expand Down
Loading
Loading