v0.1.4 — tasks actually run in the packaged app
v0.1.4 — tasks actually run in the packaged app
The app could not complete a task when launched normally. Three independent bugs; the
first two formed a single chain.
1. One typo took out every task in the packaged app
sidecar/metering.py read res.choices[0].message.content. But the object it receives is
a CreateResult — fara.clients.wrapper.create() already unwraps the response into
CreateResult(content=response.choices[0].message, usage=…, finish_reason=…). There is no
.choices.
The cascade that made a logging typo fatal:
- A real ~2 MB multimodal call succeeds (token usage was recorded correctly).
- The next line raises
AttributeError. - It propagates into
Fara15Agent._make_model_call, whose@retryexcludes only
BadRequestError— so 5 attempts. - Each attempt carries the OpenAI SDK's own 2 retries.
- Net: up to 15 × ~2 MB POSTs per step, all deterministically doomed.
- The endpoint is behind Cloudflare, which answers a burst with HTTP 403 to
everything until it stops. The SDK surfaced the exhausted retries as
APIConnectionError('Connection error.')— the error operators actually saw.
Fixed: correct field access (plus tool_calls, which the audit needs for replay), and
the whole telemetry block is now wrapped — metering must never fail the call it measures.
Why no test caught it: the test stubbed a fake response that did expose .choices —
an OpenAI-raw shape the real wrapper never returns. The stub was more capable than
production. It now builds a genuine CreateResult, so the shape cannot drift again.
Why it only broke the packaged app: --no-meter was passed on the dev arm only, so
the metering path was exercised exclusively in production. Dev and release now spawn the
sidecar identically.
2. Every task opened Bing first
start_page defaulted to https://www.bing.com/ and the UI pre-filled the egress
allow-list with bing.com. So every task navigated to a host its goal never mentioned,
burned a step getting there, and silently widened egress to match. Both defaults are gone —
about:blank costs nothing, since governance already treats an empty hostname as
non-egress.
3. A typo in our own install command, accepted silently
The landing page's copy-paste command read api.tf-staging.iiamsaif.ai (double i), which
does not resolve. The installer wrote it to config without checking, so the only symptom
was an opaque APIConnectionError deep inside a task run, minutes later.
Fixed on the site and in the docs — and the installer now preflights the endpoint
before writing it: it resolves the host and calls /models with the key, failing with a
message that names the cause (bad host vs rejected key) instead of deferring the failure to
runtime.
Also
- New
sidecar/throttle.py: paces model calls and treats 403/429/503 as
retry-with-backoff-and-jitter rather than permanent errors. The amplifier that caused
this outage is vendor code and still there, so this is the backstop — the next bug of
that shape degrades latency instead of removing the endpoint. Genuine 4xx still fail fast.
Verified
Packaged app, launched by double-click, sidecar spawned with metering (the exact
configuration that was broken): the reported form-filling task ran to completed through
the full approval cycle — approval_requested → approval_notified → approval_granted —
with 8 model calls, 45,590 tokens, 0 errors, zero Bing navigations and zero
AttributeErrors. 242 tests pass (232 + 10 new throttle tests).
Install
curl -fsSL https://infinia-automation-studio.adid.dev/install.sh \
| INFINIA_TF_BASE_URL=https://api.tf-staging.iamsaif.ai/v1 \
INFINIA_TF_API_KEY=tf-your-key-here \
bash