rig 0.42.0

An opinionated library for building LLM powered applications.
Documentation
# The full `--all-features` test suite, split out of the PR gate (ci.yaml).
#
# What runs only here and not on the PR gate:
#   * the Docker-backed vector-store integration tests in `tests/integrations/`
#     (lancedb, mongodb, neo4j, postgres, qdrant, scylladb — plus the
#     no-container sqlite and vectorize suites), the only runtime coverage the
#     companion crates' `VectorStoreIndex` implementations have;
#   * `tests/tool_facade_features.rs` (`facade-build-tests`), the slow
#     nested-`cargo check` facade build guard;
#   * the `image`-feature generation smoke tests (gemini nano-banana, xai);
#   * every root test binary's `--all-features` configuration — the PR gate
#     runs the default feature set plus `bedrock`.
#
# The PR gate still COMPILES all of the above on every PR: ci.yaml's clippy
# job lints `--all-features --all-targets`, and doctest/doc build all
# features, so a nightly failure is almost always a runtime regression rather
# than a stale compile break discovered at 06:00 — with one deliberate
# exception. `tests/tool_facade_features.rs` nested-checks the facade in
# *individual* feature configurations, and feature-unification means no
# `--all-features` build on the gate can catch a facade feature that forgets
# to forward a sub-feature, so that one class of compile break is caught only
# here (it costs ~4 minutes, which is exactly why it is not on the gate).
#
# When it runs:
#   * nightly at 06:00 UTC;
#   * on any PR that touches a companion crate, the integration tests, or the
#     root manifest/lockfile (where the companion crates' `workspace = true`
#     dependency versions actually resolve) — without this, a PR editing
#     `crates/rig-qdrant/` or bumping its driver in Cargo.toml merges with
#     zero runtime coverage of the code it changed, and the breakage surfaces
#     either at 06:00 or, worse, in cd.yaml's `run-full-ci`, where it blocks
#     release-plz on an already-merged commit. These PRs share the scheduled
#     run's rust-cache entry, so the common PR pays nothing;
#   * in the merge queue (`merge_group`), because the squashed batch that
#     actually lands on main is not any PR head the filters above validated;
#   * on demand via `gh workflow run nightly.yaml`;
#   * via `workflow_call` from cd.yaml on every push to main, so release-plz
#     never publishes a commit the full suite has not passed.
name: Nightly Full Test

on:
  schedule:
    - cron: "0 6 * * *"
  # Exactly the crates that `tests/integrations/` actually exercises. Other
  # companion crates (rig-milvus, rig-surrealdb, rig-helixdb, …) are omitted
  # deliberately: they have no suite here, so triggering this lane on them
  # would cost 20+ minutes and run nothing that covers the changed code.
  pull_request:
    paths:
      - "crates/rig-lancedb/**"
      - "crates/rig-mongodb/**"
      - "crates/rig-neo4j/**"
      - "crates/rig-postgres/**"
      - "crates/rig-qdrant/**"
      - "crates/rig-scylladb/**"
      - "crates/rig-sqlite/**"
      - "crates/rig-vectorize/**"
      - "tests/integrations/**"
      - "tests/integrations.rs"
      # The facade feature-forwarding guard is the one test whose failure
      # class (a facade feature forgetting a sub-feature, invisible to any
      # `--all-features` build — see the header) nothing on the PR gate can
      # catch, so a PR that edits it must run it.
      - "tests/tool_facade_features.rs"
      - ".github/workflows/nightly.yaml"
      # The companion crates' dependency versions do not live under
      # `crates/rig-*/`: they are `workspace = true` references resolved in
      # the root manifest and lockfile. Without these two entries, a
      # dependabot PR bumping mongodb/neo4rs/qdrant-client/lancedb touches
      # only Cargo.toml + Cargo.lock, matches none of the globs above, and
      # merges with zero integration-test coverage of the driver it changed —
      # the exact failure mode this trigger exists to prevent. The cost is
      # accepted: any PR that touches the root manifest or lockfile runs the
      # full lane, because dependency changes are precisely the risk class
      # this suite covers. (`crates/rig-core/**` is deliberately NOT listed:
      # most PRs touch rig-core, and triggering the full lane on all of them
      # would undo the fast/full split; a rig-core change that breaks a
      # vector-store contract is caught by merge_group below at the latest.)
      - "Cargo.toml"
      - "Cargo.lock"
      - "crates/*/Cargo.toml"
      - "scripts/check-dependency-floors.py"
  # The repo merges through a merge queue (ALLGREEN, squash, batches up to
  # 5), so the commit that actually lands on main is the merge-group commit —
  # not the PR head that the `pull_request` triggers above validated. Without
  # this trigger, a companion-crate PR could go green on its head, get
  # batched with other queued PRs, and land a combination the full suite
  # never ran on, surfacing post-merge in cd.yaml where it blocks release-plz
  # (the pre-split workflow ran the full sweep under merge_group, so this
  # restores that guarantee). GitHub does not support `paths` filters on
  # merge_group events, so every queued merge pays the full lane — accepted:
  # the queue batches PRs, which amortizes the cost across everything in the
  # batch.
  merge_group:
  workflow_dispatch: # cd.yaml already uses this; match it
  workflow_call:

