Commit graph

11 commits

Author SHA1 Message Date
Viktor Barzin
1132777705 openai-compat: use bare model aliases (haiku/sonnet/opus) to auto-roll forward
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2026-06-01 19:55:19 +00:00
Viktor Barzin
7baa66d994 openai-compat: pass --model from request through to claude -p
Replaces the MODEL_TO_AGENT dict (which only mapped model -> agent and
ignored the model itself) with a SUPPORTED_MODELS allowlist + per-request
--model CLI flag. Callers can now pick Haiku/Sonnet/Opus per request to
control cost; unknown model IDs 400 with the supported list; missing
model defaults to claude-sonnet-4-6 (mid-tier).

The --model CLI flag overrides whatever model: is in the agent's
frontmatter, so recruiter-triage's `model: sonnet` no longer pins
every request to Sonnet.

Verified with claude CLI 2.1.153 that the bare-form IDs
(claude-haiku-4-5, claude-sonnet-4-6, claude-opus-4-7) are accepted
without date suffixes — confirmed via modelUsage keys in the JSON
output.

Six new tests cover: default routing, haiku/sonnet/opus pass-through,
unsupported-model 400 shape, and the response.model echo.
2026-06-01 19:33:54 +00:00
Viktor Barzin
07dcfca333 openai-compat: add /v1/chat/completions endpoint
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
OpenAI-compatible chat completions endpoint so existing OpenAI-API
clients (fire-planner's examples/llm_extract.py and others) can target
this service without rewriting their client.

Behaviour:
- POST /v1/chat/completions accepts the OpenAI chat-completions request
  shape (model, messages, max_tokens?, temperature?, stream?).
- Reuses the existing Bearer auth from /execute.
- Synthesises a single prompt body from system+user messages
  ("System instructions:\n... --- Request:\n...") so the agent treats
  them as the user's request rather than seeing raw JSON.
- Internally shares the execution path with /execute by extracting
  _invoke_claude_subprocess(). Holds execution_lock for the duration;
  returns 503 (not 409) when busy, since OpenAI callers have no
  job-id model to retry against.
- Returns the OpenAI chat-completions envelope with the final
  assistant text extracted from `claude -p --output-format json`
  (falls back to raw stdout if parsing fails).
- stream=true -> 400 {"error": "streaming not supported"}.
- Underlying failure (non-zero exit, timeout, exception) -> 503
  {"error": "execution failed", "detail": "<one line>"}.

Model -> agent mapping is hardcoded to `recruiter-triage` for all
models for v1 (broadest tool surface among current agents). Budget
is hardcoded to $2.00/call; timeout 900s. Revisit when a true
general-purpose agent lands.

Tests: 9 new tests covering happy path, streaming rejection, missing
auth, wrong token, job failure, empty messages, JSON-parse fallback,
prompt synthesis, and busy-503. All 20 tests (11 existing + 9 new)
pass; ruff clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 06:24:20 +00:00
191ed5dd87 recruiter-triage: AI culture & tooling section in deep research
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
New section between Remote and Perks. Covers:
- Leadership stance (last-12mo public statements on internal AI use)
- Approved tools (Cursor / Copilot / Claude Code / ChatGPT Enterprise
  / internal LLM gateway)
- Per-seat usage limits, quotas, model whitelist/blacklist, DLP
  blocks on source-to-external-models
- Code-gen safety policy (review of AI-generated code, disclosure)
- Whether the company ships AI features and at what depth
- If the web is silent: explicit follow-up questions to ask the
  recruiter in writing

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 13:04:57 +00:00
f764fef642 recruiter-triage: add Perks & office life section (food/health/pension/leave/etc)
New mandatory block in the markdown output template between Remote and
Recent news. Covers: meals (free vs stipend vs none), health (medical
dental mental), pension contribution %, equity refresh cadence,
PTO/sabbatical/parental, equipment + WFH stipend, learning budget,
gym/wellness, office amenities (game room, rooftop, pet-friendly, EV
charging), commuter benefits.

Bumped word cap 800→1200 to fit the new section. Agent system prompt
explicitly says 'say not found' rather than guess for sub-items.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 12:00:04 +00:00
1b3350c0ac claude-agent-service: add recruiter-triage agent
Web-first deep-research agent that recruiter-responder calls on demand.
Output is a structured markdown report (≤800 words): comp vs Viktor's
£600k floor, culture/retention signals, remote policy, recent news,
bottom-line verdict. No DB writes, no phone-call suggestions, no file
writes. Tools: WebSearch, WebFetch, Read, Grep, Glob, Bash (read-only
use).

Wired through Dockerfile (COPY to /usr/share/agent-seed/) and the
seed-beads-agent init container in infra/stacks/claude-agent-service/
(cp into /home/agent/.claude/agents/recruiter-triage.md).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 11:40:13 +00:00
Viktor Barzin
bab6dd2506 [ci] Dockerfile: download Vault CLI at build time instead of COPY
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
The 495MB vault binary is in .gitignore so it doesn't ship to
Forgejo, breaking 'COPY vault /usr/local/bin/vault'. Switch to
the standard download-zip-then-unzip pattern used for terraform
and sops in this same Dockerfile.
2026-05-07 23:26:46 +00:00
Viktor Barzin
c5f8af75a2 Phase 4: drop registry.viktorbarzin.me dual-push, Forgejo only
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2026-05-07 23:16:53 +00:00
Viktor Barzin
578c408ac6 trigger after forge timeout fix 2026-05-07 23:15:52 +00:00
Viktor Barzin
d1d3827e12 Drop monorepo path filter and prefix from .woodpecker.yml 2026-05-07 17:07:29 +00:00
Viktor Barzin
6fa60fdd1a Initial extraction from monorepo 2026-05-07 17:07:12 +00:00