- On a Claude Code session/usage limit ('resets 7:10pm'), _call_claude_cli now
pauses IN PLACE until the stated reset time + CLAUDE_CLI_LIMIT_BUFFER_SECONDS
(default 60s past), then retries — up to CLAUDE_CLI_LIMIT_MAX_WAITS windows.
Parses 12-hour reset times to their next occurrence; falls back to a fixed
wait when no time is present. Makes long unattended runs survive reset windows.
- load_library() reports invalid capability-set JSON as a clean SystemExit
(line number + reason) instead of a traceback; fixed a trailing-comma typo in
data/capability_sets/dx02.json.
- Docs: USAGE.md + .env.example document the claude-cli provider and its knobs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
67 lines
2.6 KiB
Plaintext
67 lines
2.6 KiB
Plaintext
# Copy to .env and fill in.
|
|
|
|
# --- LLM provider ---
|
|
# LLM_PROVIDER: claude-cli | anthropic | openai | gemini.
|
|
# claude-cli = run inference through Claude Code headless mode (`claude -p`),
|
|
# the sanctioned way to use a Claude subscription programmatically.
|
|
# (Direct-API calls with a Claude Code OAuth token are policy-blocked.)
|
|
LLM_PROVIDER=claude-cli
|
|
CLAUDE_CLI_MODEL=sonnet
|
|
CLAUDE_CLI_TIMEOUT=300
|
|
# On a session-limit hit ("resets 7:10pm"), pause until reset + buffer, then retry:
|
|
CLAUDE_CLI_LIMIT_BUFFER_SECONDS=60
|
|
CLAUDE_CLI_LIMIT_MAX_WAITS=6
|
|
CLAUDE_CLI_LIMIT_FALLBACK_WAIT_SECONDS=3600
|
|
|
|
# Direct Anthropic API (real API key) — use LLM_PROVIDER=anthropic:
|
|
LLM_MODEL=claude-sonnet-5
|
|
ANTHROPIC_EFFORT=low # low | medium | high | max
|
|
ANTHROPIC_USE_KEYCHAIN=1
|
|
# ANTHROPIC_OAUTH_TOKEN=
|
|
# ANTHROPIC_API_KEY=
|
|
|
|
# OpenAI-compatible endpoint — works with OpenAI, OpenRouter, Together, Groq,
|
|
# vLLM, Ollama, LM Studio, etc. Just point these three at any /chat/completions API:
|
|
OPENAI_BASE_URL=https://api.openai.com/v1
|
|
OPENAI_API_KEY=
|
|
OPENAI_MODEL=gpt-4o-mini
|
|
OPENAI_JSON_MODE=1 # set 0 if the endpoint rejects response_format=json_object
|
|
|
|
# There is NO mock fallback. On HTTP 429 the loop WAITS this long and retries
|
|
# (honors Retry-After if present), so it grinds through tight rate limits.
|
|
LLM_RATELIMIT_WAIT_SECONDS=900
|
|
LLM_RATELIMIT_MAX_RETRIES=24
|
|
|
|
# Other providers:
|
|
GEMINI_API_KEY=
|
|
GEMINI_MODEL=gemini-2.5-flash
|
|
|
|
# --- SEC EDGAR filings harvester (free, no key; public accounts auto-matched) ---
|
|
SEC_ENABLED=1
|
|
SEC_MAX_FILINGS_PER_ACCOUNT=5
|
|
|
|
# Scoring thresholds (design Phase 5)
|
|
PRIORITY_THRESHOLD=0.72
|
|
STANDARD_THRESHOLD=0.45
|
|
|
|
# --- Exa.ai news/web harvester ---
|
|
# Without a key, the news connector falls back to data/fixtures.json.
|
|
EXA_API_KEY=
|
|
EXA_ENABLED=1
|
|
# Hard ceilings to stay inside the free plan (~20,000 req/month). The connector
|
|
# refuses to call Exa once either cap is reached. Monthly count persists in
|
|
# output/state/exa_usage.json and resets at the start of each calendar month.
|
|
EXA_MONTHLY_REQUEST_CAP=1000
|
|
EXA_PER_RUN_REQUEST_CAP=25
|
|
EXA_RESULTS_PER_QUERY=5
|
|
EXA_LOOKBACK_DAYS=45
|
|
# Exa content category. "news" keeps out careers/marketing landing pages — the
|
|
# biggest signal-quality lever. "" disables category filtering.
|
|
EXA_CATEGORY=news
|
|
# Scope to the account's own domain (1) or broad-web news about it (0, default).
|
|
# With category=news, broad web finds actual coverage; domain scoping finds the
|
|
# company's own newsroom. Override per run: loop --no-domain-filter / --domain-filter
|
|
EXA_DOMAIN_FILTER=0
|
|
# Hosts to always exclude (comma-separated), e.g. talent.example.com,careers.example.com
|
|
EXA_EXCLUDE_DOMAINS=
|