Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
318 changes: 151 additions & 167 deletions Cargo.lock

Large diffs are not rendered by default.

16 changes: 12 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ tinyhumans-sdk = { path = "vendor/openhuman/vendor/tinyhumans-sdk" }
# openhuman host consumes it — one shared pin, one shared upgrade cadence.
# `mock` is a normal (not dev-only) feature: dry-run authoring uses the engine's
# deterministic capability stand-ins in ordinary builds.
tinyflows = { version = "0.6", features = ["mock"] }
tinyflows = { version = "0.6", features = ["mock", "host-caps", "store"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
toml = "0.8"
Expand Down Expand Up @@ -120,16 +120,24 @@ unicode-width = "0.2"
tinyagents = { path = "vendor/openhuman/vendor/tinyagents" }
tinychannels = { path = "vendor/openhuman/vendor/tinychannels" }
tinycortex = { path = "vendor/openhuman/vendor/tinycortex" }
# OpenHuman's extracted TinyMemory core names this contract by version. The
# vendored OpenHuman manifest patches it, but path dependencies do not inherit
# their own patch tables, so Medulla must bind it at this workspace root too.
# `tinymemory-core` names `tinycortex-api` by version requirement while this
# graph depends on tinycortex by path, so without this the resolver goes to
# crates.io for it and fails outright — the crate is not published. The
# vendored OpenHuman manifest patches it too, but path dependencies do not
# inherit their own patch tables, so Medulla must bind it at this workspace
# root as well.
tinycortex-api = { path = "vendor/openhuman/vendor/tinycortex/api" }
tinyflows = { path = "vendor/openhuman/vendor/tinyflows" }
tinyjuice = { path = "vendor/openhuman/vendor/tinyjuice" }
# Load-bearing even though no crate in this workspace links tinyplace any more:
# the vendored OpenHuman core still does, and without the redirect Cargo would
# resolve the published crate instead of the vendored tree.
tinyplace = { path = "vendor/openhuman/vendor/tinyplace/sdk/rust" }
# Not a tiny* crate, but patched for the same reason the others are: OpenHuman
# vendors its own copy and this table is the only one Cargo reads, so an entry
# missing here silently resolves the published crate instead of the vendored
# tree.
motosan-ai-oauth = { path = "vendor/openhuman/vendor/motosan-ai-oauth" }
# NOT copied from OpenHuman: its whisper-rs-sys git patch. Cargo fetches a git
# patch source during resolution even when the patched crate is absent from the
# graph, which would put a network fetch in the critical path of every
Expand Down
15 changes: 12 additions & 3 deletions scripts/init-submodules.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,23 @@ git submodule update --init --depth 1 vendor/openhuman
# root manifest must stay in lockstep with its `[patch.crates-io]` table;
# tinybus and tinymemory are unpublished direct paths from OpenHuman's manifest.
git -C vendor/openhuman submodule update --init --depth 1 \
vendor/motosan-ai-oauth \
vendor/tinyagents \
vendor/tinybus \
vendor/tinychannels \
vendor/tinycortex \
vendor/tinyflows \
vendor/tinyhumans-sdk \
vendor/tinyjuice \
vendor/tinyplace \
vendor/tinymemory
vendor/tinymemory \
vendor/tinyplace

echo "Submodules initialized (OpenHuman core + its nine required dependencies)."
# Deliberately NOT recursive. Three of these vendor crates of their own —
# tinyflows has its own `tinyagents`, tinymemory its own `tinyagents`, `tinybus`
# and `tinycortex` — and none of those nested copies is ever resolved: the root
# patch table redirects each name to the copy beside OpenHuman, so the graph
# holds one of each. Initializing them recursively would clone several hundred
# megabytes that nothing links, and would put two checkouts of one crate on
# disk for anyone reading the tree.

echo "Submodules initialized (OpenHuman core + its ten vendored crates)."
8 changes: 5 additions & 3 deletions src/sdk/src/daemon/task_loop/workflow/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ use crate::protocol::{TaskFrame, TaskFrameKind, WorkflowAdvert, WorkflowInputAdv
use crate::workflows::bridge::trigger_input;
use crate::workflows::evolve::{EvolveConfig, EvolveSession, EvolveTrigger};
use crate::workflows::{
run_workflow_versioned, FileWorkflowStore, RunContext, RunStatus, StoreWorkflowResolver,
WorkflowStore,
run_workflow_versioned, RunContext, RunStatus, StoreWorkflowResolver, WorkflowStore,
};

use super::super::super::types::{DaemonRuntime, FrameAttachments, CAPACITY_REJECTION_PREFIX};
Expand Down Expand Up @@ -72,7 +71,10 @@ impl DaemonRuntime {
/// resolves it.
fn workflow_store(&self) -> Arc<dyn WorkflowStore> {
let cwd = std::path::Path::new(&self.inner.config.workspace);
Arc::new(FileWorkflowStore::discover(&self.inner.config.env, cwd))
Arc::new(crate::workflows::store::discover(
&self.inner.config.env,
cwd,
))
}

/// Run the workflow a `task` frame named, replying with its outcome.
Expand Down
4 changes: 2 additions & 2 deletions src/sdk/src/flow_engine/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The adapter seam between Medulla and the `tinyflows` workflow engine.

## Contents

- [`caps/`](./caps/) — Assembling the capability bundle the engine runs against.
- [`caps/`](./caps/) — Assembling the capability bundle the engine runs against. The host-agnostic implementations moved to `tinyflows::caps::host`; what is left is the harness seam.
- [`execute.rs`](./execute.rs) — Driving the engine: compile, run, resume, simulate.
- [`harness_choice.rs`](./harness_choice.rs) — Which harness and model an `agent` node runs on.
- [`harness_choice_tests.rs`](./harness_choice_tests.rs) — Unit tests for harness and model selection.
Expand All @@ -13,7 +13,7 @@ The adapter seam between Medulla and the `tinyflows` workflow engine.
- [`observability_tests.rs`](./observability_tests.rs) — Tests for the run observer.
- [`settings.rs`](./settings.rs) — What the capability adapters are allowed to do, and where they keep things.
- [`settings_tests.rs`](./settings_tests.rs) — Tests for capability settings and the config that produces them.
- [`tests/`](./tests/) — The offline capability-seam suite. `mod.rs` holds the shared fixtures; submodules cover the `medulla:shell` tool, harness/model selection, the state store, the tool invoker, and the HTTP capsule.
- [`tests/`](./tests/) — The offline capability-seam suite. `mod.rs` holds the shared fixtures; submodules cover the `medulla:shell` tool, harness/model selection, the tool invoker, and dry-run simulation. The state store's and HTTP capsule's own cases moved to `tinyflows::caps::host` with the code.

## Maintenance

Expand Down
4 changes: 3 additions & 1 deletion src/sdk/src/flow_engine/agent_evidence/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ fn prompt_queue_is_bounded_before_the_run_finishes() {

let input = serde_json::to_vec(&steps[0].input).unwrap();
assert!(input.len() <= 64 * 1024 + 256);
assert_eq!(steps[0].input.as_ref().unwrap()["_medullaTruncated"], true);
assert!(tinyflows::store::is_truncated(
steps[0].input.as_ref().expect("an input")
));
}

#[test]
Expand Down
14 changes: 10 additions & 4 deletions src/sdk/src/flow_engine/caps/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@ Assembling the capability bundle the engine runs against.
## Contents

- [`agent.rs`](./agent.rs) — `agent` nodes, run on a real harness.
- [`code.rs`](./code.rs) — The `code` node's runner — refusing by default.
- [`dispatch.rs`](./dispatch.rs) — Handing a workflow node's instruction to a harness.
- [`http.rs`](./http.rs) — Outbound HTTP for `http_request` nodes, behind a host allowlist.
- [`mocks.rs`](./mocks.rs) — Capability stand-ins for dry runs.
- [`mod.rs`](./mod.rs) — Assembling the capability bundle the engine runs against.
- [`state.rs`](./state.rs) — Durable key/value state for stateful workflows.
- [`tools.rs`](./tools.rs) — `tool_call` dispatch across two namespaces.

## What is no longer here

The capability implementations with no Medulla in them — the out-of-process
script runner and its path policy, the `code` and `shell` runners, the file
state store, the allowlisted HTTP client, and the dry-run stand-ins — moved to
`tinyflows::caps::host`, behind that crate's `host-caps` feature. Every host
embedding the engine needs them, and each one that wrote them itself rewrote the
same subtle parts. [`mod.rs`](./mod.rs) re-exports them, so a call site in this
crate still names one place.

## Maintenance

Keep this index synchronized when responsibilities move. Put shared data structures in `types.rs`, focused unit tests in `tests.rs` or a sibling `_tests.rs`, and preserve the module-level Rust documentation as the API source of truth.
80 changes: 0 additions & 80 deletions src/sdk/src/flow_engine/caps/code.rs

This file was deleted.

Loading
Loading