Skip to content

feat(prompt): move identity/style to workspace files, cut sub-agent surface to three tools - #11

Merged
senamakel merged 39 commits into
fix/ui-v4from
prompt-slimming
Aug 24, 2026
Merged

senamakel merged 39 commits into
fix/ui-v4from
prompt-slimming

Conversation

@senamakel

Copy link
Copy Markdown
Owner

Why this PR is on the fork. tinyhumansai/openhuman refuses new branch
creation (Cannot create ref due to creations being restricted), so neither
this branch nor its base fix/ui-v4 can be pushed there. Retargeting at
upstream main was the alternative and is worse: fix/ui-v4 is far enough
ahead of main that the diff grows from 12 files / ~277 insertions to 37
files / ~2,690, sweeping in unrelated tokenjuice, modules, documents and
voice work. Re-point this at upstream once fix/ui-v4 lands there.

Summary

  • Sub-agent tool surface cut from 11 tools to 3 (spawn_async_subagent, list_subagents, continue_subagent). A sub-agent is always async and its result is delivered back on an idle system turn, so the collection surface (wait, wait_loop, wait_subagent) was buying nothing but tokens and an invitation to stall the turn. spawn_parallel_agents, steer_subagent and close_subagent go with them.
  • Agent identity and writing style moved out of compiled prompts into workspace files — ROLE.md (role brief) and STYLE.md (writing style) join SOUL.md / IDENTITY.md under the workspace, so tuning either is an edit rather than a rebuild.
  • ## Core Responsibilities, ## Rules and ## Grounding and tool use merged into one ## Rules section. They overlapped: Core Responsibilities largely restated "direct-first" and "delegate when it helps".
  • ## Output style and ## Response Style compressed into a single # Writing style in STYLE.md, ending a split where the same concern lived in both builder.rs and orchestrator/prompt.md.
  • HEARTBEAT.md and MEMORY_GOALS.md are no longer seeded. The subconscious engine that read HEARTBEAT.md was deleted; the goals store already returns an empty GoalsDoc for a missing file and creates it on first write.
  • Fixed a latent bug where prompt tests wrote into the repo root — sync_workspace_file now refuses a non-absolute workspace.

Problem

The orchestrator's fixed per-turn cost was 18,168 tokens and nothing measured where it went. Breaking it down surfaced three things:

  1. The sub-agent surface was 11 tools / 2,060 tokens for one capability. orchestration::background_delivery already returns a finished worker's result on an idle system turn, so nothing had to block for it. wait / wait_loop / wait_subagent existed to collect a result that arrives on its own, and spawn_parallel_agents was a second way to say "spawn again".
  2. Identity and style were compiled in. SOUL.md / IDENTITY.md already had a sync-and-inject path, but the orchestrator ran with omit_identity = true and never loaded them; its role text and voice were instead baked into orchestrator/prompt.md and a GLOBAL_STYLE_SUFFIX constant. Tuning either meant a rebuild, and style specifically was split across two files.
  3. Three sections repeated each other. Core Responsibilities, Rules, and the grounding contract each restated direct-first and delegate-when-it-helps.

Solution

Sub-agent tools. Dropped six from orchestrator/agent.toml and rewrote the "Running several workers at once" section around the async model: fan-out is several spawns, results arrive as they land, continue_subagent resumes a worker that stopped to ask. The loader assertions became a both-ways contract — the three required, the six pinned as retired so they cannot drift back without someone re-teaching them in prompt.md.

Result-gating work ("critique it before you finalize") still needs an answer inside the turn, so that hard rule now names a blocking delegate_* specialist or spawn_async_subagent with blocking: true. #4681's regression test is updated to pin those two rather than the retired primitives.

Identity and style. ROLE.md and STYLE.md are bundled, seeded into the workspace by sync_workspace_file, and injected from there. GLOBAL_STYLE_SUFFIX becomes include_str!("STYLE.md") — the bundled seed and the read-failure fallback — with global_style_block() preferring the workspace copy.

omit_identity turned out to be inert for this agent: the orchestrator is a PromptSource::Dynamic agent, and SystemPromptBuilder::from_dynamic installs only that builder and never consults the flag. The identity render therefore lives in orchestrator/prompt.rs, beside the render_user_files call that is there for the same reason.

