We built an agent runtime where jobs are explicit state machines compiled from configuration

Reddit r/ArtificialInteligence Tools

Summary

Friday Studio is an open-source agent runtime that compiles natural language workflows into explicit, version-controlled YAML state machines. It allows developers to build AI agents via chat but ship them as stable configuration files for reliable production use.

Hey all, I'm one of the builders of Friday Studio. Sharing because we'd love feedback from people who've actually shipped with agents. Our team kept running into the same two problems with agentic AI: either it was a huge PITA to set up, or too brittle once it was running. We wanted a runtime where your workflow runs the same way every time, leaves a trace every time, and doesn't surprise you. We think reliability is a configuration problem. Most tools ask the LLM to figure out what to do on every run. That's where you get drift and "it worked yesterday" failures. Friday compiles what you describe into a workspace.yml and executes that every time. You can read the YAML, commit it to git, and diff it across versions. Jobs are finite state machines: states, transitions, and agent dispatch are explicit in config, not inferred at runtime (compiler at packages/workspace/src/execution-to-fsm.ts). The LLM does work inside each state; the FSM decides what runs next. An agent can't decide mid-run to do something you didn't define. Every run leaves a full trace: the state machine, a waterfall timeline of each step, and the complete input and output of every tool call. When something breaks you see which state failed and why. Agents get an explicit MCP tool allowlist enforced in code as a hardcoded Set, not a prompt-level "please don't" (see packages/core/src/agent-conversion/agent-tool-filters.ts). Memory is append-only markdown, auto-injected into agent context at session start, agents write summaries back via memory\_save. No vector DB, no retrieval tuning; agents call memory\_read first to dedupe. Reliability holds up across model bumps because the state graph is the contract; only entry-action prompts change. Setup is fast for most workflows, especially the out-of-the-box ones (cron, webhook signals). It's macOS only for now. Docs: [docs.hellofriday.ai](http://docs.hellofriday.ai/) Repo: [github.com/friday-platform/friday-studio](http://github.com/friday-platform/friday-studio) Would love feedback, especially from folks who've built with agents.
Original Article
View Cached Full Text

Cached at: 05/08/26, 10:18 AM

friday-platform/friday-studio

Source: https://github.com/friday-platform/friday-studio

Friday Studio

CI Discord

Friday turns natural-language asks into repeatable AI-powered workflows. You describe what you want in chat — “every morning, triage my inbox, draft replies, file real asks as Linear tickets” — and the result is a workspace.yml you can read, version, share, and run on schedule. Run it once, or run it forever.

Why both a chat and a YAML? Prompts decay. Run the same prompt tomorrow and the output drifts; bump the model and your old contracts shift with it. Friday keeps both halves of the loop: conversation is how you build, configuration is how you ship — agents, MCP tools, signals (HTTP, cron, Slack, email, webhook), and the jobs that wire them together. Read the file. Version it. Hand it to a teammate and it runs the same on their machine.

Two surfaces, one runtime:

  • Chat in the playground. Friday picks up your installed skills, MCP servers, memory, and OAuth credentials, and actually drives your tools instead of describing what it would do.
  • Run autonomously. Capture the pattern in a workspace.yml, bind it to a signal, and the daemon runs it observably and locally on schedule.

It’s for developers and operators who want agents in production — reviewing PRs at 3am, draining their inbox before standup, watching competitor pricing, summarizing a Fathom call into a Linear ticket — without wiring queues, secret stores, schedulers, MCP plumbing, and provider clients from scratch every time.

Prefer the packaged version? hellofriday.ai ships the same daemon and playground as a one-click installer for macOS with the launcher, dependencies, and tray UI bundled. The rest of this README is for working in-tree.

Architecture

What it isWhen you use it
atlasd (daemon)Headless runtime — HTTP API on :8080, workspace lifecycle, signal router, session state, JetStream message bus.Production. CI. Anything you’d systemd-ify.
Agent PlaygroundSvelteKit web UI on :5200 — chat with Friday, author and run agents, inspect every session step-by-step, manage skills/MCP servers/schedules/memory/credentials, browse the workspace marketplace.Day-to-day. The playground is what you actually look at.

The desktop installer ships both behind a tray icon. In-tree, deno task dev:playground runs both side by side with hot reload.

Quickstart

Prerequisites

The daemon orchestrates several runtimes — Friday agents can be authored in TypeScript or Python, can drive a real browser, and fan out work over a message bus. Install the four below yourself, then scripts/setup-dev-env.sh handles the rest.

You install these (we won’t touch your version managers):

ToolMinWhy
Node.js24+Playground runs under Vite via npx; @atlas/ui builds with svelte-package. Manage via fnm/volta/nvm — auto-installing system Node clobbers project pins.
gitany recent

setup-dev-env.sh handles these — installs if missing or below min, otherwise keeps yours:

