Skip to content

ACP host hooks — permission, updates, cancel, stream

C# · package Toolnexus · SPEC §8

Opt-in hooks on an ACP model source: choose the permission option, watch every session/update, cancel a turn, and stream through an in-process client.

C# ships an ACP client, AcpClient, without the Go host hooks. What it does today:

  • Permissions are answered automatically with the first allow* option (AutoAnswerPermission, default true). There is no callback to choose an option or ask a human. To limit what the agent may do, start it in a restrictive mode with SetModeAsync.
  • Updates: only the agent’s message text forms the reply; session/update notifications are not surfaced to the host.
  • Cancellation: the CancellationToken on PromptAsync stops the wait; no session/cancel is sent. PromptTimeout (default 10 s) bounds a turn.
  • Streaming: none. Plug acp.Generate into an in-process client and use RunAsync.
using var acp = await AcpClient.StartAsync("my-agent", new[] { "acp" });
acp.PromptTimeout = TimeSpan.FromMinutes(5);
var text = await acp.PromptAsync("Summarize the repo", cancellationToken);

Go has all four hooks today (ACPOptions.OnPermission, ACPOptions.OnUpdate, ACPClient.GenerateCtx, ACPClient.GenerateStream); see the Go page. The C# port is tracked in openspec/changes/add-go-host-asks, task 2.6d.

  • LlmClient.Create — The unified client: system prompt, skills injection, parallel and chained tool calls, retries, memory.
  • LlmClient.RunAsync — Send a prompt, let the loop call tools until the model stops, get a RunResult.
  • LlmClient.StreamAsync — The streaming loop: text deltas, tool-call events, and suspension events as they happen.
  • LlmClient.Hooks — Intercept before/after model calls and tool calls: audit, redact, veto, or rewrite.