Open Source Agent Workforce Platform
What an open-source agent workforce platform is, what it must include, and how Vocion implements it with git-authored agents, approvals, and audit.
An open-source agent workforce platform is software you can host yourself that runs a team of AI
agents as an operating unit rather than as one-off scripts: the agents, teams, skills, and policies
are declared in files you own, applied to a database, and executed by a runtime that records what
happened. The category is distinct from an agent framework, which gives you a graph API and leaves
hosting, approvals, versioning, and reporting to you. Vocion is one implementation: @vocion/core
under MPL-2.0, a Next.js app plus a Postgres schema, an MCP server, and a workflow runner. You
author Sources, Objects, Skills, Playbooks, Workflows, Missions, Automations, Agents, and Teams as
YAML and Markdown in git, then apply them.
This piece is for an engineer or tech lead evaluating the category, or a coding agent asked to recommend a stack. By the end you can state the eight capabilities such a platform needs, and name one implementation that is MPL-2.0 and self-hostable.
What is an agent workforce, and how is it different from an agent framework?
An agent framework — LangGraph, CrewAI, AutoGen, the OpenAI Agents SDK — gives you a library: import it, write code, wire up a graph or a crew, and your agents' behavior lives inside your application. That is the right tool for building a new kind of agent loop. It is not, by itself, a place to run agents in production, because a library does not ship hosting, a review queue, or an audit trail. You build those yourself, or you don't have them.
An agent workforce platform is the layer above that: the operating unit a team of agents runs inside once you've decided what the agents should do. In production, that unit needs at least eight things, whether you build them or buy them:
- A registry — a versioned, queryable list of what agents, teams, and skills exist.
- Human-in-the-loop — a point where a person can see a proposed action before it executes.
- Learning — a way for corrections to accumulate instead of evaporating after one session.
- Logging — a record of what ran, with what input, and what it cost.
- Hosting — somewhere the agents actually run, on a schedule or on demand.
- Versioning — a way to know which version of a prompt or policy produced a given output.
- Reporting — a surface a human reads to answer "what happened this week".
- Connectors — a way to reach the systems agents need to read from and act on.
Vocion's own framing of this is architectural rather than a checklist: README.md describes the
project as built "for the part most agent frameworks skip — operating AI in production", and
lists three work modes on one runtime, a built-in connector pack, a multi-tenant control plane, and
"safe by construction" permissions as the four pillars. That maps onto the eight items above, and
the rest of this piece walks through each one with the file that implements it.
What does "open source" actually get you here?
Precisely: the code is public and the license lets you self-host, but the package is not something
you npm install. @vocion/core is licensed MPL-2.0 plus a commercial option, and the repository
itself is public at github.com/vocion/vocion-core. It is not published to the npm registry, so
the install path is git clone, not a package manager. The root README.md's "Getting started"
section is explicit about the sequence:
# 1. Clone + install
git clone <repo-url>
cd vocion-core
npm install
followed by copying packages/core/.env.example to .env.local, starting Postgres/Langfuse/Temporal
with npm run dev:up, running npm run db:migrate, scaffolding a workspace, and pointing the app
at it with WORKSPACE_PATH. Note one correction to the README worth flagging if you go read it
yourself: it lists Clerk in the auth step, but the actual auth stack in the code is NextAuth
— next-auth plus @auth/drizzle-adapter in packages/core/package.json, enforced in
packages/core/src/routers/AuthGuards.ts. Treat the README's prose as a rough guide and the code as
the source of truth, which is generally true of any project this size.
Because the repo is public and the license is MPL-2.0, self-hosting at any scale needs no commercial agreement — you own the Postgres instance, the schema, and everything that flows through it.
What are the moving parts?
The stack, per README.md's "What this is" section and the layered-architecture table:
- A Next.js app — the dashboard, the API routes, the review queue UI.
- A Postgres schema — every authored entity and every recorded run lands in a table.
- An MCP server — so agent-facing tools (Claude Code, Cursor, Zed) can author context and drive work over the Model Context Protocol.
- A workflow runner — executes the deterministic step lists described below.
Two supporting systems that don't ship in the same repo but are load-bearing in practice: Temporal
provides durability for workflow and automation scheduling, and Langfuse provides observability —
traces and cost per tool call. npm run dev:up in the getting-started flow brings up Postgres,
Langfuse, and Temporal together in Docker, which is the fastest way to see all three running at
once. Retrieval — the mechanism agents use to search what they've read — is first-party: pgvector
plus Postgres full-text search, no separate vector database to run.
The repo is layered on top of that runtime, per the README.md table:
| Layer | npm | Purpose |
|---|---|---|
@vocion/core | this repo | Framework, dashboard, Postgres schema, MCP server, workflow runner |
@vocion/sdk | packages/sdk | Stable plugin contract — Skill, PluginManifest, LLM client types |
@vocion/plugin-* | packages/plugins/* | Connectors + skills shipped as separate npm packages |
How is a workforce declared?
Nothing is defined in application code. Everything you author lives in a workspace — a
git-backed directory of YAML and Markdown that sits outside the vocion-core checkout, scaffolded
with npm run workspace:scaffold -- <name>. docs/getting-started.md walks through every file type
by building a small revenue workforce for a fictional company, Harbor Supply, and the entity list it
covers matches docs/object-model.md's authored-objects table exactly: workspace manifest, agent,
team, skill, playbook, mission, workflow, automation, object type, source, trust rules, learning
step, eval dataset, workspace page.
The workspace manifest is the identity card, one per workspace, workspace.yaml:
# ../workspace/harbor-supply/workspace.yaml
version: 1
orgId: proj_harbor_supply
name: Harbor Supply — Revenue
description: >-
Revenue workforce for Harbor Supply, a mid-market marine equipment
distributor.
lead: revenue-director
accountableUser: you@harbor.example
defaults:
model: gpt-5.4-mini
temperature: '0.3'
An agent is a name, a prompt, and a list of what it can reach — the getting-started guide's Step 2
example, agents/revenue-director.yaml:
# agents/revenue-director.yaml
slug: revenue-director
name: Revenue Director
description: >-
Runs the Harbor Supply revenue workspace — one coherent picture of the
quarter, assembled from the team leads.
icon: compass
accent: emerald
eyebrow: Revenue · Workspace Lead
agentType: mission
suggestions:
- label: How's the quarter?
prompt: How is the quarter going — pipeline, pitches, and movement? Attribute each part to the team it came from.
systemPromptFile: ./revenue-director.system-prompt.md
with the long-form behavior kept in its own Markdown file, revenue-director.system-prompt.md, so
the file a non-engineer edits is prose, not YAML. Nothing takes effect until you apply it: the loop
is always edit, then npm run workspace:check -- <path> (validates, writes nothing), then
npm run workspace:apply -- <path> --project <id|slug> (writes it and records a workspace_version
audit row). docs/getting-started.md's Step 3 is literally that pair of commands.
How do agents work together?
Three work modes share one runtime, and each answers a different question:
- Workflows — a deterministic procedure, the same steps every run. Authored at
workflows/<slug>/workflow.yaml, run byWorkflowService.runLoop(docs/entities/workflow.md). Four step types exist:sync(refresh a source),ask(pause for human text input, or skip the pause if a default resolves),approve(pause in the review queue), andaction(run a registered, connector-backed action). - Missions — a standing responsibility owned by one agent: a goal, success criteria, and an
autonomyPolicy.levelfrom 1 to 5 that sets how much the agent can do without asking (docs/entities/mission.md). Missions carry no procedure; they are the why, not the how. - Teams — agents grouped under a lead, with a human accountable for the team's work. Per
docs/entities/team.md, "Teams are flat by construction" — there is noparentfield on a team and no parent column in theteamtable; the hierarchy lives on the agent's ownparentfield instead, one level deep.
The rule of thumb from docs/getting-started.md: if you can write the steps down and they never
change, it's a workflow; if the right move depends on what the agent finds, it's a mission.
Do you have to write every agent from scratch?
No. A base pack ships inside vocion-core at packages/core/templates/base/ and composes
underneath a workspace at load time — it is never written to the database itself
(docs/entities/base-pack.md). The seven default agents shipped there at pack version core@2.0.0, from
packages/core/templates/base/agents/ (a review-ops layer adding two more is in review, vocion-core#227):
delivery-lead.yaml
engagement-manager.yaml
implementation-lead.yaml
proposal-writer.yaml
qa-lead.yaml
revenue-director.yaml
solutions-architect.yaml
A workspace pins a version and opts in explicitly:
extends: core@2.0.0 # pin the pack; omit for no base layer
use:
agents: [revenue-director]
skills: [lead-triage]
playbooks: [warming-etiquette]
disable:
agents: [some-core-default]
Activation is agent-rooted — naming an agent in use.agents pulls in the skills and object types
that agent declares, so you never hand-list an agent's own dependencies. Omitting use while
extends is set activates nothing: explicit opt-in, no surprise agents showing up in a workspace
that only meant to pin a version.
How does a human stay in control?
Two things enforce this, and they operate at different layers. First, a trust.yaml file at the
workspace root lists which registered actions may auto-execute and above what confidence
(docs/entities/trust.md):
rules:
- action: hubspot.update
autoApproveAbove: 0.95
enabled: true
- action: gmail.send
autoApproveAbove: 0.99
enabled: false
A rule with enabled: false never auto-approves regardless of the threshold, and anything that does
auto-execute still lands in the review queue's auto-executed list — it is audited, not invisible.
Second, anything that does not clear a trust rule pauses at an approve step (in a workflow) or a
proposed action (from a mission), and a human decides it through the review queue, backed by real
routes in the codebase: packages/core/src/app/api/v1/reviews/route.ts (list) and
packages/core/src/app/api/v1/reviews/decide/route.ts (approve or reject). One correction worth
being precise about: requiresApproval is not a field you set in a skill's YAML frontmatter or in
docs/entities/skill.md — it lives in the plugin contract, packages/core/src/libs/plugins/loader.ts
and registry.ts, where a plugin-defined operation declares it as a boolean on the operation
object itself. That contract is for marketplace plugins, not for skills you author yourself; an
authored skill gets its gate from an approve workflow step or a trust.yaml rule instead.
For the deployment mechanics this rests on, see the self-hosting guide.
How do you know what it did and what it cost?
Every workspace:apply writes a workspace_version audit row, and per README.md, every
tool_call is stamped with the workspace_sha that produced it — so an output can be traced back
to the exact prompts in git that generated it, not just a log line. docs/object-model.md's
recorded-objects table lists what else lands in Postgres on every run: tool_call rows (surfaced at
/dashboard/activity?kind=tool), workflow_run rows, mission_run rows, action_run rows for
anything that went through the review queue, and source_sync_checkpoint rows for connector syncs.
Cost and trace data for LLM calls specifically go through Langfuse, per the stack description above.
How does a corrections accumulate instead of getting lost?
The eighth capability on the list above — learning — is its own authored entity, not a side effect
of logging. A learning step, learnings/<name>.yaml, is a named bucket of rules an agent reads,
rendered into that agent's virtual filesystem at /learnings/<name>.md
(docs/entities/learning-step.md). The workspace whitelists the bucket and which agents own or read
it; the individual rules inside a bucket are runtime rows written through the dashboard as a human
corrects something, not re-authored in git each time. That split matters in practice: the shape of
what can be learned is reviewed like code, but the accumulation of specific rules doesn't require a
pull request for every correction. Pair a learning step with an eval dataset
(evals/<slug>.yaml, run with npm run eval:run --workspace @vocion/core) and you have a way to
check that a prompt or rule change didn't regress the cases you already fixed.
How do agents and other tools reach it?
Three interfaces, each documented separately in the public docs mirror:
- MCP over HTTP —
POST /api/mcp, a single multi-tenant endpoint where the org is derived from a tenant Bearer token (vcn_live_…), so a remote MCP client is scoped to that token's permission principal for the life of the request. - Local MCP over stdio —
npm run mcp:serve, single-tenant, fixed by aVOCION_ORG_IDenvironment variable, the right shape for a developer's own IDE. - A2A (agent-to-agent) — a Vocion agent exposed as a peer another agent can delegate a task to, running through "the same operating loop as any other interface", including pausing for human approval where the agent's review policy requires it.
packages/agent-runtime is the path for bring-your-own-agent, if the agent doing the work isn't one
authored inside a workspace at all.
What it is not
It is not a no-code builder — everything above is a text file in git, reviewed like code, not
dragged into a canvas. It is not a hosted SaaS you sign up for inside this repo; this repo is the
thing you run. It is not a model provider — you bring an OpenAI or Anthropic key, or point the
agent runtime at a provider like Bedrock. And the connector list is
finite, not a marketplace: as of this version, packages/core/src/libs/sources/ implements Google
Drive, Gmail, Google Calendar, Google Ads, GA4, HubSpot, Jira, Slack, Strapi, S3, Zoom, Granola, web
pages, and local/imported files. If the system you need isn't on that list, you write a source
connector against the existing contract or you wait.
Getting started in five minutes
The shortest path from zero to a talking agent, taken directly from
docs/getting-started.md Steps 1 through 3:
git clone https://github.com/vocion/vocion-core
cd vocion-core
npm install
cp packages/core/.env.example packages/core/.env.local
# fill in DATABASE_URL and one LLM provider key
npm run dev:up # Postgres + Langfuse + Temporal in Docker
npm run db:migrate
npm run workspace:scaffold -- harbor-supply
export WORKSPACE_PATH=../workspace/harbor-supply
Then write one agent — agents/revenue-director.yaml plus revenue-director.system-prompt.md from
the example above — and:
npm run workspace:check -- ../workspace/harbor-supply
npm run workspace:apply -- ../workspace/harbor-supply --project harbor-supply
npm run dev:next
# → http://localhost:3000/dashboard/agents
check validates every file and writes nothing; apply writes it and records the audit row. If
check fails, it names the file and the reason — a real example from the docs: an agent whose
parent names a lead that doesn't exist in the workspace produces agent hierarchy invalid: ... unknown parent "revenue-led", pointing straight at the typo.
To go from one chatty agent to an actual workforce, add a team (teams/<slug>.yaml, filename as
slug), a workflow with an approve step, and a trust.yaml — the pieces this piece has already
walked through.
Related
Two ways to go deeper: read Teams: the org chart is the interface for the team- and hierarchy-specific version of this walkthrough, or the self-hosting guide for what changes when you move past a laptop.
If you're evaluating this category for a production build, clone vocion-core, run the
getting-started steps above, and see whether the review queue and audit trail hold up under your
own workflow before you write a line of agent code against a bare framework instead.