Skip to content

Let extensions hold agents' model calls; define the scope of pi-agents - #112

Merged
mavam merged 4 commits into
mainfrom
before-agent-request
Oct 21, 2026
Merged

mavam merged 4 commits into
mainfrom
before-agent-request

Conversation

@mavam

@mavam mavam commented Oct 21, 2026

Copy link
Copy Markdown
Owner

🔍 Problem

  • Co-loaded extensions need a way to hold agents' model calls, for example during peak pricing. Agents should stay alive while held, and stopping one must never be blocked by a hold.
  • A first proposal put the hold policy inside pi-agents: a hold/release protocol, recheckAt timers, a manual hold, a way to combine holds, and a Models wrapper. That is policy machinery, and it doesn't belong in a durability extension.
  • Nothing written down kept agents from adding features like that whenever a user asked.

🛠️ Solution

  • Scope. docs/design.md defines the core as durable agent execution and durable messaging. Graphs, delegation, and waits are built on top of those; everything else is a customization point. AGENTS.md adds a short checklist that agents must follow before building new behavior. Budgets move off the deferred list because they are extension policy.
  • beforeAgentRequest(ctx): a new optional hook. It runs before each generation request and compaction summary, and the call waits until the callback returns. pi-agents keeps no hold state, timers, reasons, or status, so pricing schedules and manual holds stay in the consumer extension.
  • Where it runs: in pi-durable's own beforeRequest/beforeCompact hooks, the same place the working-agent cap waits. That means:
    • credentials resolve after a long hold;
    • retries and resumed calls pass the hook again, and deferred polling doesn't;
    • stopping, interrupting, or shutting down ends the wait, even when the callback ignores its signal.

💬 Review

  • Errors fail open. A callback that throws gets reported under its namespace, and the call proceeds. pi-durable already handles hook errors this way. Failing the call instead would need the Models wrapper back, so extensions that want to fail closed catch their own errors and keep waiting.
  • Interaction with the working-agent cap. Hooks run before the cap. A run held at its first call takes no slot. An agent held later in its run keeps its slot, so other agents may wait behind it. This is documented rather than solved, to keep slot logic out of the hook.
  • model is the agent's configured model, read before routing. onAgentRequest still sees the model actually dispatched.
  • Out of scope: the parent session, and codemode's classify/generateImages calls. Covering those later would take one beforeTool registration.

mavam added 4 commits October 21, 2026 09:45
The core is durable agent execution and durable messaging. Policy such as pricing, budgets, quotas, or scheduling belongs in co-loaded extensions behind small hooks, so user requests no longer grow the core by default. AGENTS.md turns this into a checklist for agents, and budgets leave the deferred list because they are extension policy.
A new optional beforeAgentRequest hook runs before each generation request and compaction summary. Each request waits until the hook's callback returns. The hook runs in pi-durable's own request hooks, before credentials resolve and before the working-agent cap takes a slot. Stopping or interrupting an agent, or shutting down, ends the wait. pi-agents keeps no hold state, timers, or status, so pricing schedules and manual holds stay in the consumer extension.
AGENTS.md keeps the four-step check in fewer words and drops the rule about precedent. The architecture diagram in the README and docs now lists holding calls among the hooks.
@mavam
mavam merged commit f1d2944 into main Oct 21, 2026
3 checks passed
@mavam
mavam deleted the before-agent-request branch October 21, 2026 08:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant