Skip to content

Latest commit

 

History

History
159 lines (124 loc) · 6.96 KB

File metadata and controls

159 lines (124 loc) · 6.96 KB

Getting started (local)

Everything runs on your machine with docker compose: one container per agent, plus a self-hosted Langfuse stack for tracing. This is the default mode (target: local) and the right place to start even if you plan to deploy to Kubernetes later — agents behave identically in both.

Prerequisites

  • Docker — Docker Desktop, or any Docker Engine with Compose v2.20+ (docker compose version).

  • Node.js ≥ 22 (node --version).

  • Slack workspace + Slack CLI — wrapper creates one Slack app per agent, fully automatically, through the Slack CLI:

    brew install --cask slack-cli    # or the installer for your OS
    slack auth login                 # one-time, per workspace
  • Your Slack team ID (T0…) — shown by slack auth list, or in Slack under workspace name → "About this workspace".

  • An LLM provider API key — e.g. ANTHROPIC_API_KEY. Any provider supported by pi-ai works; the model is chosen per agent as provider/model-id.

Install and initialize

git clone <this-repo> && cd wrapper
npm install --ignore-scripts
npm run build

cp wrapper.example.yaml wrapper.yaml     # edit: target: local, your slackTeamId
node packages/cli/dist/index.js init --team-id T0XXXXXXXXX

Tip: alias the CLI — alias wrapper="node $PWD/packages/cli/dist/index.js". The rest of the docs assume this alias.

init does three things (idempotent — safe to re-run):

  1. Generates all secrets for the Langfuse stack into infra/langfuse/.env and wrapper.secrets.json (both gitignored, mode 600). Existing values are kept.
  2. Writes an agents/.env stub for shared provider API keys (excluded from git in both repos; a legacy root .env still works, with per-agent > agents/.env > root precedence).
  3. Starts the Langfuse v3 stack (web, worker, postgres, clickhouse, redis, minio) and provisions the wrapper org + shared wrapper-agents project headlessly. First run downloads several images — expect a few minutes.

When it finishes you get the Langfuse UI URL (http://localhost:3010) and a one-time printout of the admin login (also kept in wrapper.secrets.json).

Per-agent Langfuse projects are an enterprise-only API on OSS self-hosted Langfuse, so all agents share the wrapper-agents project and are separated by tag and session. To give an agent its own project, create it in the UI and wrapper env set <agent> LANGFUSE_PUBLIC_KEY=… LANGFUSE_SECRET_KEY=….

Already running Langfuse somewhere (self-hosted or Langfuse Cloud)? Set langfuse.external: true in wrapper.yaml and skip the bundled stack entirely — see langfuse.md.

Set your provider key

Shared across all agents (each agent's own .env overrides it):

echo 'ANTHROPIC_API_KEY=sk-ant-...' >> agents/.env

Create and run your first agent

wrapper agent add support-bot --channels "#support" --model anthropic/claude-sonnet-4-5
wrapper up support-bot

agent add scaffolds agents/support-bot/ (config, prompt, an example tool), creates + installs a dedicated Slack app non-interactively, mints its SLACK_BOT_TOKEN/SLACK_APP_TOKEN straight into agents/support-bot/.env (never printed), and writes the Langfuse keys. up regenerates docker-compose.yml and starts the container.

Then in Slack: /invite @support-bot to a channel and @mention it, or DM it directly. Every thread is a separate conversation with persistent history; every reply shows up as a trace in Langfuse with token usage, cost, and tool spans.

See agents.md for everything you can put in an agent — custom tools, cron schedules, memory, workspace files, custom Docker images.

Day-to-day commands

wrapper status                    # containers + langfuse health
wrapper ui                        # web console at localhost:3020 (status, logs, env)
wrapper logs support-bot -f       # follow logs
wrapper env set support-bot K=V   # set container env (then restart)
wrapper env list support-bot      # list env (secrets masked; --show to reveal)
wrapper restart support-bot       # picks up .env changes
wrapper down [agent...]           # stop agents (no args = whole stack)
wrapper agent remove support-bot [--purge]   # delete Slack app (+files with --purge)

Files you should know about

Path What In wrapper's git?
wrapper.yaml your deployment config (copy of wrapper.example.yaml); can live at agents/wrapper.yaml to be versioned in your agents repo no
wrapper.secrets.json Langfuse admin/project keys, generated by init no
agents/.env shared provider API keys (all agents) never, in any repo
agents/<name>/ agent config, prompt, tools no — your own git (see below)
agents/<name>/.env that agent's Slack tokens + keys never, in any repo
docker-compose.yml generated from agents/*/agent.yaml — do not edit no
k8s/ generated manifests (k8s target only) — do not edit no
infra/langfuse/ the Langfuse stack compose file (+ generated .env) yes (not .env)

Everything gitignored is either a secret, regenerated by the CLI, or yours; a fresh clone needs only npm install, npm run build, a wrapper.yaml, and wrapper init.

Your agents get their own git

Wrapper's repo ignores the entire agents/ folder — your agents are your code, versioned separately, so git pull in the wrapper root updates the framework without ever touching your agents (and your agents' history never lands in the framework repo). Typically:

cd agents && git init && git remote add origin <your-agents-repo>

wrapper agent add scaffolds the folder with a README and .gitignore files (at agents/ and per agent) that keep secrets (.env, data/, slack/.slack/) out of your repo. Consider committing your wrapper.yaml as agents/wrapper.yaml too — the CLI reads it from there when the root has none, making your whole deployment restorable from that one private repo.

Updating wrapper later:

git pull && npm install --ignore-scripts && npm run build
wrapper up        # rebuild + restart agents on the new runtime

Troubleshooting

  • init hangs waiting for Langfuse — check docker compose logs langfuse-web. The healthcheck hits http://$HOSTNAME:3000/api/public/health inside the container (Next.js binds the container IP, not loopback).
  • Traces get 401s right after setup — Langfuse caches API-key verdicts in Redis; a key used before it existed can have a cached 401. Wait for the TTL or flush Redis.
  • Bot doesn't answer in a channel — it must be invited, and if channels: [...] is set in agent.yaml, the channel must be listed (the allowlist applies to @mentions; DMs are always answered).
  • Two replies or missed events — never run two copies of the same agent (e.g. local container + k8s pod): both hold Socket Mode connections and Slack splits events between them.