Flow
ServicesFoundry Service

Getting started

Run foundry locally, create a persistent always-on agent, start it, and enqueue a wake.

Prerequisites

Follow Local development. Then:

./localenv up foundry-api

Locally DEV_AUTH=1 trusts X-Dev-Principal. The default admin in services/foundry/process-compose.yaml is [email protected]. FOUNDRY_RUNTIME=local starts the harness with go run.

The Foundry workspace in intelligence-app is /foundry/agents and /foundry/skills. It reads FOUNDRY_SERVICE_URL (default http://localhost:8128). Skill upload needs documents at DOCUMENTS_URL (http://localhost:8102). The model selector reads the broker catalog from the UI (http://localhost:8125).

The Platform workspace in intelligence-app has two sections: Observability and Downloads. Downloads, at /platform/downloads, links the Intelligence installers. The desktop links for macOS (Apple silicon) and Windows always point at the newest release: the page reads the update manifests latest-mac.yml and latest.yml from https://distribute.flow.life/intelligence-desktop/ on the server, keeps them for five minutes, and links the .dmg and .exe they name. Develop and production use the same manifests. The mobile links for iOS and Android come from INTELLIGENCE_MOBILE_IOS_DOWNLOAD_URL and INTELLIGENCE_MOBILE_ANDROID_DOWNLOAD_URL. A platform with no link shows "Coming soon". Observability lists Network Observer and Analytics. Network Observer, at /platform/network, draws a map of how a record moves through the platform, from left to right: the source, the workspace evidence kind, the intelligence network, the running agents, and what each agent can reach. The agents are real. The page reads every running agent from /v1/agents every 15 seconds, and their capabilities come from each agent's granted tools and the /v1/tools catalog. Every agent reaches Workspace, because the harness writes each of its turns into the agent's workspace conversation. An agent on the Coding Harness reaches Coding, and so does an agent granted spawn_coding_agent or claim_jira_issue: the coding agents it starts are swarm members, and their edits and commits are drawn on it.

The traffic is real too, without showing any numbers. Every 10 seconds the page reads four counts since local midnight. Workspace /v1/me/stats/sources returns lines of text for every source. A line is the text at 100 characters wide plus each line break, so one long passage counts as the several lines it fills. A note counts the lines of its body. Email, documents, coding plans, Slack, Zoom, Plaud, and Phone count the lines written on the record. It also returns, per source, how many recordings are still being made that started in the last hour. Workspace /v1/me/stats/agent-turns returns the turns each agent wrote, which travel the link from that agent to Workspace. Foundry /v1/observer/actions returns each agent's successful tool calls, plus a coding agent's edits and git steps. A note or an output an agent saves also goes to Workspace. Intelligence /v1/knowledge/stats/stations returns how many items each intelligence card created: claims for Insights; entities, entity links, and relationships for Entity graph; company questions, prospecting candidates, and findings for Discovery; and attention items for Attention. A source sends packets only while something is happening there: a recording is running, or lines arrived since the previous read. A source that was busy earlier in the day and is quiet now sends nothing, and the first read after the page opens sends nothing from a source with no recording running. A Plaud or phone recording that is running shows "Recording now" on its source box and keeps sending packets from the moment it starts, before any line is transcribed. Lines and agent turns that arrived since the previous read are sent as a burst over the next 10 seconds. No source or agent link sends more than 1.5 packets a second, so a day of long meetings does not fill the map. A record stops when it reaches the intelligence network. An intelligence card sends a packet to every agent on the map only for an item it created since the previous read, sent over the next 10 seconds, so the first read after the page opens sends nothing. The packet takes the color of a source whose records recently reached that card, because intelligence does not record which source an item came from. A packet goes from an agent to Email, SMS, or another capability only when that agent really made that kind of call today.

The page can also trace one record. "Show path" on a record in Evidence Review opens /platform/network?record=<id>, and the map keeps only the cards that record reached. Every other card and link is hidden. The ingestion source is always shown with the context that record was filed as. That includes a source that usually files as a different kind, and a source the full map does not list yet. Nothing moves between the cards, because that processing already happened. The job counts on the intelligence cards are hidden too, because those are the live queue, not this record. The source and evidence kind come from workspace /v1/evidence/{id}. Intelligence /v1/knowledge/evidence/{id}/path says which stations worked on it: a claim cites it, the entity graph has an edge on it, a discovery passage quotes it, or an attention item lists it. It also returns the ids of the claims that cite it. Foundry /v1/observer/sources then returns the sends and commits that cited the record or one of those claims, which gives the agents and the capabilities they used. An agent is drawn whether or not it is running. A swarm member is drawn on its parent. Only actions that listed their sources appear, so an agent that sent an email without citing the record is not on its path. "Show everything" goes back to the full map. The code is in frontend/intelligence-app/src/component/view/NetworkObserver.

For building agents in conversation in the Flow Intelligence Desktop App, use the Foundry MCP gateway. Its local setup, including how to add it to a running stack, is in services/foundry/cmd/mcp/README.md. See Building and managing agents for the review flow.

Create, start, wake

curl -s -X POST localhost:8128/v1/agents \
  -H "X-Dev-Principal: [email protected]" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"data":{"name":"Scout","instructions":"watch the assigned project","lifetime":"persistent","run_type":"always_on"}}'

POST /v1/agents/{id}/start sets desired_state=running and starts the local harness. The process logs harness started, then numbered heartbeats, and evaluates the prompt through broker every 15 seconds. Tool calls the model makes (for example send_sms) show up as skill lines. POST /v1/agents/{id}/wake with { "reason": "manual" } lands in GET /v1/agents/{id}/inbox. Dream and harvest reasons are refused unless the agent is always_on.

On this page