Home/Install

Install

Two ways to run Talooner — both self-hosted, both with the same rules. Pick the one that fits how you work.

Talooner ships as one image — talooner-runner — that you add as a step to the pipeline you already have. The job starts OpenTalon and the Talooner plugin inside its own container, checks your license, reviews the merge request or pull request against your repository's .talooner/rules.tln, posts a check run and one comment, and exits.

registry.gitlab.com/onlinecopyrig-rlr6226/talooner-runner:1

The image holds binaries only — no source, no compiler — on a minimal, non-root base.

What you need

  1. A license key — from your license page (or get a free demo license).
  2. A forge token so Talooner can post its review: GitLab — a project or group access token, Developer role, api scope; GitHub Actions — the built-in github.token.
  3. Optional: any LLM for AI review — see Any LLM. Without one, Talooner reviews with rules only.
  4. Optional: Jev (JEV_URL + JEV_TOKEN) — TypeSafe's typed-decision model as a fast first pass: each changed unit gets a typed match / mismatch / unclear with a confidence score, and only what Jev can't confirm goes to the full LLM review.

Any LLM

Talooner works with any model behind an OpenAI-compatible API — hosted or on your own servers. Set three variables:

TALOONER_MODEL_BASE_URLTALOONER_MODEL
Qwen (Alibaba Cloud)https://dashscope-intl.aliyuncs.com/compatible-mode/v1qwen3-coder-plus
DeepSeekhttps://api.deepseek.com/v1deepseek-chat
OpenRouterhttps://openrouter.ai/api/v1any model it lists
Ollama / vLLM on your servershttp://llm.internal:11434/v1e.g. qwen3-coder

…plus TALOONER_MODEL_API_KEY (any non-empty value for a local server). Anthropic and OpenAI have shortcuts: ANTHROPIC_API_KEY, or OPENAI_API_KEY with TALOONER_MODEL.

The snippets below use the three variables; swap in a shortcut if you prefer.

GitLab CI

Works on gitlab.com and self-managed GitLab. Add the job to .gitlab-ci.yml, then add TALOONER_LICENSE_KEY and GITLAB_TOKEN (and optionally your LLM: TALOONER_MODEL_BASE_URL, TALOONER_MODEL, TALOONER_MODEL_API_KEY) under Settings → CI/CD → Variables, masked.

talooner:
  image:
    name: registry.gitlab.com/onlinecopyrig-rlr6226/talooner-runner:1
    entrypoint: [""]
  stage: test
  needs: []
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  variables:
    TALOONER_PROVIDER: gitlab
    GIT_STRATEGY: none
  script:
    - talooner-step

Keep entrypoint: [""] — GitLab runs the job's script: through a shell.

GitHub Actions

