Parent: #284 — Agent-in-Sandbox via a remote aca provider.
Design doc: docs/aca-provider.design.md — Open Question #1 (Blocking / Phase 0), DD3.
Why (blocking)
The aca provider relocates an agent's whole runtime into an ACA custom-container
dynamic session. A single agent turn can run for minutes, so the runner transport
must survive ACA's request/idle-timeout limits. Two ACA limits must not be conflated:
- Per-request forwarded-duration cap — how long one request may stay open.
Undocumented for sessions; general ACA ingress idle-timeout defaults to 4 min,
premium max 30 min. This is the real cut-off risk.
- Inter-request
Timed cooldown (300–3600 s) — how long an idle session
survives between requests, reset each time the session API is called.
Two candidate transport branches with identical event/result semantics:
- Branch S (preferred) — single streaming request. One
POST /execute streams
NDJSON event frames until a terminal result frame. True incremental events +
mid-call partials + real interrupt. Viable only if one request can stay open for
the whole turn.
- Branch P (fallback) — submit + poll.
POST /execute returns a job id; the
host polls for event batches. Each poll is a fresh request under the cap and
resets the cooldown. Survives a short cap at the cost of coarser streaming/interrupt.
This spike gates the build and fixes the conditional streaming_events /
interrupt capabilities. No provider code should land before it resolves.
Method
- Stand up a throwaway custom-container session pool (DD6 two-step deploy: push
image to ACR, then az containerapp sessionpool create --container-type CustomContainer …).
- Bake a trivial heartbeat runner into the image: emits one NDJSON frame/second,
then a terminal result frame.
- Drive it from a standalone probe script (no Conductor dependency).
What to measure
- True per-request forwarded-duration cap — hold a single chunked response
open and record when the sessions endpoint cuts it off. Repeat with premium
ingress and its request idle-timeout raised toward the 30-min max.
- Stream durability — does steady chunked streaming survive ≥10 min without
a drop?
- Resumability — can a dropped stream be resumed by replaying from a
Last-Event-ID cursor (AG-UI style)?
Decision rule
- One request reliably survives a full multi-minute turn → Branch S
(streaming_events=True, real interrupt).
- Request is capped short → Branch P (
streaming_events=False,
hard-abort-only interrupt via stopSession).
Deliverables / acceptance criteria
References
Parent: #284 — Agent-in-Sandbox via a remote
acaprovider.Design doc:
docs/aca-provider.design.md— Open Question #1 (Blocking / Phase 0), DD3.Why (blocking)
The
acaprovider relocates an agent's whole runtime into an ACA custom-containerdynamic session. A single agent turn can run for minutes, so the runner transport
must survive ACA's request/idle-timeout limits. Two ACA limits must not be conflated:
Undocumented for sessions; general ACA ingress idle-timeout defaults to 4 min,
premium max 30 min. This is the real cut-off risk.
Timedcooldown (300–3600 s) — how long an idle sessionsurvives between requests, reset each time the session API is called.
Two candidate transport branches with identical event/result semantics:
POST /executestreamsNDJSON event frames until a terminal
resultframe. True incremental events +mid-call partials + real interrupt. Viable only if one request can stay open for
the whole turn.
POST /executereturns a job id; thehost polls for event batches. Each poll is a fresh request under the cap and
resets the cooldown. Survives a short cap at the cost of coarser streaming/interrupt.
This spike gates the build and fixes the conditional
streaming_events/interruptcapabilities. No provider code should land before it resolves.Method
image to ACR, then
az containerapp sessionpool create --container-type CustomContainer …).then a terminal
resultframe.What to measure
open and record when the sessions endpoint cuts it off. Repeat with premium
ingress and its request idle-timeout raised toward the 30-min max.
a drop?
Last-Event-IDcursor (AG-UI style)?Decision rule
(
streaming_events=True, realinterrupt).streaming_events=False,hard-abort-only
interruptviastopSession).Deliverables / acceptance criteria
Dockerfile/ pool setup (or scriptedazcommands).Last-Event-IDresume feasibility.streaming_events/interruptcapability values, folded back intodocs/aca-provider.design.md(DD3 + capabilities table).References