Skip to content

feat: add persona to agent settings (DEVP-624) - #294

Merged
toswe merged 4 commits into
mainfrom
svet/devp-624-add-persona-to-agent-settings
Aug 28, 2026
Merged

feat: add persona to agent settings (DEVP-624)#294
toswe merged 4 commits into
mainfrom
svet/devp-624-add-persona-to-agent-settings

Conversation

@toswe

@toswe toswe commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Replaces the separate Personality and Role settings in ADK with the single free-text persona resource that superseded them in Agent Studio. agent_settings/persona.txt now pulls, pushes and diffs; personality.yaml and role.yaml are gone, and a migration deletes them from existing project directories.

Motivation

DEVP-624

On the wire the merged Role field is a new persona component on agentSettings. ADK had no persona resource at all, so pull dropped the field builders actually author, push could only write the dead settings, and diff across environments silently ignored the primary identity field.

Changes

  • SettingsPersona in resources/agent_settings.py — plain-text agent_settings/persona.txt, modelled on SettingsRules, registered via @register_resource("persona")
  • References validated against {{attr:}} and {{vrbl:}} — the same two the personality and role custom fields accepted. Attribute references travel in the content and are not tracked on the resource, since PersonaReferences is variables-only; so were PersonalityReferences and RoleReferences, so this is not new
  • update_persona always carries a variables map (possibly empty) — the backend schema requires the key whenever references is sent
  • from_projection reads persona.content, not the persona object — the projection always carries the object, so absent content just means there is nothing to write to disk. An authored empty string is a real persona and is kept
  • SettingsPersonality and SettingsRole deleted. They still exist on the wire but nothing surfaces them, so keeping them registered only leaves two files that pull, push and validate while affecting nothing
  • Migration removed_personality_and_role_files deletes agent_settings/personality.yaml and role.yaml the first time a project is loaded, logging what it removed and telling the builder to pull to get persona.txt. file_structure_info is recomputed from the loaded resources on every load, so the stale status entries drop out on their own
  • Docs: the packaged docs/agent_settings.md + docs/docs.md, and the mkdocs site — the resource reference, architecture guide, working-locally tree, tooling/CLI tables and the restaurant tutorial all walked builders through personality.yaml and role.yaml

On the compiled backfill

For a project that has never authored a persona, the content the projection returns is derived server-side from the old personality + role and stored nowhere. This is deliberately left as-is rather than detected and skipped: push_project only sends resources whose on-disk hash differs from the pulled snapshot, so an untouched persona.txt is never pushed back, and editing the file authors a real persona — which is the intent. Documented in docs/agent_settings.md.

Test strategy

  • Added/updated unit tests
  • Manual CLI testing (poly docs agent_settings)
  • Tested against a live Agent Studio project

New coverage: SettingsPersonaTests (15 cases — raw/pretty roundtrip, attribute and variable validation, {{fn:}} rejection, update proto with and without references, from_projection for present / absent-content / absent-object / empty-string) and TestRemovePersonalityAndRoleFiles for the migration (no-op without agent_settings/, both files removed with the warning logged, other settings files untouched).

Also verified offline that a Command(type="update_persona", ...) builds, serialises and round-trips with references.variables populated.

Not yet run against a live project — poly pull / poly push on a real project is still outstanding.

Checklist

  • ruff check . and ruff format --check . pass
  • pytest passes (1352 passed, 112 subtests)
  • No breaking changes to the poly CLI interface
  • Commit messages follow conventional commits

🤖 Generated with Claude Code

Agent Studio replaced the separate Personality and Role settings with a
single free-text Role field, which on the wire is a new `persona`
component on agentSettings. ADK had no persona resource, so pull dropped
the field builders actually author, push could only write the legacy
settings the UI no longer surfaces, and diff ignored the primary identity
field entirely.

Adds SettingsPersona as agent_settings/persona.txt, a plain-text resource
modelled on rules.txt. References are validated against variables only —
PersonaReferences has no attributes map, unlike the personality and role
references — and update_persona always carries a variables map, since the
backend schema requires the key whenever references are sent.

from_projection treats absent persona.content as "not enabled for this
project" rather than an error: a project without the enable-persona-prompt
flag still has a persona object in the projection, just without content,
so nothing is written and nothing fails. An authored empty string is a
real persona and is kept.

