← All posts

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.

Vocion Teamvocion-v2.47.4

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:

  1. A registry — a versioned, queryable list of what agents, teams, and skills exist.
  2. Human-in-the-loop — a point where a person can see a proposed action before it executes.
  3. Learning — a way for corrections to accumulate instead of evaporating after one session.
  4. Logging — a record of what ran, with what input, and what it cost.
  5. Hosting — somewhere the agents actually run, on a schedule or on demand.
  6. Versioning — a way to know which version of a prompt or policy produced a given output.
  7. Reporting — a surface a human reads to answer "what happened this week".
  8. 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:

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:

LayernpmPurpose
@vocion/corethis repoFramework, dashboard, Postgres schema, MCP server, workflow runner
@vocion/sdkpackages/sdkStable 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:

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:

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.

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.