Works on github.com and GitHub Enterprise Server. Add TALOONER_LICENSE_KEY (and optionally your LLM's TALOONER_MODEL_API_KEY) under Settings → Secrets and variables → Actions, and allow GitHub Actions to create and approve pull requests under Settings → Actions → General.

# .github/workflows/talooner.yml
name: talooner
on:
  pull_request:
  pull_request_review:
  issue_comment:
    types: [created]
permissions:
  contents: read
  pull-requests: write
  checks: write
jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: docker://registry.gitlab.com/onlinecopyrig-rlr6226/talooner-runner:1
        env:
          TALOONER_PROVIDER: github
          TALOONER_LICENSE_KEY: ${{ secrets.TALOONER_LICENSE_KEY }}
          TALOONER_MODEL_BASE_URL: https://dashscope-intl.aliyuncs.com/compatible-mode/v1
          TALOONER_MODEL: qwen3-coder-plus
          TALOONER_MODEL_API_KEY: ${{ secrets.TALOONER_MODEL_API_KEY }}
          GITHUB_TOKEN: ${{ github.token }}

Any other CI

Jenkins, CircleCI, Buildkite, Drone, Woodpecker, TeamCity — anything that can run a container against a GitHub or GitLab repository:

docker run --rm \
  -e TALOONER_PROVIDER=gitlab \
  -e TALOONER_LICENSE_KEY \
  -e TALOONER_MODEL_BASE_URL -e TALOONER_MODEL -e TALOONER_MODEL_API_KEY \
  -e GITLAB_TOKEN -e GITLAB_API_URL \
  -e CI_PROJECT_ID -e CI_MERGE_REQUEST_IID -e CI_PIPELINE_SOURCE \
  registry.gitlab.com/onlinecopyrig-rlr6226/talooner-runner:1 talooner-step

The image prints a ready config for your CI: docker run --rm <image> snippet gitlab (or github, generic).

Gitea/Forgejo, Bitbucket and Azure DevOps are coming soon.

One variable instead of five

Put everything in one YAML file and store it as a single masked variable, TALOONER_CONFIG_B64:

# talooner.yaml
provider: gitlab
license_key: TLN1....
model:
  base_url: https://dashscope-intl.aliyuncs.com/compatible-mode/v1
  name: qwen3-coder-plus
  api_key: sk-...
gitlab_token: glpat-...
docker run --rm -i registry.gitlab.com/onlinecopyrig-rlr6226/talooner-runner:1 \
  encode-config - < talooner.yaml        # → paste the output into TALOONER_CONFIG_B64

A variable set on its own always overrides the same setting in the file.

Settings

VariableIn talooner.yaml
TALOONER_LICENSE_KEYlicense_keyrequired
TALOONER_PROVIDERprovidergitlab or github — detected in GitLab CI and GitHub Actions
GITLAB_TOKEN / GITHUB_TOKENgitlab_token / github_tokenrequired for the provider
GITLAB_API_URLgitlab_urlself-managed GitLab outside GitLab CI
TALOONER_MODEL_BASE_URL + TALOONER_MODEL_API_KEY + TALOONER_MODELmodel.base_url + model.api_key + model.nameAI review with any LLM behind an OpenAI-compatible API
ANTHROPIC_API_KEYmodel.anthropic_api_keyshortcut for Anthropic; model defaults to claude-sonnet-5-5
OPENAI_API_KEY + TALOONER_MODELmodel.openai_api_key + model.nameshortcut for OpenAI
JEV_URL + JEV_TOKENjev.url + jev.tokenJev triage before the full review
TALOONER_JEV_MIN_CONFIDENCEjev.min_confidenceJev threshold, default 0.9
TALOONER_LOG_LEVELlog_leveldebug prints OpenTalon's own log
TALOONER_METRICS_PUSH_URLmetrics.push_urlpush talooner_* metrics at the end of each job — see below
TALOONER_METRICS_PUSH_TOKENmetrics.push_tokenthe gateway's bearer token — store it masked / as a secret
TALOONER_METRICS_PUSH_JOBmetrics.jobthe job label, default talooner
TALOONER_METRICS_LABELSmetrics.labelsoptional extra labels to filter by in Grafana, e.g. team=payments when several teams share one Prometheus

Metrics with Prometheus and Grafana

Every verdict, action, rule hit and AI review is a talooner_* Prometheus metric. A pipeline job lives for seconds, so Prometheus can't scrape it — instead, each job pushes its metrics once, when it finishes, to a gateway next to your Prometheus.

Push from your pipeline

The job pushes its metrics with the Prometheus Pushgateway protocol to your gateway — prom-aggregation-gateway, which adds up the counters of every job.

GitLab CI — add two variables under Settings → CI/CD → Variables (or once on the group, for every project):

VariableValue
TALOONER_METRICS_PUSH_URLhttps://metrics.acme.dev:9091
TALOONER_METRICS_PUSH_TOKENthe gateway's token — only if it has onemasked, never in .gitlab-ci.yml

The URL can also go in the job; the token always stays a masked variable:

talooner:
  image:
    name: registry.gitlab.com/onlinecopyrig-rlr6226/talooner-runner:1
    entrypoint: [""]
  stage: test
  needs: []
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  variables:
    TALOONER_PROVIDER: gitlab
    GIT_STRATEGY: none
    TALOONER_METRICS_PUSH_URL: https://metrics.acme.dev:9091
    # TALOONER_METRICS_PUSH_TOKEN comes from the masked CI/CD variable
  script:
    - talooner-step

When the review is done, talooner-step pushes once and the job log shows talooner-step: metrics: pushed 23 series to https://metrics.acme.dev:9091. The token is sent as Authorization: Bearer <token>.

GitHub Actions — the same two settings in the step's env: the URL as a repository variable, the token as a secret:

      - uses: docker://registry.gitlab.com/onlinecopyrig-rlr6226/talooner-runner:1
        env:
          TALOONER_PROVIDER: github
          TALOONER_LICENSE_KEY: ${{ secrets.TALOONER_LICENSE_KEY }}
          GITHUB_TOKEN: ${{ github.token }}
          TALOONER_METRICS_PUSH_URL: ${{ vars.TALOONER_METRICS_PUSH_URL }}
          TALOONER_METRICS_PUSH_TOKEN: ${{ secrets.TALOONER_METRICS_PUSH_TOKEN }}

The runner must reach the gateway. The push goes out from the machine that runs the job:

  • Your own runners (self-hosted GitLab runner or GitHub runner) — use the internal address, e.g. http://metrics.internal:9091. Nothing needs to be public.
  • gitlab.com shared runners or GitHub-hosted runners run on the internet, so the gateway needs a public HTTPS address. Put it behind a reverse proxy that checks a bearer token, and store the token as a masked variable or secret, TALOONER_METRICS_PUSH_TOKEN.

Collect it in Prometheus

docker run -d -p 9091:80 ghcr.io/zapier/prom-aggregation-gateway:latest
# prometheus.yml
scrape_configs:
  - job_name: talooner
    honor_labels: true          # keep the repo / provider labels Talooner sets
    static_configs:
      - targets: ["metrics.internal:9091"]

Import the dashboard into Grafana (Dashboards → New → Import) — download talooner-dashboard.json, or print the one that matches your image:

docker run --rm registry.gitlab.com/onlinecopyrig-rlr6226/talooner-runner:1 \
  dashboard > talooner-dashboard.json

What you get

Metric
talooner_pr_evaluations_total{repo, verdict}reviews by verdict — approve, block, none
talooner_pr_actions_total{verb}what the rules did: approve, block, route, comment…
talooner_pr_rules_firedrules that fired per review (histogram)
talooner_pr_evaluation_duration_secondshow long a review took (histogram)
talooner_llm_reviews_total{result}AI reviews: match, mismatch, unclear, triage hits…
talooner_pr_warnings_total{code}ruleset health warnings

Each series also carries repo, provider and pipeline_source, plus your own TALOONER_METRICS_LABELS. The dashboard shows the auto-approval and needs-a-human rates, the verdict mix over time, latency, top repositories, AI review outcomes and warnings — watch the auto-approval rate climb as you tune the rules:

sum(rate(talooner_pr_evaluations_total{verdict="approve"}[1d]))
  / sum(rate(talooner_pr_evaluations_total[1d]))

A push that fails — gateway down, wrong URL — is logged as a warning and never fails the job.

What leaves your pipeline

  • Calls to your forge's API.
  • Calls to your own LLM provider — only where a rule asks for llm_review.
  • Metrics to your own gateway, if you set one — counts, verdicts and repository names.
  • One license check to us: the key, a nonce and the version.

Never code, repositories or PR data to us.

Each job verifies the license online before it reviews. If the license is revoked or expired, or the license server can't be reached, Talooner posts a "license inactive" check run and comment — and the job still succeeds, so it never blocks your merges.

Works with

Forges

GitLab
GitHub

CI

GitLab CI
GitHub Actions
Jenkins
CircleCI
Buildkite
Drone
TeamCity
Any CI with Docker

Models

Anthropic
OpenAI
OpenAI-compatible
TypeSafe / Jev

Need a license key?

Start a free demo