remove obsolete agenton and run api docs

This commit is contained in:
盐粒 Yanli 2026-05-13 03:55:43 +08:00
parent ae4a3f75f4
commit b70763d751
2 changed files with 0 additions and 514 deletions

View File

@ -1,201 +0,0 @@
# Agenton API reference
This page summarizes the public Agenton API. Import paths are shown for symbols
commonly used by layer authors and compositor callers.
## Layers: `agenton.layers`
### `Layer[DepsT, PromptT, UserPromptT, ToolT, ConfigT, RuntimeStateT]`
Framework-neutral base class for invocation-scoped prompt/tool layers.
Class attributes:
- `type_id: str | None`: provider id for config-backed graph nodes.
- `config_type: type[LayerConfig]`: Pydantic schema for per-run layer config.
- `runtime_state_type: type[BaseModel]`: Pydantic schema for snapshot-safe
per-layer state.
- `deps_type: type[LayerDeps]`: inferred from the layer generic base or declared
explicitly.
Invocation attributes assigned by `CompositorRun`:
- `config: ConfigT`
- `deps: DepsT`
- `runtime_state: RuntimeStateT`
Construction and dependency APIs:
- `from_config(config: ConfigT) -> Self`: create a fresh layer from
schema-validated config. The default implementation supports only empty config.
- `dependency_names() -> frozenset[str]`: dependency fields declared by
`deps_type`.
- `bind_deps(deps: Mapping[str, Layer | None]) -> None`: bind direct layer
instance dependencies for one invocation.
Lifecycle hooks:
- `on_context_create() -> None`
- `on_context_resume() -> None`
- `on_context_suspend() -> None`
- `on_context_delete() -> None`
Prompt/tool authoring surfaces:
- `prefix_prompts -> Sequence[PromptT]`
- `suffix_prompts -> Sequence[PromptT]`
- `user_prompts -> Sequence[UserPromptT]`
- `tools -> Sequence[ToolT]`
Aggregation adapters implemented by typed layer families:
- `wrap_prompt(prompt: PromptT) -> object`
- `wrap_user_prompt(prompt: UserPromptT) -> object`
- `wrap_tool(tool: ToolT) -> object`
### Schema defaults and lifecycle enums
- `LayerConfig`: base DTO for serializable layer config schemas.
- `LayerConfigValue`: JSON value or concrete `LayerConfig` DTO.
- `EmptyLayerConfig`: default config schema for layers without config.
- `EmptyRuntimeState`: default serializable runtime-state schema.
- `LayerDeps`: typed dependency container base.
- `NoLayerDeps`: dependency container for layers with no dependencies.
- `LifecycleState`: `NEW`, `ACTIVE`, `SUSPENDED`, `CLOSED`.
- `ExitIntent`: `DELETE`, `SUSPEND`.
`ACTIVE` is internal to an entered run and is rejected in external snapshots.
### Typed layer families: `agenton.layers.types`
- `PlainLayer[DepsT, ConfigT, RuntimeStateT]`
- `PydanticAILayer[DepsT, AgentDepsT, ConfigT, RuntimeStateT]`
Tagged aggregate item types:
- `PlainPromptType`, `PlainUserPromptType`, `PlainToolType`
- `PydanticAIPromptType`, `PydanticAIUserPromptType`, `PydanticAIToolType`
- `AllPromptTypes`, `AllUserPromptTypes`, `AllToolTypes`
## Compositor: `agenton.compositor`
### Config models
- `LayerNodeConfig`: `name`, `type`, `deps`, `metadata`.
- `CompositorConfig`: `schema_version`, `layers`.
- `LayerConfigInput`: accepted per-run config input for one node.
Config nodes are pure serializable graph topology. Per-run layer config is passed
separately to `Compositor.enter(configs=...)` keyed by node name.
### Providers and graph nodes
`LayerProvider[LayerT]` is a reusable validated factory for one concrete layer
class.
- `LayerProvider.from_layer_type(layer_type) -> LayerProvider`: construct through
`layer_type.from_config`.
- `LayerProvider.from_factory(layer_type=..., create=...) -> LayerProvider`:
construct through a custom typed-config factory.
- `type_id -> str | None`: provider id declared by the layer type.
- `validate_config(config=None) -> LayerConfig`: validate config without invoking
the factory.
- `create_layer(config=None) -> LayerT`: validate config and create a fresh layer.
- `create_layer_from_config(config) -> LayerT`: create from already validated
config and enforce fresh-instance semantics.
`LayerNode(name, implementation, deps=None, metadata=None)` creates a stateless
graph node from a `Layer` subclass or `LayerProvider`. `deps` maps dependency
field names on the node's layer class to other node names.
### `Compositor`
`Compositor[PromptT, ToolT, LayerPromptT, LayerToolT, UserPromptT, LayerUserPromptT]`
owns the ordered graph plan and provider construction plans.
Construction:
- `Compositor(nodes, prompt_transformer=None, user_prompt_transformer=None, tool_transformer=None)`.
- `Compositor.from_config(conf, providers=..., node_providers=None, prompt_transformer=None, user_prompt_transformer=None, tool_transformer=None)`.
Public properties and entry API:
- `nodes -> tuple[LayerNode, ...]`: stateless graph plan in order.
- `enter(configs=None, session_snapshot=None) -> AsyncIterator[CompositorRun]`:
validate per-run configs and optional snapshot, create fresh layers, bind direct
dependencies, enter hooks in graph order, and exit hooks in reverse order.
`providers` resolve graph node `type` ids. `node_providers` are keyed by node name
and override type-id providers for node-specific construction.
### `CompositorRun`
`CompositorRun` is the single-invocation runtime object yielded by
`Compositor.enter(...)`.
Fields:
- `slots: OrderedDict[str, LayerRunSlot]`
- `session_snapshot: CompositorSessionSnapshot | None`
Layer access and exit intent:
- `get_layer(name) -> Layer`
- `get_layer(name, layer_type) -> LayerT`
- `suspend_on_exit() -> None`
- `delete_on_exit() -> None`
- `suspend_layer_on_exit(name) -> None`
- `delete_layer_on_exit(name) -> None`
Aggregation properties:
- `prompts -> list[PromptT]`: prefix prompts in layer order, suffix prompts in
reverse layer order, then optional `prompt_transformer`.
- `user_prompts -> list[UserPromptT]`: user prompts in layer order, then optional
`user_prompt_transformer`.
- `tools -> list[ToolT]`: tools in layer order, then optional `tool_transformer`.
Snapshot API:
- `snapshot_session() -> CompositorSessionSnapshot`: snapshot non-active layer
lifecycle state and runtime state.
`session_snapshot` is populated after context exit. Core run slots default to
delete-on-exit; request suspend before exit when the next snapshot must be
resumable.
### Run slots and snapshots
- `LayerRunSlot`: `layer`, `lifecycle_state`, `exit_intent`.
- `LayerSessionSnapshot`: `name`, `lifecycle_state`, `runtime_state`.
- `CompositorSessionSnapshot`: `schema_version`, `layers`.
Snapshots include ordered layer lifecycle state and JSON-safe runtime state only.
They exclude live resources, dependencies, prompts, tools, per-run config, and
exit intent.
## Collection layers and transformers
### Plain layers: `agenton_collections.layers.plain`
- `PromptLayer`: config-backed layer with `PromptLayerConfig(prefix, user,
suffix)` and `type_id = "plain.prompt"`.
- `ObjectLayer`: factory-backed layer for Python objects.
- `ToolsLayer`: factory-backed layer for plain callables.
- `DynamicToolsLayer`: factory-backed layer for object-bound callables.
- `with_object`: decorator for dynamic tools whose first argument is supplied by
an `ObjectLayer` dependency.
### Pydantic AI bridge
`agenton_collections.layers.pydantic_ai.PydanticAIBridgeLayer` exposes
pydantic-ai system prompts, user prompts, and tools while depending on an
`ObjectLayer` for `RunContext.deps`.
`agenton_collections.transformers.pydantic_ai.PYDANTIC_AI_TRANSFORMERS` provides:
- `prompt_transformer`: maps tagged Agenton prompt items to pydantic-ai system
prompt functions.
- `user_prompt_transformer`: maps tagged Agenton user prompt items to pydantic-ai
`UserContent` values.
- `tool_transformer`: maps tagged Agenton tool items to pydantic-ai tools.

View File

@ -1,313 +0,0 @@
# Dify Agent Run API
The Dify Agent API exposes asynchronous agent runs backed by Agenton state-only
layer composition, Pydantic AI runtime execution, Redis run records, and per-run
Redis Streams event logs. The FastAPI application lives at
`dify-agent/src/dify_agent/server/app.py`.
Public Python DTOs and event models are exported from
`dify_agent.protocol.schemas`. `dify_agent.server.schemas` is intentionally
server-only and should not be used by API consumers.
## Input model
Create-run requests accept a public `RunComposition` and an optional
`CompositorSessionSnapshot`. There is **no top-level `user_prompt` or model
profile field**. User input and model/provider selection are supplied by Agenton
layers. `on_exit` optionally controls whether layers suspend or delete when the
run leaves the active session; the default is suspend for all layers. In the MVP
server, the safe provider set includes `plain.prompt`, `dify.plugin`, and
`dify.plugin.llm`. The runtime reads the LLM model layer named by
`DIFY_AGENT_MODEL_LAYER_ID`, whose public value is `"llm"`.
Blank user input is rejected. A request with no user prompt, an empty string, or
only whitespace strings such as `"user": ["", " "]` returns `422` before a run
record is created.
The server does not implement a Pydantic AI history layer. Resumable Agenton
state is represented only by `session_snapshot`.
## Create a run
```http
POST /runs
Content-Type: application/json
```
Request:
```json
{
"composition": {
"schema_version": 1,
"layers": [
{
"name": "prompt",
"type": "plain.prompt",
"config": {
"prefix": "You are a concise assistant.",
"user": "Say hello from the Dify Agent API."
}
},
{
"name": "plugin",
"type": "dify.plugin",
"config": {
"tenant_id": "replace-with-tenant-id",
"plugin_id": "langgenius/openai"
}
},
{
"name": "llm",
"type": "dify.plugin.llm",
"deps": {
"plugin": "plugin"
},
"config": {
"model_provider": "openai",
"model": "gpt-4o-mini",
"credentials": {
"api_key": "replace-with-provider-key"
},
"model_settings": {
"temperature": 0.2
}
}
}
]
},
"session_snapshot": null,
"on_exit": {
"default": "suspend",
"layers": {
"prompt": "delete"
}
}
}
```
Response (`202 Accepted`):
```json
{
"run_id": "4a7f9a98-5c55-48d0-8f3e-87ef2cf81234",
"status": "running"
}
```
The server persists the run record and schedules execution immediately in the
same FastAPI process. Redis is not used as a job queue. Run records and per-run
event streams expire after `DIFY_AGENT_RUN_RETENTION_SECONDS`, which defaults to
`259200` seconds (3 days).
`dify.plugin` receives tenant/plugin identity only; daemon URL, API key, timeout,
and connection limits are server settings. `dify.plugin.llm.credentials` accepts
scalar values only (`string`, `number`, `boolean`, or `null`). Unknown
`on_exit.layers` keys return `422` before a run record is created.
Validation error example (`422`):
```json
{
"detail": "run.user_prompts must not be empty"
}
```
## Get run status
```http
GET /runs/{run_id}
```
Response:
```json
{
"run_id": "4a7f9a98-5c55-48d0-8f3e-87ef2cf81234",
"status": "succeeded",
"created_at": "2026-05-08T12:00:00Z",
"updated_at": "2026-05-08T12:00:02Z",
"error": null
}
```
Status values are:
- `running`
- `succeeded`
- `failed`
Unknown or expired run ids return `404` with `"run not found"`.
## Poll events
```http
GET /runs/{run_id}/events?after=0-0&limit=100
```
Cursor values are Redis Stream IDs. Use `after=0-0` to read from the beginning.
The response includes `next_cursor`; pass it as the next `after` value to continue
polling.
Response:
```json
{
"run_id": "4a7f9a98-5c55-48d0-8f3e-87ef2cf81234",
"events": [
{
"id": "1715170000000-0",
"run_id": "4a7f9a98-5c55-48d0-8f3e-87ef2cf81234",
"type": "run_started",
"data": {},
"created_at": "2026-05-08T12:00:00Z"
}
],
"next_cursor": "1715170000000-0"
}
```
## Stream events with SSE
```http
GET /runs/{run_id}/events/sse
```
SSE frames use the run event id as `id`, the event type as `event`, and the full
`RunEvent` JSON object as `data`:
```text
id: 1715170000000-0
event: run_started
data: {"id":"1715170000000-0","run_id":"...","type":"run_started","data":{},"created_at":"..."}
```
Replay can start from a cursor with either:
- `GET /runs/{run_id}/events/sse?after=1715170000000-0`
- `Last-Event-ID: 1715170000000-0`
If both are provided, the `after` query parameter takes precedence.
## Python client
Use `dify_agent.client.Client` for both async and sync code. Async methods use
normal names; sync methods add `_sync`.
```python {test="skip" lint="skip"}
from agenton.layers import ExitIntent
from agenton_collections.layers.plain import PromptLayerConfig
from dify_agent.client import Client
from dify_agent.layers.dify_plugin import DifyPluginLLMLayerConfig, DifyPluginLayerConfig
from dify_agent.protocol import (
DIFY_AGENT_MODEL_LAYER_ID,
CreateRunRequest,
LayerExitSignals,
RunComposition,
RunLayerSpec,
)
async def main() -> None:
request = CreateRunRequest(
composition=RunComposition(
layers=[
RunLayerSpec(name="prompt", type="plain.prompt", config=PromptLayerConfig(user="hello")),
RunLayerSpec(
name="plugin",
type="dify.plugin",
config=DifyPluginLayerConfig(tenant_id="tenant-id", plugin_id="langgenius/openai"),
),
RunLayerSpec(
name=DIFY_AGENT_MODEL_LAYER_ID,
type="dify.plugin.llm",
deps={"plugin": "plugin"},
config=DifyPluginLLMLayerConfig(
model_provider="openai",
model="gpt-4o-mini",
credentials={"api_key": "provider-key"},
),
),
]
),
on_exit=LayerExitSignals(layers={"prompt": ExitIntent.DELETE}),
)
async with Client(base_url="http://localhost:8000") as client:
run = await client.create_run(request)
async for event in client.stream_events(run.run_id):
print(event)
```
```python {test="skip" lint="skip"}
from agenton_collections.layers.plain import PromptLayerConfig
from dify_agent.client import Client
from dify_agent.layers.dify_plugin import DifyPluginLLMLayerConfig, DifyPluginLayerConfig
from dify_agent.protocol import DIFY_AGENT_MODEL_LAYER_ID, CreateRunRequest, RunComposition, RunLayerSpec
request = CreateRunRequest(
composition=RunComposition(
layers=[
RunLayerSpec(name="prompt", type="plain.prompt", config=PromptLayerConfig(user="hello")),
RunLayerSpec(
name="plugin",
type="dify.plugin",
config=DifyPluginLayerConfig(tenant_id="tenant-id", plugin_id="langgenius/openai"),
),
RunLayerSpec(
name=DIFY_AGENT_MODEL_LAYER_ID,
type="dify.plugin.llm",
deps={"plugin": "plugin"},
config=DifyPluginLLMLayerConfig(
model_provider="openai",
model="gpt-4o-mini",
credentials={"api_key": "provider-key"},
),
),
]
)
)
with Client(base_url="http://localhost:8000") as client:
run = client.create_run_sync(request)
terminal = client.wait_run_sync(run.run_id)
```
`stream_events` and `stream_events_sync` parse SSE without an extra dependency.
They reconnect by default from the latest yielded event id and stop after
`run_succeeded` or `run_failed`. They do not reconnect for HTTP 4xx responses,
DTO validation failures, or malformed SSE frames. `create_run` and
`create_run_sync` require a `CreateRunRequest` DTO and never retry `POST /runs`;
if a timeout occurs, the caller must decide whether to inspect existing runs or
submit a new run.
## Event types and order
A normal successful run emits:
1. `run_started`
2. zero or more `pydantic_ai_event`
3. `run_succeeded`
A failed run emits:
1. `run_started`
2. zero or more `pydantic_ai_event`
3. `run_failed`
Each event keeps the same envelope shape and has typed `data`: `run_started` uses
`{}`, `pydantic_ai_event` uses Pydantic AI's `AgentStreamEvent` union,
`run_succeeded` uses `{ "output": JsonValue, "session_snapshot":
CompositorSessionSnapshot }`, and `run_failed` uses `{ "error": string,
"reason": string | null }`. The session snapshot from `run_succeeded.data` can
be sent as `session_snapshot` in a later create-run request with the same
composition layer names and order.
## Consumer examples
See:
- `dify-agent/examples/dify_agent/dify_agent_examples/run_server_consumer.py` for cursor polling
- `dify-agent/examples/dify_agent/dify_agent_examples/run_server_sse_consumer.py` for SSE consumption
- `dify-agent/examples/dify_agent/dify_agent_examples/run_server_sync_client.py` for synchronous client usage