ToolMinWhy
Deno2.7.0Runs the daemon, CLI, link service, and every TS/Svelte package.
Go1.26.0Builds the Go services in tools/. macOS auto-install via Homebrew; Linux fails with the install URL (no sudo without consent).
uv0.11.0Provisions the managed Python that type: "user" agents spawn under.
nats-server2.12.0Internal message bus the daemon spawns for agent ↔ daemon RPC. Pinned to v2.12.8 for fresh installs.
agent-browserlatestCLI the bundled web agent shells out to for headless browsing. Pulls a Chromium build (~150MB) on first run.
Python 3.12 + friday-agent-sdkpinnedPre-warmed into uv’s cache so the first user-agent spawn isn’t a cold start.

Docker (optional) skips all of the above — docker compose up runs the whole stack in containers.

You don’t need a separate database for local development — the daemon persists state through its embedded JetStream bus. Postgres is only needed for production deployments of the link credential service.

1. Clone and install

git clone https://github.com/friday-platform/friday-studio
cd friday-studio
bash scripts/setup-dev-env.sh    # bootstraps deno+go+uv+nats+agent-browser, runs deno install, pre-warms Python

setup-dev-env.sh checks each tool’s version against the minimums above and keeps your existing toolchain wherever it satisfies them — auto- install only kicks in for missing or stale tools. It also runs deno install, writes the daemon envfile, and pre-warms the uv cache. Re-run it whenever the pinned friday-agent-sdk version bumps in tools/friday-launcher/paths.go.

If the script ends with a ⚠ Skipped: block, follow the per-tool hint and re-run. Common case: agent-browser install fails on a system Node — switch to a user-scoped Node manager (fnm/volta/nvm) and re-run to enable web/browser agents.

2. Configure environment

cp .env.example .env
# open .env and set ANTHROPIC_API_KEY (or another provider key)

The example file documents every variable the daemon reads — provider keys, proxies, OAuth/GitHub App credentials, integration tokens. The minimum to run a real agent is one LLM provider key.

3. Run the playground (recommended)

One command, four processes — daemon, link, playground, and webhook tunnel — all with hot reload:

deno task dev:playground

Open http://localhost:5200 and the sidebar gives you everything: bundled agents under Agents, MCP server browser, skills, schedules, memory, workspace inspector, settings.

4. (Or) just the daemon

If you only need the API:

deno task atlas daemon start --detached
curl -sf http://localhost:8080/health && echo "  daemon ok"
deno task atlas daemon stop

Examples

Just chat with it

Open the playground at http://localhost:5200. Type:

Find every unread email from my team that’s waiting on a reply, summarize what each is asking, and draft responses.

Friday uses your google-gmail MCP server to search the inbox, an LLM agent to triage, and Gmail’s create_draft tool to leave the replies in your drafts folder — picking tools from what’s installed. Same surface as a chat product, except the actions actually run. No tools wired up? Add them under MCP / Skills / Settings and ask again — the conversation continues.

The CLI is the same surface, headless:

deno task atlas prompt "summarize the last 10 PRs in friday-platform/friday-studio"
deno task atlas chat <chatId> --human    # readable transcript

Promote a chat into a workspace

When a one-off chat is worth re-running on its own, capture the agents and tools you used in a workspace.yml and bind it to a signal.

HTTP — review every PR I open:

git clone https://github.com/friday-platform/friday-studio-examples
deno task atlas workspace add ./friday-studio-examples/github-pr-reviewer

curl -X POST http://localhost:8080/review-pr \
  -d '{"pr_url": "https://github.com/your-org/your-repo/pull/42"}'

The workspace declares an HTTP signal at /review-pr, an LLM agent with the gh MCP server, and a system prompt scoped to your team’s review checklist. Wire it to GitHub via webhook-tunnel for a public URL.

Cron — drain my inbox before 9am:

# workspace.yml
workspace: { name: inbox-zero }
signals:
  - { id: morning, type: cron, schedule: "0 8 * * 1-5" }
agents:
  - id: triage
    type: llm
    model: claude-sonnet-4-6
    mcp: [gmail, linear]
    prompt: |
      Read unread Gmail. Real asks → file as a Linear ticket tagged `inbox`.
      Newsletters → archive. Reply to anything from <my-team>.
jobs:
  - { on: morning, run: triage }

deno task atlas workspace add ./inbox-zero and the cron is live. Each morning’s run lands in Platform → inbox-zero → Sessions.

Web — watch competitor pricing: the bundled web agent shells out to the agent-browser CLI, so any agent (chat or workspace) can drive a real Chromium. Install once with npm i -g agent-browser && agent-browser install, then bind it to an hourly cron and have it post to Slack on price changes.

Skip the YAML — write Python

For mechanical work where an LLM is overkill, an agent declared type: "user" is a Python file the daemon spawns under uv. The agent calls LLM, HTTP, and MCP capabilities through friday-agent-sdk — authoring guide, full API, and ten runnable examples live in friday-platform/agent-sdk.

Rule of thumb: use type: "user" only when each call’s decision is mechanical (regex / schema / fixed routing). For LLM-judgment work, use type: "llm" with MCP tools.