For a project that has never authored a persona, the content pulled is
derived server-side from personality + role and stored nowhere. That is
left as-is: push only sends resources whose on-disk hash has changed, so
an untouched persona.txt is never pushed back, and editing the file
authors a real persona — which is the intent. Documented in
docs/agent_settings.md.

Two smaller consequences handled:

- A persona created locally (flag off, or a status file predating this
  change) classifies as new, but there is no create_persona command.
  _clean_resources_before_push moves it into the updated set instead.
- personality.yaml and role.yaml still push, but no longer affect what the
  agent shows. push now records a warning when either changes on a project
  that has a persona, surfaced by the CLI and in --json output.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@toswe
toswe requested a review from a team August 27, 2026 13:50
@toswe
toswe requested a review from a team as a code owner August 27, 2026 13:50
@linear-code

linear-code Bot commented Aug 27, 2026

Copy link
Copy Markdown

DEVP-624

@github-actions

This comment has been minimized.

…rences

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

This comment has been minimized.

@Ruari-Phipps Ruari-Phipps 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.

If personality and role are deprecated, I think we should delete them from the ADK?
(Or de-register them if we want to keep code for some reason)
That way we shouldn't have issues with people trying to push and don't need the push warnings.

Additionally, we should probably have a migration step that deletes the old files. Maybe put out a log warning that they have been migrated and need to pull to get the persona

Thirdly, can we update the main docs as well. Thanks!

Comment thread src/poly/project.py Outdated
Comment on lines +1556 to +1558
# There is no create_persona command; authoring a persona is an update.
if new_personas := new_resources.pop(SettingsPersona, None):
updated_resources.setdefault(SettingsPersona, {}).update(new_personas)

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.

Is this needed? pre push we do a pull, that should mean it exists

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed.

Comment thread src/poly/project.py Outdated
Comment on lines +1297 to +1308
if new_state.get(SettingsPersona):
shadowed = [
resource.file_path
for resource_type in (SettingsPersonality, SettingsRole)
for resource in updated_resources.get(resource_type, {}).values()
]
if shadowed:
self.push_warnings.append(
f"{', '.join(sorted(shadowed))} changed, but this project uses "
f"{next(iter(new_state[SettingsPersona].values())).file_path} — "
"personality and role no longer affect the Role field in Agent Studio."
)

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.

I think we should just deprecate, so not even read them

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed as well.

Agent Studio replaced both settings with a single free-text persona, so
keeping them registered only leaves two files that pull, push and validate
while affecting nothing. They are deleted rather than left in place with a
push warning: nothing to shadow means no warning to surface, and no way to
edit a dead setting by accident.

A migration deletes agent_settings/personality.yaml and role.yaml the first
time a project is loaded, logging what it removed and telling the builder to
pull to get persona.txt. file_structure_info is recomputed from the loaded
resources on every load, so the stale status entries drop out on their own.

Also drops the create-persona-as-update special case in
_clean_resources_before_push: push pulls before it classifies, so the persona
is always in the snapshot and never lands in the new set.

Main docs updated alongside the packaged ones — the mkdocs reference,
architecture guide and the restaurant tutorial all walked builders through
personality.yaml and role.yaml.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

This comment has been minimized.

The persona validated against variables only, while the personality and
role settings it replaced accepted {{attr:}} and {{vrbl:}} in their custom
text. That restriction was read off PersonaReferences having no attributes
map — but PersonalityReferences and RoleReferences are variables-only too,
so the map was never the reason attributes worked, and narrowing the
persona dropped a reference type builders had.

Attribute references travel in the content and are not tracked on the
resource, exactly as they were on personality and role. push still
validates that the attribute exists.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

This comment has been minimized.

1 similar comment
@github-actions

This comment has been minimized.

@toswe
toswe force-pushed the svet/devp-624-add-persona-to-agent-settings branch from 6dd793c to 5d468f4 Compare August 28, 2026 10:30
@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report

Base (main) PR Change
75.9% 75.9% +0.0% ✅

Changed file coverage

File Coverage Change
poly/resources/agent_settings.py 94.3% +4.4% ✅
poly/migration_utils.py 97.4% +0.4% ✅

@Ruari-Phipps Ruari-Phipps 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.

Nice!

@toswe
toswe merged commit ecc7d9d into main Aug 28, 2026
14 checks passed
@toswe
toswe deleted the svet/devp-624-add-persona-to-agent-settings branch August 28, 2026 11:40
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