Grounding is now folded into the orchestrator's merged ## Rules, so build() skips the global append when the assembled prompt already carries the heading. Matching on the heading keeps it self-maintaining: an agent that stops carrying its own copy silently gets the global one back.

The repo-root bug. Enabling identity rendering made the prompt path write, and ~20 test fixtures pass workspace_dir: Path::new("."). The suite promptly seeded five files plus their .builtin-hash siblings into the repo root. Fixed at the source rather than across 20 call sites: a real workspace is always absolute, so a relative one means the caller never had one.

Measured

before after
system prompt 6,647 7,008
tool schemas 11,521 (59 tools) 10,331 (53 tools)
fixed per-turn 18,168 17,339

The system prompt grows, and deliberately: SOUL.md + IDENTITY.md now load for this agent where they previously did not, costing ~700 tokens that the merges (~340) and the tool cut (~1,190) offset. Editability was the goal; the token reduction is incidental. Counts are tiktoken o200k_base, a GPT tokenizer — relative weights, not a billing figure.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy
  • Diff coverage ≥ 80% — not measured locally; deferring to the CI gate. The change is overwhelmingly prompt text and TOML; the Rust touched (global_style_block, the sync_workspace_file guard, the grounding-dedup branch) is covered by the updated prompts::tests and loader::tests.
  • N/A: behaviour-only change — no feature rows added, removed or renamed in docs/TEST-COVERAGE-MATRIX.md.
  • N/A: no matrix feature IDs apply to this change.
  • No new external network dependencies introduced
  • N/A: does not touch a release-cut surface in docs/RELEASE-MANUAL-SMOKE.md.
  • N/A: no tracking issue — this came from an interactive prompt-budget review.

Impact

Behaviour changes reviewers should weigh:

  • A sub-agent can no longer be steered or explicitly closed. A worker needing different instructions must be respawned; idle sessions are reaped against the existing registry cap rather than torn down by hand.
  • STYLE.md is global, so its voice guidance reaches every agent, where ## Response Style previously reached only the orchestrator. The file scopes itself in prose ("output handed to another agent is data, not conversation"), but if a sub-agent's handoffs start reading conversationally, this is the cause.
  • Existing workspaces keep their HEARTBEAT.md / MEMORY_GOALS.md — this stops seeding them, it does not delete them. HEARTBEAT.md keeps its WORKSPACE_INTERNAL_FILES entry so a file a user still has on disk stays not-agent-writable.
  • A user edit to any of the four workspace files now changes agent behaviour, taking effect from the next session (the existing KV-cache freeze rule is unchanged).

Desktop/CLI only; no migration, no platform-specific surface, no perf implication beyond the smaller per-turn payload.

Related

  • Closes:
  • Follow-up PR(s)/TODOs: spawn_async_subagent keeps its name though it is now the only spawn tool — renaming it to spawn_subagent collides with the retired synchronous variant and would cascade across ~20 files.

AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: prompt-slimming
  • Commit SHA: see head of branch

Validation Run

  • N/A: pnpm --filter openhuman-app format:check — no files under app/ changed.
  • N/A: pnpm typecheck — no TypeScript changed.
  • Focused tests: full Rust lib suite, 11558 passed; 0 failed (--test-threads=1, RUST_MIN_STACK=16777216)
  • Rust fmt/check: cargo fmt --check clean; cargo check clean on the product feature set
  • N/A: Tauri fmt/check — app/src-tauri/ untouched.

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: identity and writing style become user-editable workspace files; the sub-agent tool surface narrows to spawn/list/continue; HEARTBEAT.md and MEMORY_GOALS.md stop being seeded.
  • User-visible effect: agent voice and role are tunable without a rebuild; the agent no longer offers to steer or close a worker.

Parity Contract

  • Legacy behavior preserved: grounding contract still reaches every agent (globally, or via the merged section, never twice); the goals domain is unaffected by the dropped seed because store::load returns GoalsDoc::default() on NotFound; retired sub-agent tools remain registered in the base registry and are only out of this agent's named scope.
  • Guard/fallback/dispatch parity checks: loader::tests pins the three-tool surface and the six retired names in both directions; prompts::tests pins that ROLE.md seeds and HEARTBEAT.md / MEMORY_GOALS.md do not; context_composer still asserts the prompt came through SystemPromptBuilder::build.

