Skip to content

Add agent persona methods to the client - #24

Merged
tomchop merged 1 commit into
mainfrom
feat/agent-personas-client
Sep 4, 2026
Merged

Add agent persona methods to the client#24
tomchop merged 1 commit into
mainfrom
feat/agent-personas-client

Conversation

@tomchop

@tomchop tomchop commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Adds search_agent_personas, get_agent_persona, new_agent_persona and patch_agent_persona, covering Yeti's /api/v2/agentpersonas endpoints.

Why

yeti-agents reads and seeds personas over this API. Without these it builds the URLs itself:

f"{client._url_root}/api/v2/agentpersonas/search"

_url_root is private, and nothing obliges this class to keep it. Every other Yeti call in yeti-agents already goes through a typed method here — semantic_search was added for exactly this reason. Personas are ordinary Yeti objects with an ordinary CRUD API, so they belong alongside the other object types rather than being reconstructed by each caller, along with the response envelope ({"personas": [...], "total": n}) that callers currently unpack by hand.

Two deliberate departures from the neighbouring methods

No required arguments on search. search_entities and friends raise if you pass nothing, because an unfiltered dump of entities is rarely what anyone meant. For personas the opposite is true — listing all of them is the common case, and Yeti's PersonaSearchRequest already defaults name to "", meaning match-all.

enabled is three-valued. None means "either" and is omitted from the payload; False has to be sent, since it is a real filter and not an absent one. Guarding with if enabled: would silently turn a search for disabled personas into a search for all of them, so it is guarded with is not None and there is a test pinning it.

No delete method

do_request dispatches GET, POST and PATCH and raises ValueError on anything else, so DELETE /agentpersonas/{id} is not reachable from this client. Adding it means teaching do_request a new verb — out of scope here, and no caller needs it yet.

Testing

6 new tests, 37 total passing, matching the existing mock-the-Session style: each asserts both the parsed return value and the exact URL and payload sent.

Ran the three CI jobs locally against a fresh poetry install --no-root:

=== pyrefly ===   INFO 0 errors (1 warning not shown)
=== unittest ===  Ran 37 tests in 0.031s  OK
=== ruff ===      6 files already formatted

No dependency changes, so poetry.lock is untouched.

Follow-up

yeti-platform/yeti-agents#12 is held pending this: once released, it drops the private-attribute access and the hand-built endpoint constant in favour of these methods.

The agents service reads and seeds personas over Yeti's API, and had to build
those URLs itself from `_url_root` -- a private attribute of this class, which
nothing obliges it to keep. Personas are ordinary Yeti objects with an ordinary
CRUD API, so they belong here alongside the other object types rather than
being reconstructed by each caller.

search takes no required arguments, unlike the other search methods: listing
every persona is the common case, and Yeti's endpoint defaults to matching all.
`enabled` distinguishes None (either) from False, which has to reach the API.

No delete: do_request supports GET, POST and PATCH only.
@tomchop
tomchop merged commit a5f84c6 into main Sep 4, 2026
3 checks passed
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