Skip to content

Keep a seat itself on every turn, not just its first - #74

Merged
sanil-23 merged 1 commit into
tinyhumansai:mainfrom
sanil-23:fix/seat-persona
Sep 23, 2026
Merged

sanil-23 merged 1 commit into
tinyhumansai:mainfrom
sanil-23:fix/seat-persona

Conversation

@sanil-23

@sanil-23 sanil-23 commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

A hosted seat's session is cleared and reseeded from the host's log every turn. Seeding brings the runtime session up before the turn runs, and a session that already has one is not cold — and only a cold turn composes its system prompt. So a seat had its persona on its first turn of an episode and none on any turn after: no role, no team, no company, just the episode brief.

It still answered, which is why nothing complained. It simply was not being itself, from turn two onward, in every multi-turn episode.

EpisodeHost::persona gives a host somewhere to hand the standing prompt back from, and the seeded history carries it at the head, where the turn reads it as the system message it would otherwise have composed.

Related issue

None.

API or behavior changes

One new trait method on EpisodeHost:

fn persona(&self, seat: &str) -> Option<String> { None }

Defaulted, so every existing host compiles and behaves exactly as before. A host that implements it gets the prompt back on its seeded turns.

Not breaking.

Validation

Commands actually run, with their outcome:

  • cargo fmt --all -- --check — passes
  • cargo clippy --all-targets --all-features -- -D warnings — not run
  • cargo build --all-targets --all-features — not run
  • cargo test --all-features — not run

The three unticked commands need this repository's own vendor/openhuman, which is uninitialised in the checkout I worked from, so I did not run them rather than claim them. CI covers them.

The change was verified end to end downstream in OpenCompany, which implements EpisodeHost. Before it, roughly half of all seat turns arrived with no system message at all; after it, none do. An episode carrying an agent-to-agent conversation previously ran sixty seconds into the turn wall without concluding, and now finishes in just over one second.

Tests

None added here. The behaviour needs a host that supplies a persona and a seat taking a second turn, which this repository has no fixture for — its own runners do not implement the new method. A test that exercises the seeding path properly is worth doing and I would rather it were deliberate work than something bolted onto this fix.

Documentation

The trait method carries the explanation: why a seeded turn is warm, why only a cold turn composes its prompt, and why the insert is conditional on there being history to seed.

Checklist

  • The change is focused on one logical change
  • No new #[allow(...)], #[ignore], or relaxed lints
  • No secrets, tokens, or .env contents in the diff or the description

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Hosted conversations can now include a host-provided persona as system context on subsequent turns when conversation history is available. This helps preserve the intended role and behavior across turns. If no persona is provided, or the conversation has no prior history, the existing behavior remains unchanged.

A hosted seat's session is cleared and reseeded from the host's log each
turn. Seeding brings the runtime session up before the turn runs, and a
session that already has one is not cold -- and only a cold turn composes
its system prompt. So a seat had its persona on its first turn of an
episode and none on any turn after: no role, no team, no company, just the
episode brief.

It still answered, which is why nothing complained. It simply was not being
itself, from turn two onward, in every multi-turn episode.

`EpisodeHost::persona` gives a host somewhere to hand the standing prompt
back from, and the seeded history carries it at the head, where the turn
reads it as the system message it would otherwise have composed. Only when
there is history to seed: with none, seeding is skipped and the turn is
cold, which is the one case that already renders the prompt itself.

Defaulted to `None`, so a host with no standing prompt is unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>
@tinysweeper

tinysweeper Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

Tiny Sweeper review

Tiny Sweeper reviewed this change across 6 lane(s) and found 1 active actionable finding(s). Detailed lane evidence and any incomplete work are listed below.

State: Ready for maintainer review
Priority: medium
Reviewed head: 8a8c47c65543
Updated: 1790171851 (Unix time)

Review snapshot

Change surface Files Review signal Count
Production 1 Active findings 1
Tests 0 Noted findings 0
Documentation 0 Resolved findings 0
Configuration 0 Pending checks/questions 0

Completeness: Complete
Test assessment: No supported feature-to-test mapping was available; this does not mean tests are absent or passed.

What changed

The review could not produce a supported behavioral summary; inspect the cited changed surface and lane details below.

Features

None identified with supported citations.

Tests

No supported feature-to-test mapping was produced. Test execution is not inferred.

Findings

  • medium · description · Add a test for the persona insertion on seeded turns — The repository rule reads: "Write the test first when fixing a bug." This commit fixes a bug (persona was missing from non-cold turns) but no test was added to cover the new behav (\(pull request description\))

Before merge

None.

How this fits together

flowchart LR
  n0["BoundAgent"]:::impacted
  n1["turn"]:::impacted
  n2["new"]:::impacted
  n3["HostedSeat"]:::impacted
  n4["HostedRunner"]:::impacted
  n5["seat"]:::impacted
  n1 -->|calls| n2
  n3 -->|implements| n0
  n4 -->|uses| n3
  n5 -->|calls| n2
  n5 -->|uses| n3
  classDef changed fill:#0d4429,stroke:#238636,color:#e6edf3
  classDef impacted fill:#161b22,stroke:#6e7681,color:#c9d1d9
  classDef flagged fill:#5a1e02,stroke:#d93f0b,color:#ffffff
  classDef blocking fill:#67060c,stroke:#f85149,color:#ffffff
