Add random backend-selection strategy for virtual provider LLM agents #156

Closed
opened 2026-10-15 18:37:07 +00:00 by CoreRasurae · 0 comments
Member

Metadata

Commit Message: feat(agents): add random backend-selection strategy for virtual provider LLM agents

Branch: feature/m1-virtual-provider-random-strategy

Background and context

Part of the virtual-provider Epic #154, extending the backends/strategy
configuration and round-robin routing introduced in #155. Design is recorded
in docs/adr/ADR-2038-virtual-provider-load-balanced-backend-routing.md.
This issue adds the second load-balancing strategy requested for the virtual
provider: uniformly random backend selection per invocation.

Current behavior

agents.<name>.config for type: llm accepts backends/strategy, but
strategy only accepts "round_robin"; any other value raises a
ConfigurationError. There is no random-selection implementation.

Expected behavior

  • strategy: random is accepted by the backends/strategy validation.
  • With strategy: random, each invocation selects a backend from the
    configured backends list uniformly at random, via Python's random
    module, and forwards the call/response unmodified — identical
    selection-and-forward semantics to round_robin, differing only in how
    the backend index is chosen.
  • All non-goals and non-regression guarantees established by #155 continue
    to hold unchanged (no retry/failover, byte-identical behavior when
    backends is absent, full conversation context sent on every turn
    regardless of which backend handles it).

Acceptance criteria

  • strategy: random constructs successfully (no longer rejected).
  • Over a large number of invocations of an agent configured with strategy: random and N backends, every configured backend is selected at least once
    (statistical coverage, not exact ordering — this is what distinguishes it
    from round_robin).
  • strategy values other than "round_robin" and "random" still raise a
    ConfigurationError naming the unsupported value.
  • The random-based selection carries a # nosec-style justification
    comment addressing the expected low-severity bandit B311 finding
    (standard pseudo-random generators unsuitable for security/cryptographic
    purposes) — this use is a capacity-distribution concern, not a security
    boundary.
  • Any error raised by the selected backend's underlying chat-model call
    propagates to the caller unmodified — it is not retried against another
    backend or swallowed.
  • All acceptance criteria of #155 (minimum backend count, required
    per-backend credentials, provider/model defaulting, credential isolation,
    non-regression when backends is absent) continue to pass unchanged.

Supporting information

  • ADR: docs/adr/ADR-2038-virtual-provider-load-balanced-backend-routing.md
  • Epic: #154
  • Depends on: #155 (backends/strategy configuration and round-robin routing)
  • Parent Legendary: #9

Subtasks

  • Extend the strategy validation to accept "random"
  • Implement RandomStrategy (the SelectionStrategy implementation
    introduced in #155) using Python's random module, with a
    # nosec-style justification comment for the expected low-severity
    bandit finding
  • Wire strategy: random into the existing virtual-provider wrapper
    from #155
  • Update docs/index.md §4.4.7 to document the random strategy value
  • Tests (Behave): random strategy selects among all configured backends
    over repeated invocations; non-regression for round_robin and for
    agents without backends
  • Tests (Robot): integration test exercising strategy: random through
    the library API
  • Verify coverage >= 97% via nox -s coverage_report
  • Run nox (all default sessions), fix any errors

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • A Git commit is created where the first line matches the Commit Message
    in Metadata exactly.
  • The commit is pushed to the branch matching the Branch in Metadata
    exactly.
  • The commit is submitted as a PR to master, reviewed, and merged.
## Metadata **Commit Message:** feat(agents): add random backend-selection strategy for virtual provider LLM agents **Branch:** feature/m1-virtual-provider-random-strategy ## Background and context Part of the virtual-provider Epic #154, extending the `backends`/`strategy` configuration and round-robin routing introduced in #155. Design is recorded in `docs/adr/ADR-2038-virtual-provider-load-balanced-backend-routing.md`. This issue adds the second load-balancing strategy requested for the virtual provider: uniformly random backend selection per invocation. ## Current behavior `agents.<name>.config` for `type: llm` accepts `backends`/`strategy`, but `strategy` only accepts `"round_robin"`; any other value raises a `ConfigurationError`. There is no random-selection implementation. ## Expected behavior - `strategy: random` is accepted by the backends/strategy validation. - With `strategy: random`, each invocation selects a backend from the configured `backends` list uniformly at random, via Python's `random` module, and forwards the call/response unmodified — identical selection-and-forward semantics to `round_robin`, differing only in how the backend index is chosen. - All non-goals and non-regression guarantees established by #155 continue to hold unchanged (no retry/failover, byte-identical behavior when `backends` is absent, full conversation context sent on every turn regardless of which backend handles it). ## Acceptance criteria - `strategy: random` constructs successfully (no longer rejected). - Over a large number of invocations of an agent configured with `strategy: random` and N backends, every configured backend is selected at least once (statistical coverage, not exact ordering — this is what distinguishes it from `round_robin`). - `strategy` values other than `"round_robin"` and `"random"` still raise a `ConfigurationError` naming the unsupported value. - The `random`-based selection carries a `# nosec`-style justification comment addressing the expected low-severity bandit `B311` finding (standard pseudo-random generators unsuitable for security/cryptographic purposes) — this use is a capacity-distribution concern, not a security boundary. - Any error raised by the selected backend's underlying chat-model call propagates to the caller unmodified — it is not retried against another backend or swallowed. - All acceptance criteria of #155 (minimum backend count, required per-backend credentials, provider/model defaulting, credential isolation, non-regression when `backends` is absent) continue to pass unchanged. ## Supporting information - ADR: `docs/adr/ADR-2038-virtual-provider-load-balanced-backend-routing.md` - Epic: #154 - Depends on: #155 (backends/strategy configuration and round-robin routing) - Parent Legendary: #9 ## Subtasks - [ ] Extend the `strategy` validation to accept `"random"` - [ ] Implement `RandomStrategy` (the `SelectionStrategy` implementation introduced in #155) using Python's `random` module, with a `# nosec`-style justification comment for the expected low-severity bandit finding - [ ] Wire `strategy: random` into the existing virtual-provider wrapper from #155 - [ ] Update `docs/index.md` §4.4.7 to document the `random` strategy value - [ ] Tests (Behave): random strategy selects among all configured backends over repeated invocations; non-regression for `round_robin` and for agents without `backends` - [ ] Tests (Robot): integration test exercising `strategy: random` through the library API - [ ] Verify coverage >= 97% via `nox -s coverage_report` - [ ] Run `nox` (all default sessions), fix any errors ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - A Git commit is created where the first line matches the Commit Message in Metadata exactly. - The commit is pushed to the branch matching the Branch in Metadata exactly. - The commit is submitted as a PR to master, reviewed, and merged.
CoreRasurae added this to the v2.1.0 milestone 2026-10-19 21:40:50 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
cleveragents/cleveractors-core#156
No description provided.