Skip to content

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

Description

@lezama

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:<id>, browser:<opaque id>, or a channel-specific conversation key.

But the WP_Agent_Conversation_Store interface only offers a user-centric creation method:

// 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:

// 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: "<opaque>" } 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions