eparch
GitHubGet started

PLATFORM

Everything a governed agent deployment needs.

Ten Go services that give agents a gateway, retrieval, tools, identity, policy, evaluation, budgets, and audit — so your team ships agents instead of plumbing.

LLM GATEWAY

One governed door to every model.

The Eparch gateway is an OpenAI-compatible chat, embeddings, and rerank proxy with rule-based model routing and fallback, a semantic response cache, per-tenant daily and monthly budgets, and Redis-backed rate limiting.

# gateway model routing — first match wins
routes:
  - match: { task: "chat", tier: "fast" }
    model: llama-3.3-70b
    fallback: qwen-2.5-72b
  - match: { task: "embedding" }
    model: jina-embeddings-v3
  - default: llama-3.3-70b

HYBRID RAG

Retrieval that lives next to your data.

Eparch's RAG service combines pgvector similarity search with object-store document storage; embeddings and reranking flow through the gateway, so retrieval is governed and budgeted like everything else.

sh
$ eparch rag query --collection runbooks 'postgres failover procedure'1. runbooks/pg-failover.md#step-2   score=0.912. runbooks/pg-failover.md#step-1   score=0.883. incident-history/2026-03-04.md   score=0.79

TOOL REGISTRY

Tools and MCP servers, secrets included.

The tool registry holds every tool and MCP server an agent may call, with an AES-256 encrypted secret store — credentials are encrypted at rest in Postgres and never leave the data plane.

POST /v1/tools
{
  "name": "jira-create-issue",
  "kind": "mcp",
  "endpoint": "https://mcp.internal:8443",
  "secretRef": "jira-api-token"   // AES-256 encrypted at rest in Postgres
}

AGENT CONFIG

Canary deploys, gated by evals.

Agent definitions are versioned objects. A new version rolls out as a canary, and promotion is blocked server-side until its eval runs pass the quality gate.

v12 (stable) ──► v13 canary 10% ──► eval gate ✓ ──► v13 promoted
                                        eval gate ✗ ──► automatic rollback

EVALUATION

Quality gates the platform enforces.

The eval service runs suites against agent versions and enforces results server-side — promotion isn't a convention, it's a checked precondition.

sh
$ eparch eval run --suite triage-regression --agent incident-triage@v13running 24 cases…  accuracy      0.96  (gate ≥ 0.90)  ✓  latency p95   1.8s  (gate ≤ 3.0s)  ✓PASS — v13 eligible for promotion

MULTI-TENANCY

Isolation the database enforces.

Every data-plane service connects to Postgres as a non-superuser role with row-level security enforced on every query — tenant isolation is a database guarantee, not an application convention.

-- every data-plane table is scoped like this
ALTER TABLE agent_configs ENABLE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolation ON agent_configs
  USING (tenant_id = current_setting('app.tenant_id')::uuid);

-- services connect as eparch_app, a non-superuser role:
-- RLS cannot be bypassed, on any query, ever.

POLICY

OPA authorization on every service.

An Open Policy Agent interceptor authorizes every request on every service, so access rules are written once as policy and enforced everywhere.

package eparch.authz

default allow := false

allow if {
  input.subject.role == "operator"
  input.action in {"agent.run", "agent.read"}
  input.resource.tenant == input.subject.tenant
}

AUDIT

An immutable record of every decision.

Eparch writes immutable, per-tenant audit logs with usage and cost accounting for every request that touches a model — hash-chained, queryable, and exportable.

{"ts":"2026-07-23T14:02:11Z","tenant":"9f2c…","actor":"agent:incident-triage",
 "action":"llm.chat","model":"llama-3.3-70b","tokens":{"prompt":1204,"completion":312},
 "costUsd":0.0041,"decision":"allow","hash":"sha256:ab41…","prevHash":"sha256:77c0…"}

EVENT BACKBONE

Events without another broker to run.

The event backbone is a Postgres transactional outbox: state changes and their events commit atomically, and the broker service fans them out to agents and consumers.

INSERT agent_run ─┐
                  ├─ same transaction ──► outbox ──► event-broker ──► triggers
UPDATE budget    ─┘

UI + SDKS

No-code in the UI. Full code in Go or TypeScript.

Define no-code agents in the platform UI, or build code-first agents with the Go and TypeScript SDKs — the same triggers, tools, RAG, and governance either way.

Go

agent := eparch.NewAgent("incident-triage").
  WithModel("llama-3.3-70b").
  WithSystemPrompt("You are an incident triage specialist…").
  WithRAG(eparch.RAGConfig{
    Collections: []string{"runbooks"}, TopK: 5,
  }).
  WithTools(
    eparch.Tool("slack-post-message"),
    eparch.Tool("runbook-executor").RequireApproval(),
  ).
  WithTrigger(eparch.KafkaTrigger{Topic: "alerts.xmatters"}).
  OnMessage(handleIncident)

TypeScript

const agent = Agent.create('incident-triage')
  .withModel('llama-3.3-70b')
  .withSystemPrompt('You are an incident triage specialist…')
  .withRAG({ collections: ['runbooks'], topK: 5 })
  .withTools(Tool.named('slack-post-message'))
  .withTrigger(new KafkaTrigger({ topic: 'alerts.xmatters' }))
  .onMessage(async (msg) => {
    const result = await msg.complete()
  })