diff --git a/README.md b/README.md index 43fdd25..2a1ecc7 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ It's a small, focused WordPress package maintained by Automattic. Think of it as **What you don't get — and shouldn't expect:** a concrete workflow runtime, durable run history, an editor UI, admin screens, or any provider-specific AI client. Those belong to your product. Agents API is the substrate, not the application. -New here? Start with the [developer documentation](docs/README.md). +New here? Start with the [Introduction](docs/introduction.md) — it breaks down the core concepts and vocabulary in plain language — then browse the [developer documentation](docs/README.md). ## Layer Boundary diff --git a/docs/README.md b/docs/README.md index af43af7..9b3e439 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,11 +2,18 @@ Developer-facing documentation for Agents API, a WordPress-shaped substrate for agent registration, runtime contracts, channels, workflows, auth, memory, and related extension points. +**New here? Read the [Introduction](introduction.md) first** — it explains the core idea and the vocabulary the rest of these docs assume. + ## Quick Navigation +### Start Here + +- [Introduction](introduction.md) - the one-sentence version, the three layers, the core vocabulary, and how a single request flows through the runtime. The on-ramp for anyone new to the concepts. + ### Architecture And Runtime - [Architecture](architecture.md) - module inventory, bootstrap lifecycle, substrate boundary, extension principles, and operational workflow. +- [Capability Map](capability-map.md) - reference mapping each capability an AI runtime needs to the substrate primitive that provides it, with contract locations. - [Registry and Packages](registry-and-packages.md) - agent registration, `WP_Agent`, package manifests, package artifacts, and artifact type registration. - [Runtime and Tools](runtime-and-tools.md) - conversation loop, request/result objects, tool declarations, mediation, policies, budgets, compaction, and events. @@ -27,7 +34,9 @@ Developer-facing documentation for Agents API, a WordPress-shaped substrate for ```text docs/ +-- README.md # This navigation index ++-- introduction.md # Concepts + vocabulary on-ramp for newcomers +-- architecture.md # Substrate architecture and module inventory ++-- capability-map.md # Capability -> primitive reference map +-- registry-and-packages.md # Agent and package registration contracts +-- runtime-and-tools.md # Runtime loop and tool mediation contracts +-- auth-consent-context-memory.md # Auth, consent, context, and memory contracts diff --git a/docs/capability-map.md b/docs/capability-map.md new file mode 100644 index 0000000..bbff3e7 --- /dev/null +++ b/docs/capability-map.md @@ -0,0 +1,92 @@ +# Capability Map + +A reference mapping the capabilities an AI agent runtime needs to the Agents API +primitive that provides each one. Use it to see at a glance what the substrate +already provides and where each contract lives. + +Each row names a capability, the primitive(s) that provide it, the contract in +the source tree, and the topic page with method-level detail. "Capability" is +phrased the way a custom runtime usually thinks about it, so a team evaluating +the substrate can match their own components against it. + +## Runtime and loop + +| Capability | Agents API primitive | Contract | Detail | +|---|---|---|---| +| Multi-turn orchestration loop | `WP_Agent_Conversation_Loop` | [`src/Runtime/class-wp-agent-conversation-loop.php`](../src/Runtime/class-wp-agent-conversation-loop.php) | [Runtime and Tools](runtime-and-tools.md) | +| Normalized message envelope | `WP_Agent_Message` | [`src/Runtime/class-wp-agent-message.php`](../src/Runtime/class-wp-agent-message.php) | [Runtime and Tools](runtime-and-tools.md) | +| Request / result value objects | `WP_Agent_Conversation_Request`, `WP_Agent_Conversation_Result` | [`src/Runtime/`](../src/Runtime/) | [Runtime and Tools](runtime-and-tools.md) | +| Completion / continuation policy | `WP_Agent_Conversation_Completion_Policy` | [`src/Runtime/class-wp-agent-conversation-completion-policy.php`](../src/Runtime/class-wp-agent-conversation-completion-policy.php) | [Runtime and Tools](runtime-and-tools.md) | +| Long-conversation trimming | `WP_Agent_Conversation_Compaction`, markdown-section adapter | [`src/Runtime/class-wp-agent-conversation-compaction.php`](../src/Runtime/class-wp-agent-conversation-compaction.php) | [Runtime and Tools](runtime-and-tools.md) | +| Iteration / runaway limits | `WP_Agent_Iteration_Budget` | [`src/Runtime/class-wp-agent-iteration-budget.php`](../src/Runtime/class-wp-agent-iteration-budget.php) | [Runtime and Tools](runtime-and-tools.md) | +| Transcript persistence hook | `WP_Agent_Transcript_Persister` | [`src/Runtime/class-wp-agent-transcript-persister.php`](../src/Runtime/class-wp-agent-transcript-persister.php) | [Runtime and Tools](runtime-and-tools.md) | +| Lifecycle events / observability | `agents_api_loop_event` action + `on_event` sink | [`src/Runtime/class-wp-agent-conversation-loop.php`](../src/Runtime/class-wp-agent-conversation-loop.php) | [Runtime and Tools](runtime-and-tools.md) | + +## Tools + +| Capability | Agents API primitive | Contract | Detail | +|---|---|---|---| +| Tool-call execution / dispatch | `WP_Agent_Tool_Execution_Core` + `WP_Agent_Tool_Executor` | [`src/Tools/class-wp-agent-tool-execution-core.php`](../src/Tools/class-wp-agent-tool-execution-core.php), [`class-wp-agent-tool-executor.php`](../src/Tools/class-wp-agent-tool-executor.php) | [Runtime and Tools](runtime-and-tools.md) | +| Tool declarations / parameters | `WP_Agent_Tool_Declaration`, `WP_Agent_Tool_Parameters` | [`src/Tools/`](../src/Tools/) | [Runtime and Tools](runtime-and-tools.md) | +| Tool visibility policy | `WP_Agent_Tool_Policy` | [`src/Tools/class-wp-agent-tool-policy.php`](../src/Tools/class-wp-agent-tool-policy.php) | [Runtime and Tools](runtime-and-tools.md) | +| Action gating (`direct`/`preview`/`forbidden`) | `WP_Agent_Action_Policy_Resolver` | [`src/Tools/class-wp-agent-action-policy-resolver.php`](../src/Tools/class-wp-agent-action-policy-resolver.php) | [Runtime and Tools](runtime-and-tools.md) | +| Tool-call/result pairing repair | `WP_Agent_Tool_Pair_Validator` | [`src/Runtime/class-wp-agent-tool-pair-validator.php`](../src/Runtime/class-wp-agent-tool-pair-validator.php) | [Runtime and Tools](runtime-and-tools.md) | +| Abilities API lifecycle integration | Ability lifecycle bridge | [`src/Abilities/class-wp-agent-ability-lifecycle-bridge.php`](../src/Abilities/class-wp-agent-ability-lifecycle-bridge.php) | [Runtime and Tools](runtime-and-tools.md) | + +## Transcripts and sessions + +| Capability | Agents API primitive | Contract | Detail | +|---|---|---|---| +| Session / transcript storage | `WP_Agent_Conversation_Store` | [`src/Transcripts/class-wp-agent-conversation-store.php`](../src/Transcripts/class-wp-agent-conversation-store.php) | [Channels, Workflows, and Operations](channels-workflows-operations.md) | +| Non-user (principal) owned sessions | `WP_Agent_Principal_Conversation_Store` | [`src/Transcripts/class-wp-agent-principal-conversation-store.php`](../src/Transcripts/class-wp-agent-principal-conversation-store.php) | [Channels, Workflows, and Operations](channels-workflows-operations.md) | +| Single-writer transcript lock | `WP_Agent_Conversation_Lock` | [`src/Transcripts/class-wp-agent-conversation-lock.php`](../src/Transcripts/class-wp-agent-conversation-lock.php) | [Channels, Workflows, and Operations](channels-workflows-operations.md) | +| Built-in WordPress-native store | `WP_Agent_Cpt_Conversation_Store` (opt-in) | [`src/Transcripts/class-wp-agent-cpt-conversation-store.php`](../src/Transcripts/class-wp-agent-cpt-conversation-store.php) | [Default Stores Companion Proposal](default-stores-companion.md) | + +## Memory and context + +| Capability | Agents API primitive | Contract | Detail | +|---|---|---|---| +| Agent memory store | `WP_Agent_Memory_Store` + value objects | [`src/Memory/`](../src/Memory/) | [Auth, Consent, Context, and Memory](auth-consent-context-memory.md) | +| Memory / context source registry | `WP_Agent_Memory_Registry` | [`src/Context/class-wp-agent-memory-registry.php`](../src/Context/class-wp-agent-memory-registry.php) | [Auth, Consent, Context, and Memory](auth-consent-context-memory.md) | +| Composable context assembly | `WP_Agent_Context_Section_Registry`, `WP_Agent_Composable_Context` | [`src/Context/`](../src/Context/) | [Auth, Consent, Context, and Memory](auth-consent-context-memory.md) | +| Retrieved-context authority / conflict | `WP_Agent_Context_Item`, conflict resolver | [`src/Context/`](../src/Context/) | [Auth, Consent, Context, and Memory](auth-consent-context-memory.md) | + +## Identity and auth + +| Capability | Agents API primitive | Contract | Detail | +|---|---|---|---| +| Acting-user / agent identity | `WP_Agent_Execution_Principal` | [`src/Runtime/class-wp-agent-execution-principal.php`](../src/Runtime/class-wp-agent-execution-principal.php) | [Auth, Consent, Context, and Memory](auth-consent-context-memory.md) | +| Bearer-token authentication | `WP_Agent_Token_Authenticator`, `WP_Agent_Token_Store` | [`src/Auth/class-wp-agent-token-authenticator.php`](../src/Auth/class-wp-agent-token-authenticator.php) | [Auth, Consent, Context, and Memory](auth-consent-context-memory.md) | +| Capability ceiling / authorization | `WP_Agent_Capability_Ceiling`, `WP_Agent_Authorization_Policy` | [`src/Auth/class-wp-agent-capability-ceiling.php`](../src/Auth/class-wp-agent-capability-ceiling.php), [`class-wp-agent-authorization-policy.php`](../src/Auth/class-wp-agent-authorization-policy.php) | [Auth, Consent, Context, and Memory](auth-consent-context-memory.md) | +| Access grants | `WP_Agent_Access_Grant`, `WP_Agent_Access_Store` | [`src/Auth/`](../src/Auth/) | [Auth, Consent, Context, and Memory](auth-consent-context-memory.md) | +| Cross-agent (A2A) caller context | `WP_Agent_Caller_Context` | [`src/Auth/class-wp-agent-caller-context.php`](../src/Auth/class-wp-agent-caller-context.php) | [Auth, Consent, Context, and Memory](auth-consent-context-memory.md) | + +## Approvals and consent + +| Capability | Agents API primitive | Contract | Detail | +|---|---|---|---| +| Human-in-the-loop approvals | Pending action primitives (`WP_Agent_Pending_Action`, store, resolver, handler) | [`src/Approvals/`](../src/Approvals/) | [Channels, Workflows, and Operations](channels-workflows-operations.md) | +| Consent decisions | `WP_Agent_Consent_Policy` | [`src/Consent/class-wp-agent-consent-policy.php`](../src/Consent/class-wp-agent-consent-policy.php) | [Auth, Consent, Context, and Memory](auth-consent-context-memory.md) | + +## Orchestration and registration + +| Capability | Agents API primitive | Contract | Detail | +|---|---|---|---| +| Workflows (multi-step) | Workflow spec / validator / runner | [`src/Workflows/`](../src/Workflows/) | [Channels, Workflows, and Operations](channels-workflows-operations.md) | +| Scheduled / recurring runs | `WP_Agent_Routine` + Action Scheduler bridge | [`src/Routines/class-wp-agent-routine.php`](../src/Routines/class-wp-agent-routine.php) | [Channels, Workflows, and Operations](channels-workflows-operations.md) | +| External channels / bridges | `WP_Agent_Channel`, bridge primitives | [`src/Channels/`](../src/Channels/) | [Channels, Workflows, and Operations](channels-workflows-operations.md) | +| Agent registration / lookup | `WP_Agent`, `WP_Agents_Registry` | [`src/Registry/class-wp-agent.php`](../src/Registry/class-wp-agent.php), [`class-wp-agents-registry.php`](../src/Registry/class-wp-agents-registry.php) | [Registry and Packages](registry-and-packages.md) | +| Packaging / artifacts | `WP_Agent_Package`, artifact registry | [`src/Packages/`](../src/Packages/) | [Registry and Packages](registry-and-packages.md) | + +## Extension points + +Each store/policy the substrate offers a default for is reachable through a +filter, so a consumer plugs in its own backend without forking: + +| Filter | Replaces | +|---|---| +| `wp_agent_conversation_store` | Transcript / session backend | +| `wp_agent_memory_store` | Memory backend | +| `wp_agent_pending_action_store` | Approval queue backend | +| `agents_api_execution_principal` | How the current principal is resolved | +| `agents_api_enable_default_conversation_store` | Opt in to the built-in WordPress-native conversation store | diff --git a/docs/introduction.md b/docs/introduction.md new file mode 100644 index 0000000..5720a31 --- /dev/null +++ b/docs/introduction.md @@ -0,0 +1,134 @@ +# Introduction to Agents API + +New to Agents API? Start here. This page explains the core idea, the vocabulary +the rest of the docs assume, and how a single request flows through the runtime. +It assumes you know WordPress and the general shape of LLM apps, but not any of +this project's terms. + +## The one-sentence version + +Agents API is the **runtime layer that turns a single model call into a +multi-turn, tool-using agent** — it owns the loop, the transcript, tool +mediation, memory, and identity, so your plugin only has to supply the parts +that are actually yours. + +## Where it sits + +Three layers cooperate to build an agent on WordPress: + +| Layer | Answers | Provided by | +|---|---|---| +| **AI Client** | "How do I call a model?" | `wp-ai-client` (talk to OpenAI / Anthropic / etc.) | +| **Abilities API** | "What is the AI allowed to do?" | WordPress core — a registry of callable abilities | +| **Agents API** | "How do I run an agent that uses those?" | This project — the runtime that orchestrates turns, tools, memory, and identity | + +A model call on its own is one question and one answer. An *agent* keeps going: +it reads the question, decides to call a tool, reads the tool's result, maybe +calls another, and stops when it's done — remembering the conversation and +respecting who's asking. Agents API is the machinery that runs that cycle. + +## The vocabulary + +These are the terms the rest of the documentation uses. Each is one idea. + +**Agent** — a registered identity with a slug, configuration, and capabilities. +You register one with `wp_register_agent()` and look it up by slug. + +**Conversation loop** — the engine that runs an agent turn by turn until it's +done. It owns sequencing, stop conditions, tool mediation, compaction, and +event emission. The central primitive: `WP_Agent_Conversation_Loop`. + +**Turn** — one pass through the loop: send the current messages to the model, +get back text and/or tool calls, act on them. + +**Turn runner** — *your* adapter that actually calls the model. The loop hands +it the messages; it returns the model's response. Prompt assembly and model +choice live here, so the substrate stays provider-neutral. + +**Tool** — an action the agent can take, declared through the Abilities API. + +**Tool executor** — *your* adapter that runs a concrete tool when the loop asks. +You implement `WP_Agent_Tool_Executor`; the substrate prepares and validates the +call first. + +**Mediation** — the loop's tool cycle: take a tool call from the model, +validate it, run it through your executor, append the result to the transcript, +and decide whether to continue. You don't write this; the loop does. + +**Transcript / Session** — the stored record of a conversation. A *session* is +the row; the *transcript* is its messages. Stored through the +`WP_Agent_Conversation_Store` contract — bring your own backend, or enable the +built-in WordPress-native one. + +**Message envelope** — the normalized shape every message takes inside the +runtime (`WP_Agent_Message`), so text, tool calls, tool results, and approvals +all travel through the same structure. + +**Principal** — *who* a request is acting as: the user, the agent, the auth +source, the workspace, and the capability ceiling. One value object, +`WP_Agent_Execution_Principal`, carries it through the run. + +**Workspace** — the generic "where does this belong" scope (a site, a network, +a code workspace, an ephemeral environment). Memory, sessions, and audit all +hang off a workspace rather than assuming a single site ID. + +**Memory** — facts an agent keeps across sessions, with provenance and an +authority tier, behind the `WP_Agent_Memory_Store` contract. + +**Compaction** — trimming a long transcript before it overflows the context +window, preserving tool-call/result pairs, via a summarizer you supply. + +**Iteration budget** — a bound on a run (max turns, max tool calls, per-tool +calls) so an agent can't loop forever. + +**Approval / pending action** — when an action needs a human yes/no, the agent +proposes it instead of running it; the proposal waits as a *pending action* +until accepted or rejected. + +**Channel** — an adapter that maps an external transport (Slack, Telegram, +email, …) onto the agent chat surface. + +**Workflow / Routine** — multi-step orchestration (*workflow*) and scheduled or +recurring runs (*routine*), with an optional Action Scheduler bridge. + +## How a turn flows + +Putting the vocabulary together, one round looks like this: + +1. A message arrives (from a REST call, a channel, a scheduled routine, …). +2. The **loop** normalizes it into the **transcript** and starts a **turn**. +3. The loop calls your **turn runner**, which calls the model and returns its + response — possibly with **tool calls**. +4. For each tool call, the loop **mediates**: validates it, runs your **tool + executor**, and appends the result to the transcript. +5. The loop checks its stop conditions — natural completion, **iteration + budget**, completion policy — and either runs another turn or finishes. +6. Along the way it can **compact** a long transcript, emit lifecycle **events** + for observability, and **persist** the transcript through your store. +7. The whole run acts as a **principal** within a **workspace**, so identity and + scope are consistent end to end. + +You supply steps 3 and 4's concrete logic (model call, tool execution). The loop +owns everything else. + +## What's yours vs. what the substrate owns + +Agents API is the substrate, not the application. It owns the reusable +contracts; you keep your product. You bring: the model call (turn runner), +concrete tools (executor), prompt and model policy, storage materialization, and +product UX. The substrate brings: the loop, mediation, transcript/session and +memory contracts, identity and auth, compaction, budgets, approvals, channels, +and workflow scaffolding. + +## Where to go next + +- **[Capability Map](capability-map.md)** — now that you know the terms, the + full table of each capability and the primitive that provides it. +- **[Runtime and Tools](runtime-and-tools.md)** — the loop, tool mediation, + policies, budgets, and events in depth. +- **[Auth, Consent, Context, and Memory](auth-consent-context-memory.md)** — + principals, tokens, capability ceilings, memory, and context. +- **[Channels, Workflows, and Operations](channels-workflows-operations.md)** — + channels, workflows, routines, transcripts, and approvals. +- **[Architecture](architecture.md)** — module inventory and the substrate + boundary. diff --git a/readme.txt b/readme.txt index 5dbe84c..1ee19fe 100644 --- a/readme.txt +++ b/readme.txt @@ -14,6 +14,8 @@ Shared WordPress runtime substrate for registering AI agents, mediating tools, r Agents API is a shared foundation for building AI agents in WordPress. +New to the project? Start with the Introduction, which breaks down the core concepts and vocabulary in plain language: https://github.com/Automattic/agents-api/blob/main/docs/introduction.md + It provides the reusable substrate that product plugins need when they add agent-backed features: agent registration, runtime value objects, tool mediation contracts, transcript and memory interfaces, approval primitives, messaging-channel adapters, and lightweight workflow scaffolding. Agents API is intentionally not a full agent product. It does not provide admin screens, provider-specific model execution, product workflows, concrete storage implementations, or an end-user chat application. Those pieces belong to consumer plugins.