Skip to content

feat: one first_speaker setting replaces persona_speaks_first - #293

Merged
luca-belli merged 1 commit into
release/2.1from
feat/first-speaker
Oct 27, 2026
Merged

luca-belli merged 1 commit into
release/2.1from
feat/first-speaker

Conversation

@luca-belli

Copy link
Copy Markdown
Collaborator

Summary

From your review on #289: "this is confusing. we should add a ROLE and the role speaks first." Stacked on #291. It should ship with #289 so configs change only once.

The flag named the speaking order from the chatbot's side (--provider-speaks-first) and the config field from the persona's side (persona_speaks_first), so the code had to flip one to match the other. Now there's one setting, named after who speaks:

Before After
CLI --provider-speaks-first (off by default) --first-speaker {user,chatbot} (default user)
Config "persona_speaks_first": true / false "first_speaker": "user" / "chatbot"

Why this shape

  • The values follow the CLI's u/c/j vocabulary (user, chatbot), the same words -u and -c use, rather than the internal Role.PERSONA / Role.PROVIDER names.
  • The schema stores a string, not Role. Role lives in llm_clients/llm_interface.py, and utils/ (where GenerationConfig lives) must not import llm_clients/; that's a layer rule. Moving Role into utils/role.py, as architecture.md asks, would let the schema use the enum. That's a separate internal cleanup.
  • The generation domain still takes a bool. run_for_user_models converts at that one boundary (first_speaker == "user"). Threading Role through the runner and simulator belongs with docs: design draft — run naming, order of events, and its enforcement #268's internal renames.
  • Old configs fail loudly. A config with persona_speaks_first stops with "generation.persona_speaks_first was renamed: use "first_speaker": "user" in place of true, or "chatbot" in place of false", rather than a generic missing-field error.
  • It's still a result field, so it's required in config files (feat: let config files leave out output and speed fields #289).

Changes

  • utils/config_schema.py: GenerationConfig.first_speaker, validated against FIRST_SPEAKERS = ("user", "chatbot")
  • vera_cli/generate.py: the flag, DEFAULTS, RESULT_FIELDS, and the rename error
  • configs/*.json, the replay and e2e test configs, cli.md, vera-cli-use-cases.md, architecture.md, and CHANGELOG (under Breaking)
  • New tests: the old field gets the rename error, and an unknown value is rejected

Testing

Ruff and pyright pass. I haven't run the tests, per your rule; CI isn't triggered automatically because this PR is stacked.

🤖 Generated with Claude Code

@luca-belli
luca-belli added this pull request to stack #292 October 26, 2026 23:37
@luca-belli
luca-belli marked this pull request as ready for review October 26, 2026 23:38
@luca-belli
luca-belli requested a review from a team as a code owner October 26, 2026 23:38

@jgieringer jgieringer left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM - unsure if the role enum has been removed or if it's usable here


# Who opens the conversation, in the CLI's u/c vocabulary: the user-side LLM
# playing the persona, or the chatbot under test.
FIRST_SPEAKERS = ("user", "chatbot")

@jgieringer jgieringer Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

do we want to use the Role enums?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

in your Enum era

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

but it's a good question, and the answer is that now Role uses the old wording so we can do that once we call the thing chatbot consistency everywhere

Base automatically changed from feat/run-record to release/2.1 October 27, 2026 19:28
The flag said who speaks first from the chatbot's side
(--provider-speaks-first) and the config field from the persona's
(persona_speaks_first), so one had to be flipped to match the other.
Both become first_speaker, "user" or "chatbot", in the CLI's u/c
vocabulary: --first-speaker on the CLI (default user), first_speaker in
a config file. A config with the old field stops with an error naming
the new one. configs/ is updated.

The generation domain still takes a bool; run_for_user_models converts
at that one boundary.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@luca-belli
luca-belli merged commit 2408423 into release/2.1 Oct 27, 2026
3 checks passed
@luca-belli
luca-belli deleted the feat/first-speaker branch October 27, 2026 19:33
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.

2 participants