# Provider Detection in Council of High Intelligence: How scripts/detect-providers.sh Identifies LLM Backends

> Learn how scripts/detect-providers.sh in Council of High Intelligence automatically detects LLM backends. It checks binaries, env variables, and API reachability for dynamic selection.

- Repository: [nyk/council-of-high-intelligence](https://github.com/0xNyk/council-of-high-intelligence)
- Tags: how-to-guide
- Published: 2026-06-30

---

**The [`detect-providers.sh`](https://github.com/0xNyk/council-of-high-intelligence/blob/main/detect-providers.sh) script performs automated provider detection across six large language model backends by inspecting binary availability, environment variables, and API reachability, then emits a structured JSON summary enabling dynamic backend selection.**

The Council of High Intelligence repository utilizes [`scripts/detect-providers.sh`](https://github.com/0xNyk/council-of-high-intelligence/blob/main/scripts/detect-providers.sh) as its core provider detection utility to determine which LLM providers are accessible on the host system without manual configuration. This self-contained Bash script inspects the runtime environment for Anthropic, OpenAI, Google, Ollama, Cursor, and NVIDIA NIM installations, allowing downstream automation to adaptively route requests to available backends.

## Supported LLM Providers and Detection Methods

The script implements distinct detection logic for each provider, ranging from native runtime assumptions to binary presence checks and environment variable validation.

### Anthropic (Native Subagent)

Anthropic is **assumed always present** because it runs directly in the host runtime without requiring external binaries. The script sets `available` to `true` unconditionally and assigns the `exec_method` value of `subagent`. The hardcoded model list includes `"opus"`, `"sonnet"`, and `"haiku"`.

### OpenAI Codex CLI

Detection requires the `codex` binary to be present in `$PATH`. The script uses `check_command` (a wrapper around `command -v`) to locate the binary, then verifies functionality by executing `codex --version` within a timeout window. If successful, the provider receives `exec_method: "codex_exec"` and reports model `"gpt-5.4"`.

### Google Gemini CLI

Similar to OpenAI, this provider detection searches for the `gemini` binary and validates it via `gemini --version`. The `exec_method` is set to `"gemini_cli"` with the model `"gemini-2.5-pro"`.

### Ollama Local Models

The script checks for the `ollama` binary and actively queries the local server by running `ollama list` through the timeout wrapper. If the server responds, the script dynamically extracts up to five model names from the output rather than using hardcoded values. The `exec_method` is `"ollama_run"`.

### Cursor Agent CLI

Detection looks for the `cursor-agent` binary and verifies it with `cursor-agent --version`. When present, the script reports a hardcoded cross-family model list: `"gpt-5.4-high"`, `"claude-opus-4-7-thinking-high"`, `"gemini-2.5-pro"`, and `"grok-4"`. The execution method is `"cursor_cli"`.

### NVIDIA NIM

This provider requires the environment variable `NVIDIA_API_KEY` to start with the prefix `nvapi-`. If present, the script optionally performs a reachability test of the NVIDIA endpoint using `curl`. The `exec_method` is `"openai_compatible_api"` and includes models such as `"deepseek-ai/deepseek-v4-pro"`, `"moonshotai/kimi-k2.6"`, `"minimaxai/minimax-m2.7"`, `"z-ai/glm-5.1"`, and `"qwen/qwen3.5-397b-a17b"`.

## JSON Output Structure

The script aggregates detection results into a standardized JSON object printed to `stdout`. The schema includes:

```json
{
  "providers": [
    {
      "name": "anthropic",
      "available": true,
      "exec_method": "subagent",
      "binary": "native",
      "models": ["opus", "sonnet", "haiku"]
    }
  ],
  "provider_count": 3,
  "multi_provider": true
}

```

Each provider object contains the `name`, `available` boolean, `exec_method` string, `binary` path (or `"not_found"`), and `models` array. The root object includes `provider_count` (integer) and `multi_provider` (boolean, true when two or more providers are available).

## Core Implementation Details

All detection logic resides in [`scripts/detect-providers.sh`](https://github.com/0xNyk/council-of-high-intelligence/blob/main/scripts/detect-providers.sh) using portable Bash helpers.

The **`check_command`** function wraps `command -v` to safely locate binaries without throwing errors. The **`run_with_timeout`** function provides a macOS-compatible Perl timeout wrapper that caps each external call to `TIMEOUT_SECONDS` (defaulting to 5 seconds), preventing hangs during version checks.

The **`json_provider`** function formats individual provider entries consistently, ensuring valid JSON output even when binaries are missing. A final loop assembles the array and computes the availability metrics (source lines 12-40, 45-87, 90-113, 115-139).

## Practical Usage Examples

### Running Basic Detection

Execute the script directly to retrieve the full provider inventory:

```bash
$ ./scripts/detect-providers.sh | jq .

```

### Filtering Available Providers

Extract only the names of providers ready for use:

```bash
available=$(./scripts/detect-providers.sh | \
  jq -r '.providers[] | select(.available) | .name')
echo "Ready providers: $available"

```

### Conditional Backend Selection

Use the JSON output to implement fallback logic in automation scripts:

```bash
detect=$(./scripts/detect-providers.sh)

if echo "$detect" | jq -e '.providers[] | select(.name=="ollama" and .available)' > /dev/null; then
    ./run-ollama.sh
elif echo "$detect" | jq -e '.providers[] | select(.name=="openai" and .available)' > /dev/null; then
    ./run-openai.sh
else
    echo "No suitable LLM provider detected."
    exit 1
fi

```

## Summary

- **[`scripts/detect-providers.sh`](https://github.com/0xNyk/council-of-high-intelligence/blob/main/scripts/detect-providers.sh)** inspects six LLM providers using binary checks, environment variables, and API reachability tests.
- Detection includes Anthropic (always available), OpenAI Codex, Google Gemini, Ollama, Cursor, and NVIDIA NIM.
- The script outputs structured JSON with provider metadata, availability flags, execution methods, and model lists.
- A `multi_provider` flag indicates when two or more backends are present, enabling redundancy strategies.
- All external commands are wrapped in a 5-second timeout to prevent blocking operations.

## Frequently Asked Questions

### How does the script handle timeouts when checking external binaries?

The script uses a `run_with_timeout` function implemented with Perl that is compatible with macOS and Linux. Each external call such as `codex --version` or `ollama list` is capped at `TIMEOUT_SECONDS` (default 5 seconds), ensuring the detection process completes even if a binary hangs or the Ollama server is unresponsive.

### Can I use detect-providers.sh outside of the Council of High Intelligence repository?

Yes, the script is self-contained and requires only standard Unix utilities (`command`, `curl`, `perl`) and optionally `jq` for parsing output. It performs no hard dependencies on other repository files, making it suitable for standalone use in other projects requiring LLM provider detection.

### What happens if no providers are detected?

The script always returns valid JSON with an empty `providers` array, `provider_count: 0`, and `multi_provider: false`. It exits with status 0 regardless of detection results, leaving error handling and fallback logic to downstream consumers.

### Why does Ollama use dynamic model detection while other providers use hardcoded lists?

Ollama serves local models that vary by user installation, so the script parses the output of `ollama list` to discover up to five available models dynamically. Other providers (OpenAI, Google, Cursor, NVIDIA) expose fixed model catalogs through their APIs or CLIs, making hardcoded lists sufficient for capability advertisement.