Automattic / Automattic/agents-api

Conversation store: owner-based session creation (session_owner) isn't in the WP_Agent_Conversation_Store interface

Open
#325 0 comments 0 reactions 0 assignees View on GitHub
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.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.