Releases: Infinia-Technology/infinia-automation-studio-release
Release list
v0.1.5 — the Studio becomes an agentic studio
v0.1.5 — the Studio becomes an agentic studio
The largest release so far: a rebuilt UI, live browser embedding, take-control, and
co-planning. v0.1.4 made tasks run; this one makes them watchable, steerable and
reviewable before they start.
Plan before anything runs
Give it a goal and an orchestrator model (Qwen/Qwen3.6-27B-FP8) drafts a plan: ordered
steps, the landing URL, and the egress allow-list. You edit it — reorder, rewrite, delete
steps — and only on approval does a browser open. microsoft/Fara1.5-27B still executes;
it is a grounded computer-use model, not a planner, and asking it to plan is
off-distribution.
The approved plan is authoritative. Delete the "submit the form" step and the form is
not submitted. That sounds obvious and was not: the first implementation put the original
goal ahead of the plan, so the agent still submitted because the goal text said to. If
editing a plan does not change behaviour, reviewing it is theatre.
The planner also flags irreversible actions ("Submitting the form") as risks the agent
must stop and ask about.
The browser is now inside the app
The agent's real Chromium renders in the right-hand panel while its OS window stays out of
sight. Not a screenshot poller and not a second browser — a CDP screencast of the actual
page the agent is driving, ~12 fps at ~95 KB/s.
- Detach / attach — pop the real window back onto your desktop and hide it again,
with no page state lost. - Take control — pause the agent at its next safe point, click and type in the page
yourself, then hand back. Control is exclusive: input is refused while the agent still
has it, and held modifiers are released on hand-back so the agent's next click is not
a shift-click.
Credential pages are protected. A screencast is a compositor capture, so it bypasses
the vault masking that lives in the observation path. On any page with a password field
the raw stream is suspended and frames come from the already-masked path instead, badged
"masked · reduced rate" — never a silent slowdown. It fails closed, and it holds whether
the agent or a human is driving.
Live, not polled
Runs used to be opaque while they happened: the agent loop ran to completion internally,
so the UI showed a stale step count until it finished. Now every step streams.
Streaming is a sidecar capability, not a GUI one:
infinia-qa watch <task-id> # live progress in the terminal
ffplay ".../live.mjpeg?token=$TOK" # the browser, in any playerinfinia-qa watch follows a run live with no token plumbing, so opencode or Claude Code
driving the CLI get the same view the app does. There is also a WebSocket for events and
one for binary frames.
The stream is authenticated — a per-launch token, plus an Origin check. Loopback
alone is not enough once a socket can show your session and type into it.
Rebuilt UI
React + Vite + Tailwind, in the two-column layout: plan, sessions, agent stream and
composer on the left; the browser on the right; diagnostics, approval inbox and
replay collapsed at the bottom. The old renderer rebuilt its whole session list every
2.5 s, discarding scroll and hover, and stole your cursor in the approval box on every
poll. Both gone. A real CSP replaces the previous null.
Fixes worth naming
- Replay was off by one — it showed the previous step's screenshot. Action i
producesscreenshot_{i+1}_post.png; verified against the solver log. - Replay never rendered at all in a packaged app — the screenshot reader resolved
paths from the working directory, which is/for a Finder-launched app, and returned
a shape the UI could not read. - Dry-run used to work by prefixing the goal with
"[DRY-RUN] ", which the agent read
as part of its instructions. It now uses the real API flag. - The sidecar's own dependencies (
fastapi,uvicorn,websockets) are declared rather
than present by accident of install order.
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 \
bashKnown limits
- Multi-tab is not in. Every tab must be created on the same browser context or it
escapes the egress fence, and keeping background tabs alive is a containment change —
both deserve a decision, not a rushed implementation. - Attach leaves a small corner of Chromium visible at the screen edge. macOS clamps
off-screen window moves, and the alternative — minimising — breaks the agent's own
screenshot path. - Plans execute in one shot. The approved plan governs the run, but there is no
per-step progress or automatic replanning yet.
290 tests pass.
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 \
bashv0.1.3 — Chromium never closed + faster startup
v0.1.3 — Chromium never closed + faster startup
Two more issues surfaced from real usage after v0.1.2.
1. Chromium (and its helper processes) never closed
session.py's _pump() set a task to COMPLETED/FAILED but never called
close() on the browser environment — only an explicit DELETE /v1/tasks/{id}
(or quitting the whole app) ever tore the browser down. Every infinia-qa run
left a Chromium process tree running forever.
Fix: close() now runs automatically at every genuinely terminal state
(COMPLETED, an exception, a failed watchdog, or step-budget exhaustion).
AWAITING_APPROVAL is untouched — that state is deliberately resumable and
needs the same live browser to stay open. Verified: watched Chromium (5+
processes) spawn mid-task and confirmed zero remain the instant a task reaches
a terminal state, across completed and failed outcomes alike.
2. ~5.5s before the app responds after every launch — now ~0.5-2.5s
Not a bug in the sense of broken logic — the frozen sidecar was a PyInstaller
onefile binary, which re-extracts its entire ~85MB payload to a fresh temp
directory on every single launch before Python can even start importing
onnxruntime/fara/playwright. Measured consistently at ~5.5s across repeated
runs, not just the first one.
Switched the freeze spec to onedir: the extracted tree now ships directly
inside the .app bundle at build time, so there's nothing to unpack at launch.
Measured: sidecar-alone cold start dropped from ~5.5s to ~0.5s after the first
run; full app-launch-to-Task-API-live dropped to ~2.5s.
Bonus: onedir also simplified signing. The old AMFI rejection this
project's signing script special-cased around (PyInstaller onefile extracting
libpython3.12.dylib to a temp dir with a Team ID mismatch under hardened
runtime) doesn't exist anymore — the dylib is now a real on-disk file signed at
build time. build-signed-dmg.sh no longer needs the separate
no-hardened-runtime re-sign pass for the sidecar.
Verified end-to-end
- Real task lifecycle: Chromium spawns mid-task, fully exits (0 processes) the
moment the task reachescompletedorfailed. open "Infinia Automate Studio.app"→ Task API live in ~2.5s (was ~5.5s+ for
the sidecar alone before).- All 232 existing sidecar tests pass.
Install (one command, no repo access)
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 \
bashv0.1.2 — one-click install fixed end-to-end
v0.1.2 — one-click install actually works end-to-end
Two independent bugs blocked the one-click install; both are fixed.
1. Frozen sidecar couldn't find Chromium
playwright's own frozen-app code (_transport.py) does
env.setdefault("PLAYWRIGHT_BROWSERS_PATH", "0") whenever the sidecar process's
environment doesn't already have that var set — "0" means "look for browsers
next to the driver," which is empty in this PyInstaller onefile bundle. Neither
launch path (double-clicking the .app, or running the frozen binary from the
same shell that ran the curl | bash installer) actually had the var in-process:
GUI launches never inherit ~/.zshrc exports, and a piped installer's export
doesn't propagate to the parent shell it was invoked from.
Fix: the sidecar now pins PLAYWRIGHT_BROWSERS_PATH to the app-data cache path
itself, in-process, before Playwright ever spawns its driver — no reliance on
inherited shell env from here on.
2. The .app itself couldn't launch (Launchd job spawn failed)
Double-clicking (or open-ing) the installed app failed outright with
RBSRequestErrorDomain Code=5 / Launchd job spawn failed. Root cause: the
app's entitlements declared keychain-access-groups: com.infinia.automate-studio.vault,
which requires a provisioning profile for that App ID — one this personal Apple
Development certificate doesn't have. AMFI kills the process at exec whenever
that entitlement is present and unprovisioned, regardless of launch method
(GUI or direct exec).
The credential vault (sidecar/vault.py) shells out to /usr/bin/security for
generic-password items rather than linking Keychain Services directly — it never
actually used the shared access group. The entitlement was dead weight with a
fatal side effect. Removed.
Verified end-to-end on this build
open "Infinia Automate Studio.app"→ app launches, spawns the sidecar, Task
API live on 127.0.0.1:8765.- Sidecar accepts a task with
PLAYWRIGHT_BROWSERS_PATHdeliberately unset in
the shell → Chromium launches, task reachesrunning.
Install (one command, no repo access)
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 \
bashv0.1.1 — Infrastructure fix: standalone sidecar config + Chromium
v0.1.1 — Infrastructure fix
Fixes running the frozen sidecar standalone (public install path, no repo):
What changed
- Config resolution: the frozen sidecar now finds
tf_staging.jsonfrom
~/.config/infinia-automate-studio/tf_staging.json(app-data), not a
repo-relative path. The installer writes there. - Chromium: the sidecar now honors
PLAYWRIGHT_BROWSERS_PATH. The
installer downloads Chromium to~/.cache/infinia-automate-studio/ms-playwright
and persists the env var.
Install (one command, no repo access)
curl -fsSL https://infinia-automation-studio.adid.dev/install.sh \
| INFINIA_TF_BASE_URL=https://api.tf-staging.iiamsaif.ai/v1 \
INFINIA_TF_API_KEY=tf-your-key-here \
bashManual sidecar start (no UI)
export PLAYWRIGHT_BROWSERS_PATH="$HOME/.cache/infinia-automate-studio/ms-playwright"
"/Applications/Infinia Automate Studio.app/Contents/Resources/python/sidecar" --port 8765v0.1.0 — Infinia Automate Studio
Infinia Automate Studio v0.1.0
Sovereign desktop web-automation app powered by Fara1.5-27B.
Download
- macOS (Apple Silicon):
Infinia-Automate-Studio-0.1.0-aarch64.dmg(91MB) - CLI + assets bundle:
infinia-automate-studio-0.1.0-bundle.tar.gz(11KB)
Install (one command)
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 \
bashWhat's included
- Tauri desktop shell (signed with Apple Development certificate)
- Frozen Python sidecar (PyInstaller onefile, 85MB)
- infinia-qa CLI (single Python file, no deps)
- Studio UI (task composer, live viewer, approval inbox)
- Config templates
Requirements
- macOS 13.0+ (Apple Silicon)
- Infinia Token Factory API key
- 200MB disk space