# The toolchain and the cache-fingerprint env (debuginfo trim,
# CARGO_INCREMENTAL) come from .github/actions/rust-setup, the same single
# source ci.yaml uses — which is what actually guarantees the two lanes
# share build fingerprints instead of a comment asking copies to stay
# identical.
env:
  CARGO_TERM_COLOR: always

# The `full-` prefix keeps this group disjoint from ci.yaml's when both are
# invoked from the same cd.yaml run (inside a called workflow,
# `github.workflow` resolves to the CALLER's name). Keyed on the PR number
# rather than `head_ref` because two forks PRing from identically-named
# branches share a head_ref — under the old key they cancelled each other's
# runs.
concurrency:
  group: full-${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
  cancel-in-progress: true

jobs:
  test-all-features:
    name: stable / test all features
    runs-on: ubuntu-latest
    # `schedule` fires on any fork whose owner has enabled Actions, against
    # the fork's default branch — so without this guard every fork owner gets
    # a daily 06:00 run (Docker pulls and a full workspace build) for a suite
    # they did not ask for. Fork *PRs* into this repo are unaffected:
    # `github.repository` is the upstream repo there, and the suite is fully
    # hermetic — cassettes replay with a dummy key, the vector-store tests
    # stub their embeddings with `api_key("TEST")`, and no job receives
    # provider secrets anywhere in CI.
    #
    # This also covers the `workflow_call` path, where `github.repository` is
    # still the caller's repo — a fork's own cd.yaml skips this job and, with
    # it, its release-plz step, which is the correct outcome on a fork.
    if: github.repository == '0xPlaygrounds/rig'
    steps:
      - name: Checkout
        uses: actions/checkout@v5

      # protoc: required because this all-features lane enables rig-lancedb
      # and the facade's feature-gated raw lancedb test dependency.
      #
      # No sccache: the all-features sweep mints by far the most
      # per-compilation-unit cache entries, this lane is not
      # latency-critical, and the repo's 10GB Actions cache quota is
      # contended — see the sccache input's note in the rust-setup action.
      - name: Install Rust stable
        uses: ./.github/actions/rust-setup
        with:
          nextest: "true"
          protoc: "true"

      # The workspace-wide sweep over every feature. This is the step that
      # was ci.yaml's `Test with latest nextest release` before the fast/full
      # split narrowed that one to `--features bedrock`. No provider API keys
      # here or anywhere in CI: everything that executes is hermetic (see
      # ci.yaml's sweep-step note), and recording new cassettes is a local,
      # human activity.
      #
      # A plain `run:` rather than `actions-rs/cargo@v1`: that action was
      # archived in 2023 and pins Node 20.
      - name: Test with all features
        run: cargo nextest run --locked --all-features --retries 2

  # The declared dependency requirements are floors, not pins (`tokio = "1"`
  # is `^1`), and a downstream resolves anywhere inside them — usually to
  # whatever its own lockfile already holds. So rig has to actually build at
  # the lowest version it declares, or the floor is a lie that surfaces as a
  # build break in someone else's tree (#2195). Cargo's `-Zdirect-minimal-
  # versions` is nightly-only and dead-ends in this workspace's transitive
  # graph, so `scripts/check-dependency-floors.py` does the equivalent on
  # stable: `cargo update --precise` every direct dependency down to the
  # lowest version the tree admits, then `cargo check --workspace
  # --all-features --all-targets`. It runs here rather than on the PR gate
  # because it is a full all-features build; the `pull_request` paths above
  # still run it on every PR that touches a manifest, the lockfile, or the
  # script itself, which is where a floor can silently rot (a PR that starts
  # using an API newer than the declared floor).
  dependency-floors:
    name: stable / dependency floors
    runs-on: ubuntu-latest
    if: github.repository == '0xPlaygrounds/rig'
    steps:
      - name: Checkout
        uses: actions/checkout@v5

      - name: Install Rust stable
        uses: ./.github/actions/rust-setup
        with:
          protoc: "true"

      - name: Build against the declared dependency floors
        run: python3 scripts/check-dependency-floors.py