Duplicate / Superseded PR Handling

  • Duplicate PR(s): none
  • Canonical PR: this one
  • Resolution: N/A

Note on commit history: an auto-commit hook checkpoints this working tree, so the branch carries machine-generated commit subjects and, at two points, commits that regressed vendor/* gitlinks. Those were restored; git diff <base> -- vendor/ is empty, so the net change touches no submodule pointer.

senamakel and others added 30 commits August 23, 2026 21:55
Advance the pinned commits for all seven vendored submodules to their latest respective revisions.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Introduce the agent.toml configuration file for the orchestrator agent, defining its metadata and capabilities to enable orchestration of other agents within the registry.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Introduce the agent.toml configuration file for the orchestrator agent, defining its metadata and runtime settings to enable orchestration capabilities within the agent registry.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Introduce a new markdown file defining the role prompt for the openhuman agent, establishing a foundational instruction set to guide agent responses and interactions.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Introduce a new style guide document to standardize prompt formatting and tone across agent implementations, ensuring consistency and clarity in generated responses.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
When rendering prompts, optional fields that were not set could cause rendering failures or produce unexpected output. This change adds proper handling for absent optional fields, ensuring they are gracefully skipped or replaced with sensible defaults during prompt construction.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Introduce a new sections module within the agent prompts to organize and define reusable prompt components, enabling clearer separation of concerns and easier maintenance of prompt templates.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The prompt builder now returns a default response when given an empty input string, preventing a panic that occurred when attempting to process an empty prompt. This ensures the agent can handle edge cases without crashing.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The prompt builder previously failed when given an empty input string, causing an unwrap on a None value. This change adds a check for empty input and returns a default prompt instead, ensuring the agent can handle edge cases without panicking.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Import the `sync_workspace_file` helper and the `Path` type to enable the system prompt builder to synchronize workspace files when assembling prompts, supporting future integration with file-based context management.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Remove the "Master Agent" header, core responsibilities, response style guidelines, and example interactions from the orchestrator prompt file. These sections are no longer needed as the agent's behavior is now defined elsewhere, and keeping them would only add clutter to the prompt.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Replace the complex roster-based async model with a simpler always-async approach where spawned workers deliver results automatically on their own turn. Remove the manual collection, polling, and fan-out rules that no longer apply, and clarify that result-gating work must use blocking delegates rather than async spawns.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The prompt now reflects the current subagent API by replacing the list of subagent control tools with a single `continue_subagent` reference and updating the batch memory lookup section to recommend `spawn_async_subagent` calls instead of `spawn_parallel_agents`, aligning the documentation with the actual async execution model.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The prompt's guidance on result-gating work previously only mentioned `delegate_*` specialists as the synchronous alternative. This change adds `spawn_async_subagent` with `blocking: true` as another valid option, giving the agent a clearer path to keep work inside the turn when a blocking specialist is not appropriate.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Update the pinned commits for the tinymcp and tinyruntime vendor submodules to incorporate upstream changes. The new commits include local modifications, as indicated by the "-dirty" suffix.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Update the pinned commits for the tinymcp and tinyruntime submodules to their latest versions, incorporating upstream fixes and improvements.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The test now checks for the three current sub-agent tools — spawn, enumerate, and resume — and asserts that the six retired tools are absent, matching the simplified async model where results arrive on an idle turn rather than being collected or blocked on.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Update the tinymemory vendor dependency to a newer commit, incorporating upstream changes.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Co-authored-by: Medulla <medulla@tinyhumans.ai>
…nation

The orchestrator prompt was missing critical instructions for agent handoff and task delegation, causing agents to operate independently rather than collaboratively. This update adds explicit coordination directives to the prompt, ensuring agents properly sequence their actions and share context when handing off tasks.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The orchestrator prompt gains a new "Grounding and tool use" section that enforces strict tool fidelity, numeric precision, and prohibitions on fabrication. The existing rules are reordered to place the primary-tier directive first, followed by the direct-first principle, and the minimisation rule is merged into the direct-first rule to reduce redundancy and clarify the delegation hierarchy.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
…e prompt

The "Core Responsibilities" section duplicated guidance already covered in the master agent's main description, making the prompt unnecessarily long without adding new behavioural constraints. Removing it keeps the role definition concise and avoids conflicting instructions.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The prompt builder was failing when optional fields were absent from the configuration, causing the agent to crash during initialization. This change adds proper default handling for those fields so the builder gracefully falls back to sensible defaults instead of panicking.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add a new public constant GROUNDING_HEADING that stores the heading text "Grounding and tool use" used by the grounding contract. This allows the prompt builder to match on the heading and avoid emitting the contract twice when it appears in both the global GROUNDING_BODY and an agent prompt that carries its own copy.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Adds a new style guide document to standardize prompt formatting and conventions across agent implementations, ensuring consistency in how agents communicate and respond.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The section heading "## Output style" was renamed to "# Writing style" in the system prompt builder. Updated the test assertions in both the prompt module tests and the context composer tests to check for the new heading, ensuring they continue to verify that prompts are built through the correct code path.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The orchestrator agent prompt was missing a critical instruction that caused it to behave incorrectly. This change adds the missing directive to ensure the agent follows the intended workflow.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The orchestrator prompt module now imports the render_identity function, which was previously missing from the import list. This ensures the function is available for use in prompt rendering.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
When the agent name argument is not provided, the CLI now returns an error message instead of panicking. This improves user experience by providing clear feedback when required arguments are missing.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add the initial set of identity, role, memory goals, soul, and heartbeat documents along with their builtin hash tracking files. These establish the foundational self-model and state-tracking structure for the system.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
senamakel and others added 9 commits August 23, 2026 22:33
…ting repo root

The prompt builder writes identity files (SOUL.md, IDENTITY.md, etc.) into the workspace directory during tests. Previously it used the current directory, which leaked those files and their `.builtin-hash` siblings into the repository root. The fix introduces a scratch workspace backed by a temporary directory that is intentionally leaked to keep the borrowed path alive for the test context.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add the initial set of foundational files for the project, including identity, role, soul, memory goals, and heartbeat documents along with their built-in hash references. This establishes the base structure for self-description and state tracking.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Removed the HEARTBEAT.md, IDENTITY.md, MEMORY_GOALS.md, ROLE.md, and SOUL.md files along with their corresponding builtin-hash markers, as these are no longer needed in the repository.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Fix a bug where optional fields with empty values were incorrectly rendered as missing, causing prompts to omit valid but empty content. The change ensures that empty strings are properly included in the rendered output when the field is present.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Removed the `HEARTBEAT.md` and `MEMORY_GOALS.md` entries from the default workspace file content lookup, as these files are no longer needed in the initial workspace setup.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
…ection

The HEARTBEAT.md file was removed from the list of files injected into agent prompts because the periodic-task domain it served has been deleted, leaving the file as an empty template that no consumer reads. The MEMORY_GOALS.md sync call was also removed since the file is now managed entirely by the memory_goals domain and no longer needs to be seeded to disk from the identity section.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Replace references to `HEARTBEAT.md` and `MEMORY_GOALS.md` with `ROLE.md` in doc comments across the prompt rendering helpers and orchestrator prompt test, reflecting the current set of bootstrap files that are actually written to the workspace.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Update the identity section test to assert that HEARTBEAT.md and MEMORY_GOALS.md are not created during workspace seeding, since the subconscious engine that consumed HEARTBEAT.md has been removed and the goals store handles missing files gracefully by returning an empty document.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Consolidated the `PromptContext` import into a single line in the orchestrator prompt module, reformatted the sub-agent tool assertion loop in the loader tests for readability, and simplified the conditional expression in the identity section prompt logic. These changes are purely stylistic and structural with no impact on behaviour.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
@senamakel
senamakel merged commit fb20425 into fix/ui-v4 Aug 24, 2026
3 of 4 checks passed
senamakel pushed a commit that referenced this pull request Oct 16, 2026
Review #11: links in the Markdown preview were plain anchors, so a click
navigated the app's own window away from OpenHuman. A click now never
navigates the app; an external link (`http(s)`, `mailto`, per
`isAllowedExternalHref`) opens in the system browser through `openUrl`,
as chat links do, and anything else does nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant