Skip to content

Commit a789d73

Browse files
docs(agentserver-skills): correct API guidance that would misguide coding agents
Reviewed all four standalone skills against the actual package surface and fixed claims that produce broken code: durable-task-skill: - Remove the broken 'from ...durable import ... Suspended' (Suspended is an internal _Suspended sentinel, not exported -> ImportError). - Fix local-provider env vars: the LocalFileTaskProvider roots at ${AGENTSERVER_DURABLE_ROOT:-~/.durable}/tasks/ and the force-local override is AGENTSERVER_TASKS_BACKEND=local (the doc's ~/.durable-tasks/ + AGENTSERVER_DURABLE_TASKS_PATH were wrong/legacy). responses-skill: - context.durable_metadata / DurableMetadataNamespace does not exist; the real handler metadata facade is context.conversation_chain_metadata (ConversationChainMetadataNamespace, has .flush()). Fixed surface table + decision shortcut. - Import CreateResponse and ResponseEventStream from the public top-level azure.ai.agentserver.responses (not the private models._generated / streaming._event_stream modules). streaming-skill: - use_file_backed_replay takes storage_dir=, not root= (2 spots). invocations-skill verified correct (invoke_handler/get_invocation_handler/ cancel_invocation_handler/ws_handler/request.state.session_id all real) — no change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 2672e44 commit a789d73

3 files changed

Lines changed: 12 additions & 11 deletions

File tree

sdk/agentserver/skills/durable-task-skill.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ Use `@task` when **any** of these apply:
6262
## Minimal pattern
6363

6464
```python
65-
from azure.ai.agentserver.core.durable import task, TaskContext, Suspended
65+
from azure.ai.agentserver.core.durable import task, TaskContext
6666

6767
@task(name="my_agent", steerable=True)
6868
async def my_agent(ctx: TaskContext[dict]) -> dict:
@@ -152,9 +152,10 @@ In hosted environments (`FOUNDRY_HOSTING_ENVIRONMENT` set by the platform)
152152
task-storage API automatically — no opt-in env var required.
153153

154154
In local development (no `FOUNDRY_HOSTING_ENVIRONMENT`) `@task` uses
155-
`LocalFileTaskProvider` rooted at `~/.durable-tasks/` (override with
156-
`AGENTSERVER_DURABLE_TASKS_PATH` for tests). No service dependency for
157-
local iteration.
155+
`LocalFileTaskProvider` rooted at `${AGENTSERVER_DURABLE_ROOT:-~/.durable}/tasks/`
156+
(override the root with `AGENTSERVER_DURABLE_ROOT`). No service dependency for
157+
local iteration. To force the local backend even when hosted-detection would
158+
otherwise pick the hosted provider, set `AGENTSERVER_TASKS_BACKEND=local`.
158159

159160
## Packaging — private preview wheels
160161

@@ -183,7 +184,7 @@ Consume the checked-in wheels per:
183184
| LangGraph integration | [`samples/durable_langgraph/`](https://github.com/Azure/azure-sdk-for-python/tree/refs/heads/feature/agentserver-durable-tasks/sdk/agentserver/azure-ai-agentserver-invocations/samples/durable_langgraph) |
184185

185186
Read the developer guide first — it covers `EntryMode`, retry semantics,
186-
`Suspended`, steering queue backpressure, cancel-cause booleans
187+
multi-turn suspend/resume, steering queue backpressure, cancel-cause booleans
187188
(`timeout_exceeded`, `cancel_requested`, `pending_input_count`), shutdown
188189
via `ctx.exit_for_recovery()`, and the patterns referenced above. The
189190
samples ground the API in working code.

sdk/agentserver/skills/responses-skill.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ from azure.ai.agentserver.responses import (
7272
ResponsesAgentServerHost,
7373
ResponseContext,
7474
TextResponse,
75+
CreateResponse,
7576
)
76-
from azure.ai.agentserver.responses.models._generated import CreateResponse
7777

7878
app = ResponsesAgentServerHost()
7979

@@ -102,7 +102,7 @@ streaming partials, structured outputs), use `ResponseEventStream` and
102102
yield events directly:
103103

104104
```python
105-
from azure.ai.agentserver.responses.streaming._event_stream import ResponseEventStream
105+
from azure.ai.agentserver.responses import ResponseEventStream
106106

107107
@app.response_handler
108108
async def my_handler(request, context, cancellation_signal):
@@ -163,7 +163,7 @@ When opted in, the handler also sees:
163163
| `context.is_recovery: bool` | `True` on a crash-recovered re-entry |
164164
| `context.is_steered_turn: bool` | `True` on the drain re-entry that follows a steering input |
165165
| `context.pending_input_count: int` | Live count of queued steering inputs |
166-
| `context.durable_metadata: DurableMetadataNamespace` | `MutableMapping` for handler-managed checkpoint state (small — watermarks, dedup tokens, NOT full conversation history). `await context.durable_metadata.flush()` for at-most-once side-effect fencing before an upstream call with observable side effects |
166+
| `context.conversation_chain_metadata: ConversationChainMetadataNamespace` | `MutableMapping` for handler-managed checkpoint state (small — watermarks, dedup tokens, NOT full conversation history). `await context.conversation_chain_metadata.flush()` for at-most-once side-effect fencing before an upstream call with observable side effects |
167167
| `await context.exit_for_recovery()` | Recovery primitive — `return await context.exit_for_recovery()` to leave the response `in_progress` so the next-lifetime recovery scanner picks it up |
168168

169169
## Hosted vs local
@@ -231,4 +231,4 @@ in working code.
231231
| OpenAI Chat Completions API endpoint || Different protocol — use a different host. |
232232
| Free-form invocations-protocol agent || Use the `agentserver-durable-tasks` + `agentserver-streaming` skills directly. |
233233
| Server-to-server background job with no HTTP surface || Use the `@task` primitive directly. |
234-
| Persist conversation history in `context.durable_metadata` || Wrong — `durable_metadata` is for small watermarks. Use your own DB or framework store (LangGraph SqliteSaver, etc.) for content. |
234+
| Persist conversation history in `context.conversation_chain_metadata` || Wrong — `conversation_chain_metadata` is for small watermarks. Use your own DB or framework store (LangGraph SqliteSaver, etc.) for content. |

sdk/agentserver/skills/streaming-skill.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ subscriber both call it with the same id and get the **same**
9898
|---|---|---|---|
9999
| `use_in_memory_live()` *(default)* | Single subscriber attaches before the producer; lowest memory. | No — late subscribers miss earlier events. | No. |
100100
| `use_in_memory_replay(cursor_fn=..., ttl_seconds=...)` | Late subscribers / disconnect+reconnect within the same process; cursor-based catch-up. | Yes, up to TTL. | No. |
101-
| `use_file_backed_replay(root=..., cursor_fn=...)` | `@task` handler that can crash and recover; subscribers need monotonic event continuity across the crash boundary. | Yes, across process restarts for the same stream id + on-disk dir. | Yes. |
101+
| `use_file_backed_replay(storage_dir=..., cursor_fn=...)` | `@task` handler that can crash and recover; subscribers need monotonic event continuity across the crash boundary. | Yes, across process restarts for the same stream id + on-disk dir. | Yes. |
102102

103103
Call exactly **one** configurator at app startup. Don't switch
104104
backings mid-process.
@@ -178,7 +178,7 @@ every event in your producer.
178178

179179
The streaming registry is the natural pair for `@task`. The recipe:
180180

181-
1. At app startup, call `streams.use_file_backed_replay(root=...,
181+
1. At app startup, call `streams.use_file_backed_replay(storage_dir=...,
182182
cursor_fn=lambda ev: ev["sequence_number"])`.
183183
2. Producer (inside your `@task` handler) stamps every event with a
184184
monotonically increasing `sequence_number`. After a crash, the

0 commit comments

Comments
 (0)