Automattic / Automattic/agents-api
Conversation store: owner-based session creation (session_owner) isn't in the WP_Agent_Conversation_Store interface
- Dominant language
- PHP
- Stars
- 33
- Forks
- 8
- Avg merge
- 1h 36m
- Merged PRs (30d)
- 31
Description
## Summary
The canonical `agents/chat` input schema promotes a **`session_owner`** concept for transcripts that aren't owned by a logged-in user — `agents_chat_session_owner_schema()` documents it as:
> Opaque, isolating owner for persisted conversation sessions. Use for anonymous browser or external-channel chats when no logged-in user owns the transcript. … such as `user:`, `browser:`, or a channel-specific conversation key.
But the **`WP_Agent_Conversation_Store` interface** only offers a user-centric creation method:
```php
// src/Transcripts/class-wp-agent-conversation-store.php:63
public function create_session( WP_Agent_Workspace_Scope $workspace, int $user_id, string $agent_slug = '', array $metadata = array(), string $context = 'chat' ): string;
```
The owner-based creation that matches `session_owner` exists **only on the concrete CPT implementation**, not in the interface:
```php
// src/Transcripts/class-wp-agent-cpt-conversation-store.php:193
public function create_session_for_owner( WP_Agent_Workspace_Scope $workspace, array $owner, string $agent_slug = '', array $metadata = array(), string $context = 'chat' ): string;
```
## Impact
A consumer coding against the contract (resolving the store via `apply_filters( 'wp_agent_conversation_store', null )` and treating it as a `WP_Agent_Conversation_Store`) **cannot portably create an anonymous / browser-owned session** — the only interface method requires an `int $user_id`. To use the very `session_owner` vocabulary the chat schema defines, you have to either bind to the concrete `WP_Agent_Cpt_Conversation_Store` (defeating the interface) or fall back to `user_id = 0`, which conflates "guest" with "no owner."
Concretely: an anonymous public chat surface (e.g. a served site, a support widget) has no `user_id`, and `session_owner: { type: "browser", key: "" }` is exactly the intended model — but it's unreachable through the contract.
## Proposal
Promote owner-based creation to the `WP_Agent_Conversation_Store` interface so the contract matches the canonical `session_owner` vocabulary. Either:
- add `create_session_for_owner( WP_Agent_Workspace_Scope $workspace, array $owner, … ): string` to the interface, or
- make `create_session` accept an owner (e.g. `int|array $user_or_owner`, or an optional `?array $owner` that supersedes `$user_id`).
The CPT store already implements it; this is mostly about lifting it into the contract (+ a default/adapter for stores that only know `user_id`).
## Secondary observation
The `agents/chat` dispatcher (`src/Channels/register-agents-chat-ability.php`) doesn't write to the registered conversation store — persistence is entirely consumer-wired. That may be intentional (consumers own materialization policy), but it's worth a doc note, since both the store and the canonical `session_owner` shape exist and a newcomer reasonably expects the chat path to use them.
## Context
Surfaced while building an example consumer (an "agent-served site" on agents-api + wp-ai-client): https://github.com/lezama/agent-served-site — its `Session_Store` resolves the store via the filter and uses `create_session`/`get_session`/`update_session`, and had to settle for `user_id` instead of a browser owner for anonymous visitors. Related: #324 (per-agent `register_chat_handler` routing).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.