Files
t3mp3st/.env.example
T
2alfandJoseph Magly 8ccea7c82a feat(llm): add Hugging Face provider + selectable local Claude Code models (#127)
* feat(llm): add Hugging Face provider + selectable local Claude Code models

Adds two operator-selectable LLM backbones, wired through both the backend
and the War Room UI.

Hugging Face (OpenAI-compatible Inference Providers router):
- New `huggingface` provider reusing OpenAIAdapter (router.huggingface.co/v1)
- HF_TOKEN / HUGGINGFACE_API_KEY / HUGGINGFACE_TOKEN env resolution, config,
  setup wizard, CLI, factory, best-available, and .env.example
- Settings key card + 4 inference models in the picker + direct client routing
- Tests: src/__tests__/huggingface-provider.test.ts

Local Claude from Claude Code:
- Explicit "active backbone" pin in Settings so a connected agent (Claude Code)
  can be chosen; a pin outranks stored API keys in both the client resolver and
  mission dispatch
- Claude Code model picker (Account default / Opus / Sonnet / Haiku), threaded
  to the CLI's --model via an "agentId::model" encoding parsed by LocalAgentAdapter;
  requireLiveLocalAgent strips the suffix for connected-agent validation

* fix(llm): address PR #127 review — self-contained keyless path + centralized pin/model routing

Finding 1 — keyless mission path was not self-contained:
- Add the `local-agent` case to ConfigManager.getLLMConfig so provider:'local-agent'
  resolves (keyless, agent id — optionally "agentId::model" — in `model`) instead of
  hitting the default "Unknown provider" throw.

Finding 2 — inconsistent pin/model routing across dispatch surfaces:
- Centralize backend agent resolution in window.t3mpDispatchAgent (single source of truth).
  It honors an explicit pin OVER a stored API key and encodes the picked local model as
  "agentId::model" so it is never dropped.
- Route all three surfaces through it: mission dispatch, General (getGeneralConfig), and
  Admiral (_admBackbone). Previously General/Admiral only picked an agent when no key
  existed and sent the bare agent id, so a stored key overrode the pin and the selected
  Claude model was lost.

Tests:
- getLLMConfig('local-agent') regression coverage (self-contained keyless path)
- LocalAgentAdapter "agentId::model" passthrough reaches the CLI --model flag
- t3mpDispatchAgent behavior: pin>key precedence, model encoding, fallbacks (evaluated
  from the shipped docs/index.html)
- centralization invariant: mission/General/Admiral all route through t3mpDispatchAgent
- update the Op-Admiral keyless-routing static test to the centralized resolver

---------

Co-authored-by: Joseph Magly <1159087+jmagly@users.noreply.github.com>
2026-07-27 15:47:06 -04:00

36 lines
1.6 KiB
Bash

# T3MP3ST environment — copy to `.env` and fill in. NEVER commit your real .env.
# At least one LLM provider key is required (OpenRouter is the default backbone).
# ── LLM providers (set the one(s) you use) ──
OPENROUTER_API_KEY=sk-or-v1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
VENICE_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Hugging Face — open models via the OpenAI-compatible Inference Providers router.
# HF_TOKEN is canonical; HUGGINGFACE_API_KEY / HUGGINGFACE_TOKEN also work.
HF_TOKEN=hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
GROQ_API_KEY=
TOGETHER_API_KEY=
REPLICATE_API_TOKEN=
# ── Target authentication (both values are required) ──
# Exact origin that may receive the configured headers (scheme + host + optional port).
# TEMPEST_TARGET_ORIGIN=https://target.example
# JSON object of headers injected into HTTP requests to that exact origin.
# Explicit per-request headers override these defaults case-insensitively.
# Bearer token: TEMPEST_TARGET_HEADERS={"Authorization":"Bearer eyJhbGc..."}
# Cookie: TEMPEST_TARGET_HEADERS={"Cookie":"session=abc123"}
# Multiple: TEMPEST_TARGET_HEADERS={"Authorization":"Bearer token","X-Tenant":"acme"}
# TEMPEST_TARGET_HEADERS=
# ── GitHub (xbow-bench challenge fetch / gh operations) ──
GITHUB_TOKEN=
# ── optional: default backbone overrides ──
# LLM_PROVIDER=openrouter
# LLM_MODEL=claude-opus-4-8
# Optional: Venice uncensored inference (OpenAI-compatible). https://venice.ai
VENICE_API_KEY=