@bevel-software/pipeline-agent
v0.1.9
Published
An AI coding agent for CI (GitLab/GitHub), connected to your knowledge base and any HTTP UTCP tool manuals.
Readme
@bevel-software/pipeline-agent
An AI agent for your CI pipeline, connected to your knowledge base — and to
any other HTTP UTCP tool
manuals you point it at. It can read and edit files in the checked-out repo, run
commands, and query/update the knowledge base. (To give it the repo's files, add
actions/checkout on GitHub Actions — GitLab CI clones the repo automatically.)
By default it even borrows the
backend's model, so a pipeline needs only your knowledge-base URL + key — no
model API key. Runs straight from npx — nothing to install.
GitLab CI
# .gitlab-ci.yml
kb-agent:
image: node:22
timeout: 20m
variables:
KNOWLEDGE_BASE_API_URL: "https://your-company.bevel.software"
AGENT_PROMPT: |
Check our README against the onboarding process in the knowledge base.
Flag anything out of date and suggest fixes.
script:
- npx --yes @bevel-software/pipeline-agent@latestSet KNOWLEDGE_BASE_CONNECTION_KEY as a masked + protected CI/CD variable
(Settings → CI/CD → Variables) — never inline secrets. --yes skips the npx
prompt in non-interactive CI.
Why
@latestand not a bare name or a version pin? npx resolves the package against the current directory first. If you run the agent inside a JS repo whosepackage.jsonhappens to satisfy the spec, npx uses that local checkout instead of the registry — and if its build isn't present it fails withpipeline-agent: not found(exit 127).@latestis a dist-tag only the registry can resolve, so npx is always forced to fetch the published build. This keeps the command working from any repo, JS or otherwise.
GitHub Actions
jobs:
kb-agent:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4 # so the agent can read/edit the repo's files
- uses: actions/setup-node@v4
with: { node-version: 22 }
- run: npx --yes @bevel-software/pipeline-agent@latest
env:
KNOWLEDGE_BASE_API_URL: https://your-company.bevel.software
KNOWLEDGE_BASE_CONNECTION_KEY: ${{ secrets.KNOWLEDGE_BASE_CONNECTION_KEY }}
AGENT_PROMPT: Summarise our value-slice definition from the knowledge baseEnvironment variables
| Variable | Required | What |
|---|---|---|
| KNOWLEDGE_BASE_API_URL | yes | Knowledge base backend URL, e.g. https://your-company.bevel.software |
| KNOWLEDGE_BASE_CONNECTION_KEY | yes | A connection key from your knowledge base settings. Store as a masked CI variable. |
| AGENT_PROMPT | no | The task prompt — an alternative to -p "…" (nice for multiline YAML). See The prompt. |
| OPENAI_API_KEY (or another provider key) | no | Only needed to override the model yourself — see Model. |
| UTCP_MANUALS | no | JSON array of extra tool manuals — see Adding other tool manuals. |
| PIPELINE_KB_CONTEXT_WINDOW | no | Tokens the agent assumes the proxied model can take before it compacts the conversation. Default 400000. Set it to your backend model's window, with some margin, when you want reviews to carry more or the model's limit is lower. |
Model
The agent has no model of its own — it routes its LLM calls through your knowledge base's built-in proxy (authenticated with the connection key), and the backend decides the model. Switch the model on the backend and every pipeline follows automatically; the pipeline holds no model API key and there's nothing to configure here.
Advanced (optional): to use your own model instead, set a provider API key (e.g.
OPENAI_API_KEY) and pass--provider <name> --model <id>— that takes precedence over the proxy.
The prompt
Give the agent its task with -p "…", or set AGENT_PROMPT instead — nicer
for multiline prompts, which are awkward to quote on a command line but trivial
as a YAML | block (see the GitLab example). With AGENT_PROMPT set you don't
pass -p at all; the agent runs headless on that prompt. If both are given,
-p wins.
Adding other tool manuals
To give the agent more tools, set UTCP_MANUALS to a JSON array of UTCP HTTP
call templates ({ name, url, http_method?, headers?, … }):
variables:
UTCP_MANUALS: |
[
{ "name": "WEATHER", "url": "https://api.example.com/utcp",
"headers": { "Authorization": "Bearer ${API_KEY}" } }
]
# ${API_KEY} resolves from WEATHER_API_KEY (a masked CI variable)nameis the variable namespace: a${VAR}in that manual resolves from the env var<name>_<VAR>(soWEATHER+${API_KEY}→WEATHER_API_KEY). Avoid underscores in names.urlmust return a UTCP manual ({ utcp_version, tools }).- A bad manual is skipped (and logged); it won't affect the knowledge base or the others.
Running without the knowledge base
The knowledge base provides both the KB tool and the default model. If you
omit both KNOWLEDGE_BASE_API_URL and KNOWLEDGE_BASE_CONNECTION_KEY, the
agent runs with its built-in tools plus any UTCP_MANUALS — and you must supply
your own model (a provider key + --provider/--model), since the proxy isn't
available. (Setting only one of the two KB vars is treated as a mistake and
fails with a clear message.)
Security
A connection key acts as a specific user in your knowledge base, is long-lived (revoke-only), and can spend the backend's model budget via the proxy (capped per key per day). Mint a dedicated key for CI, keep it in masked + protected CI variables, and revoke it if it leaks. The agent runs unattended with file and command access inside its CI container — scope the job, branch, and key accordingly.
