-
Notifications
You must be signed in to change notification settings - Fork 142
Description
Feature Request: Async query mode with completion notification
Problem
Currently, ACP query is synchronous — the client (acpx) blocks until the agent (e.g., cursor-agent) returns the full response. For short tasks this works well, but for long-running tasks (5+ minutes), this creates issues:
- Session is blocked: The ACP session cannot process other queries while waiting
- Timeout risk: Long tasks may exceed the
ttl(default 300s), causing the session to drop - No intermediate status: The caller has no visibility into task progress
- Resource waste: The acpx process sits idle, holding an open stdio pipe, waiting for a response
This is especially painful when integrating with orchestrators like OpenClaw, where multiple tasks need to be dispatched and results collected asynchronously.
Proposed Solution: Async Query + Notification
Add an optional async mode to the query method, where the agent can acknowledge receipt immediately and deliver results later via a notification.
Flow
Client Agent
| |
|-- query (async: true) ----------->|
|<-- ack { taskId, status } --------| (immediate, non-blocking)
| |
| (client is free to do other |
| work or send more queries) |
| | (agent working...)
| |
|<-- notification/taskComplete -----| (when done)
| { taskId, result, status } |
| |
Proposed Protocol Changes
1. Extended query params:
2. Immediate acknowledgment response:
{
"result": {
"taskId": "task_abc123",
"status": "accepted",
"message": "Task accepted, will notify on completion"
}
}3. New notification method (agent → client):
{
"method": "notification/taskComplete",
"params": {
"taskId": "task_abc123",
"status": "completed", // or "failed", "cancelled"
"result": {
"message": "Here is the full output..."
}
}
}4. Optional: Progress notification:
{
"method": "notification/taskProgress",
"params": {
"taskId": "task_abc123",
"progress": 0.6,
"message": "Running tests..."
}
}Capability negotiation
Agents that support async mode should declare it during initialize:
{
"agentCapabilities": {
"asyncQuery": true // NEW
}
}If the agent doesn't support asyncQuery, acpx should fall back to the current synchronous behavior transparently.
Use Cases
- Long-running code generation: "Build a complete project with tests" — may take 10+ minutes
- Multi-agent orchestration: Dispatch tasks to multiple agents in parallel, collect results as they complete
- CI/CD-like workflows: Kick off a build/test task, get notified when done
- OpenClaw integration: The gateway dispatches a task via ACP and immediately frees the agent to handle other chat messages; when the result arrives, it pushes a notification to the user
Workarounds Today
- Multiple concurrent sessions: Works but each session is still individually blocked
- External hook scripts: Asking the agent to run a notification script at the end — unreliable, depends on agent compliance
- Polling from orchestrator layer: Defeats the purpose of ACP's structured protocol
Compatibility
- Fully backward-compatible:
asyncparam defaults tofalse, existing behavior unchanged - Agents that don't support it simply ignore the flag and respond synchronously
- JSON-RPC already supports notifications (one-way messages), so no protocol-level changes needed
Related
- This is complementary to
session/loadandsession/new— async tasks would still belong to a session - Claude Code already has a similar pattern via lifecycle Hooks (Stop Hook / SessionEnd Hook), proving the async dispatch model works well in practice
Environment
- acpx: 0.3.0
- Observed with: cursor-agent (Cursor IDE CLI) via OpenClaw gateway
- OS: Windows 10
{ "method": "query", "params": { "prompt": "Build a REST API with FastAPI...", "async": true // NEW: request async execution } }