Architecture¶
The harness is organized so campaigns are declared in YAML and each experiment binds one agent, one memory system, and one benchmark before execution.
flowchart TD
heams["heams run --config --output-dir"] --> resolve["prepare_run"]
resolve --> runOrch["execute_run"]
runOrch --> expOrch["execute_experiment"]
expOrch --> factory["create_benchmark"]
factory --> samples["BenchmarkSample iterable"]
samples --> bind["bind agent + memory"]
bind --> orch["Orchestrator"]
orch --> agent["TinyAgent"]
orch --> memory["MemorySystem"]
orch --> evaluators["Evaluators"]
evaluators --> artefacts["runs.jsonl"]
Components¶
heams CLI (heams.cli.cli)¶
Entry point for campaigns. Responsibilities:
- Parse the small subcommand surface (
run,memory list/memory test,generate-report,browse) - Load a run config from
configs/runs/ - Hand a typed
ResolvedRunConfigto the run orchestrator
No CLI overrides for model, memory, limits, or benchmark selection.
Run and experiment orchestration (heams.orchestration)¶
| Module | Role |
|---|---|
run_config |
RunConfig / ExperimentConfig / component refs |
run_orchestration |
Resolve component YAML, write run snapshot, execute experiments serially |
experiment_orchestration |
Materialize benchmark samples, bind components, run Orchestrator |
experiment_config |
ResolvedExperimentExecutionConfig (typed agent/memory/benchmark) |
orchestrator |
Scenario runtime: setup → execute → audit → teardown |
scenario_runtime |
setup_scenario_runtime / teardown_scenario_runtime |
scenario_execution |
execute_scenario: runs the execution sequence in order |
Each experiment is one agent/memory/benchmark tuple. Comparing memory backends means listing multiple experiments in the run YAML, not sweeping inside one experiment.
Benchmark factories (heams.benchmarks.factory)¶
New-path benchmarks are typed configs with a type discriminator:
BenchmarkConfig (discriminated by `type`: locomo, beam, mpbench, long_mem_eval,
evomemory_single_turn, transparency, ci, stale, ee, retention_policy)
→ BaseBenchmark → BenchmarkSample
New-path workloads inherit BaseBenchmark: their validated configuration
defines workload policy, they eagerly materialize ordered BenchmarkSample
objects, orchestration binds resolved agent and memory components, and runtime
executes the resulting Scenario objects. Each sample maps mechanically to a
scenario via BenchmarkSample.to_scenario().
See Adding a benchmark. Agents implementing a new suite
should load
.agents/skills/implement-benchmark/
(also linked under .cursor/skills/ and .claude/skills/).
Config ownership¶
| Owner | Examples |
|---|---|
| Agent config | model_id, instructions, memory_strategy |
| Memory-system config | backend type, top_k, file path, privacy wrapper |
| Benchmark config | dataset path, limit / limit_stimuli, task prompts |
| Run config | run_name, named experiment matrix |
| CLI invocation | resolved artifact output directory |
| Scenario data | stimuli, priming, ground truth — not agent/memory policy |
Benchmarks must not silently overwrite agent or memory policy at runtime. If a setting is required for compatibility, validate it; keep the serialized experiment config identical to what executes.
Memory strategies¶
Agent memory access is selected by memory_strategy:
| Strategy | Access and write policy |
|---|---|
no_memory |
No memory access. |
tool_use |
Agent-controlled recall and memory mutation tools. |
recall_only_tool_use |
Agent-controlled recall through the recall tool only. |
deterministic |
Framework-controlled recall injection and completed-turn retention. |
deterministic_with_delete |
Framework-controlled recall/retention plus explicit delete-intent routing through the memory backend. |
recall_only_deterministic |
Framework-controlled recall injection without completed-turn retention. |
Orchestrator execution¶
Every run follows one synchronous setup → execute → audit → teardown path.
setup_scenario_runtime builds the optional environment, memory system,
tool-bound TinyAgent, and evaluator. execute_scenario then interprets
every Scenario.execution_sequence serially in declaration order.
UserStimulus calls stateful agent.run, while EnvironmentManipulation
dispatches to the active environment. MemoryManipulation calls the memory
system directly with retain, recall, or set_retention_policy (Retention
policy uses it), and AgentManipulation supports reset_state (Evo-Memory
uses it); other commands raise ValueError.
flowchart TD
subgraph setup["setup_scenario_runtime"]
S1["Scenario + ScenarioPriming"]
S1 --> E1["BaseEnvironment.reset()"]
S1 --> M1["BaseMemorySystem prime"]
M1 --> T1["build_tools(env + memory retain/recall/…)"]
T1 --> A1["TinyAgent.run()"]
S1 --> EV1["BaseEvaluator"]
end
subgraph loop["execute_scenario (ordered, synchronous)"]
direction TB
L1["UserStimulus"] -->|"agent.run(prompt, run_context)"| A1
A1 -->|"tool calls"| E1
A1 -->|"tool calls"| M1
A1 --> R1["AgentResponse → transcript"]
L2["EnvironmentManipulation"] -->|"dispatch_command()"| E1
L3["MemoryManipulation"] -->|"retain / recall / set_retention_policy"| M1
L4["AgentManipulation"] -->|"reset_state()"| A1
end
setup --> loop
loop --> AUD["EvaluatorConfig.to_ground_truth()"]
AUD --> AUD2["BaseEvaluator.audit(responses, ground_truth)"]
AUD2 --> RR["RunResult"]
Reporting¶
After a config-driven run:
- Per-experiment
runs.jsonlandrun_status.json - Resolved config snapshots at run and experiment scope
heams generate-reportthen writes areport.mdper experiment; per-benchmark rollups are optional and generated from Python
How to read these: Understanding results.
Repository layout¶
| Path | Purpose |
|---|---|
python_package/src/heams/ |
Implementation (CLI, orchestration, benchmarks, memory, agents) |
python_package/datasets/ |
Upstream datasets, downloaded on first use (not committed), and our own retention_policy/ and transparency/ datasets (committed) |
python_package/configs/agents/ |
Agent component presets |
python_package/configs/memory_systems/ |
Memory-system component presets |
python_package/configs/benchmarks/ |
Benchmark component presets |
python_package/configs/runs/ |
Campaign / run configs |
python_package/tests/ |
Unit and orchestration smoke tests |
python_package/docs/ |
This documentation site |