Browse friday-studio-examples for github-digest, competitive-monitor, daily-operating-memo, jira-bugfix-bitbucket, and others.

Agent Playground

deno task dev:playground opens the playground at http://localhost:5200. It’s the same Svelte app the desktop installer ships — production UI, not a debug widget.

What’s in there:

  • Agents — bundled agents (claude-code, gh, jira, hubspot, web, csv, knowledge, image-generation, …) with one-click execute and live SSE streaming. Build a custom one-shot agent (provider, model, system prompt, MCP tools) from the same screen.
  • Workspaces / Inspector — load a workspace.yml, see the parsed signals/agents/jobs graph, run the full pipeline (prompt → blueprint → FSM compile → execute), and replay every step from disk.
  • Platform → <workspace> — sessions per workspace, FSM state, per-step transcripts, tool calls, costs.
  • MCP — every MCP server registered with the daemon, with tool schemas and a “test call” panel.
  • Skills — author and edit the markdown skills agents load on demand.
  • Memory — narrative memory each workspace has accumulated.
  • Schedules — every cron-bound job, last/next fire, manual trigger.
  • Discover — workspace marketplace (browse and install community workspaces).
  • Settings — model chains, OAuth, provider keys, environment.

CLI mode (workspace generation, no UI):

deno task sim "build a daily competitor-pricing digest"          # full pipeline
deno task sim "..." --stop-at=plan       # blueprint only
deno task sim "..." --stop-at=fsm        # blueprint + FSM compile
deno task sim "..." --real               # execute with real MCP agents

Artifacts land in runs/workspaces/<timestamp>-<slug>/ — replay them in the playground’s Workspaces / History tab.

Common commands

# Daemon lifecycle
deno task atlas daemon start --detached   # background
deno task atlas:dev daemon start          # auto-restart on file change
deno task atlas daemon status             # health
deno task atlas daemon stop

# Talk to it
deno task atlas prompt "your prompt"      # one-shot prompt → bundled chat workspace
deno task atlas chat                      # list recent chats
deno task atlas chat <chatId> --human     # readable transcript

# Develop
deno task typecheck                       # deno check + svelte-check
deno task lint                            # deno lint + biome check --write
deno task fmt                             # biome format --write
deno task test <file>                     # vitest single file

Docker

Want it all in containers?

docker compose up

Brings up the daemon, playground, link credential service, PTY server, and webhook tunnel. Ports default to 1xxxx to avoid host collisions — see docker-compose.yml.

Project structure

apps/
  atlasd/             # Daemon — HTTP API, workspace lifecycle, signal router
  atlas-cli/          # CLI entry point — `deno task atlas`
  link/               # Credential / OAuth service
  ledger/             # Resource & activity storage service
  studio-installer/   # Tauri desktop app — tray, daemon supervisor,
                      # autostart. The hellofriday.ai download.
packages/             # @atlas/* libraries — core, agent-sdk, config,
                      # fsm-engine, llm, logger, mcp, memory, skills,
                      # storage, workspace, signals, jetstream, …
tools/
  agent-playground/   # Web client (SvelteKit) — production UI
  evals/              # Agent eval harness
  friday-launcher/    # System tray launcher + daemon supervisor (Go)
  pty-server/         # WebSocket → PTY shell bridge (Go)
  webhook-tunnel/     # Cloudflare tunnel → daemon webhook forwarder (Go)

Config: friday.yml (platform-wide) · workspace.yml (per-workspace) · CONTRIBUTING.md (dev guidelines + code style).

Learn more

License

Friday is source-available under the Business Source License 1.1. You can read, modify, and self-host the code under the Additional Use Grant, which permits free production use for personal use, organizations under 5 people, and businesses with under $1M ARR. Production use outside those bounds, or that competes with Tempest Labs’ offering, requires a commercial license. Each released version converts automatically to Apache-2.0 one year after that version is first distributed (current version’s Change Date: 2027-04-30; later versions get their own date).

For commercial-license inquiries: [email protected].

Third-party components retain their original licenses — see THIRD_PARTY_LICENSES.md and NOTICE (includes MPL-2.0 §3.2 source-availability notice and license elections for dual/tri-licensed deps).

Similar Articles

Introducing the Stateful Runtime Environment for Agents in Amazon Bedrock

OpenAI Blog

OpenAI and Amazon have partnered to introduce a Stateful Runtime Environment for agents in Amazon Bedrock, enabling production-grade multi-step agent workflows with built-in state management, reliability, and governance. The runtime runs natively in AWS environments and simplifies complex agentic orchestration for enterprise use cases like customer support, sales operations, and finance processes.

Should an agent be code or a declared thing with its own runtime?

Reddit r/AI_Agents

The author argues that AI agents in production should be defined as declarative manifests with their own runtime, rather than being scattered across application code, in order to enable proper versioning, observability, and rollback. They present their own solution as an open-source tool.