Loading
Agent review details

critique

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: The change adds an opt-in persona hook and safely prepends it to seeded hosted-session history when history exists. No correctness issue is evident in the reviewed file, so it is safe to merge. _The code index is behind this pull request (indexed at `808b3a4551c5`), so retrieved context may be out of date._ _Memory was unavailable (model: cortex: v1/recall: timed out after 10s), so this review ran without it._

security

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: The change adds an optional host-provided persona when reseeding a non-cold hosted session. It does not introduce a security issue and looks safe to merge. _The code index is behind this pull request (indexed at `808b3a4551c5`), so retrieved context may be out of date._ _Memory was unavailable (model: cortex: v1/recall: timed out after 10s), so this review ran without it._

tests

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: Adds a `persona` method to `EpisodeHost` that lets the host supply a standing system message for non-first turns, and inserts it at the head of seeded history. No test exercises this new codepath, so a regression in the insertion logic or in the trait's contract would be silent. Add a test that verifies the persona is inserted, and that a `None` return keeps the old behaviour. (1 finding discarded for not matching a changed line) _The code index is behind this pull request (indexed at `808b3a4551c5`), so retrieved context may be out of date._ _Memory was unavailable (model: cortex: v1/recall: timed out after 10s), so this review ran without it._

commits

  • Conclusion: Neutral
  • Scope reviewed: all assigned evidence
  • Lane summary: Nothing sensitive found in what this pull request commits.

description

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: The change fixes a bug by inserting a host-supplied persona into seeded history on non-cold turns, which is correct and well-structured. However, it violates the repository rule to write a test first when fixing a bug: no test was added, as stated explicitly in the pull request. _The code index is behind this pull request (indexed at `808b3a4551c5`), so retrieved context may be out of date._ _Memory was unavailable (model: cortex: v1/recall: timed out after 10s), so this review ran without it._
  • Evidence: \(pull request description\) — Add a test for the persona insertion on seeded turns

e2e

  • Conclusion: Neutral
  • Scope reviewed: all assigned evidence
  • Lane summary: No end-to-end harness in this repository: no e2e test files and no e2e workflow.
Evidence and run details
  • Models: ladder/vectors, gpt-5.6-luna, deepseek-v4-flash
  • Spend: $0.004399
  • Tokens: 112333 input · 10041 output · 4595 cached · 166 embedding
Head State Pass summary
8a8c47c65543 ready for maintainer review 1 active finding(s), 0 resolved finding(s) (at 1790171851)

tinysweeper 0.1.0

@coderabbitai

coderabbitai Bot commented Sep 23, 2026

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: bb650735-6665-412e-bdd8-63024b581583

📥 Commits

Reviewing files that changed from the base of the PR and between 9d35b44 and 8a8c47c.

📒 Files selected for processing (1)
  • crates/tinyhivemind-openhuman/src/hosted/mod.rs
 ________________________________________________________________
< This is the kind of code that makes on-call believe in ghosts. >
 ----------------------------------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).

Comment @coderabbitai help to get the list of available commands.

@sanil-23
sanil-23 merged commit 8cc4dc9 into tinyhumansai:main Sep 23, 2026
3 of 6 checks passed

@tinysweeper tinysweeper Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tinysweeper found nothing blocking. Approving.

             $0.0044 · 112,333 in / 10,041 out · 4,595 cached (4%)  · ladder/vectors, gpt-5.6-luna, deepseek-v4-flash · 166 embedded
critique:    $0.0015 · 46,741 in  / 1,847 out  · 2,035 cached (4%)  · gpt-5.6-luna
security:    $0.0022 · 46,478 in  / 1,079 out  · 0 cached (0%)      · gpt-5.6-luna
tests:       $0.0003 · 12,760 in  / 1,341 out  · 1,536 cached (12%) · deepseek-v4-flash
description: $0.0002 · 4,180 in   / 3,480 out  · 1,024 cached (24%) · deepseek-v4-flash

sanil-23 added a commit that referenced this pull request Sep 23, 2026
`main` has been red since #74. The Rust lane's clippy step and the Docs
lane both fail on `missing documentation for a method` at
`EpisodeHost::tool_prefix`, and every branch cut from main inherits it.

Nothing was ever missing. `tool_prefix`'s doc block is intact -- it sits
above `persona`, fused to `persona`'s own first line with no blank
between them, and `tool_prefix` itself was left bare a few lines below.
A merge slip, not a gap: the prose describing the prefix still reads
correctly, just over the wrong method.

Moving the method back under its own doc fixes both lanes.
`cargo clippy --all-targets --all-features -- -D warnings` and
`cargo doc --no-deps --all-features` are exit 0, and the suite is
unchanged at 36 targets.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant