Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .opencode/agent/code-reviewer.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
description: Elite code review specialist — security vulnerabilities, performance, correctness, production reliability. Use PROACTIVELY for code quality assurance within the Samourai pipeline.
model: inherit
temperature: 0.2
reasoningEffort: high
tools:
Expand Down
60 changes: 30 additions & 30 deletions .opencode/opencode.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

// Fallback model used by any agent without an explicit "model" in the "agent" section.
// Format: "provider/model-id"
"model": "github-copilot/gpt-5.2",
"model": "openrouter/deepseek/deepseek-chat-v3-0324",

// Lightweight model for non-critical utility tasks:
// session title generation, short summaries, metadata.
"small_model": "github-copilot/gpt-5-mini",
"small_model": "openrouter/openai/gpt-5-nano",

// ─── Global Instructions ───────────────────────────────────────────────────

Expand Down Expand Up @@ -251,7 +251,7 @@
// Full access required to read/write artifacts, call sub-agents,
// and interact with trackers (GitHub MCP when enabled).
"pm": {
"model": "github-copilot/claude-opus-4.6",
"model": "openrouter/deepseek/deepseek-v4-pro",
"steps": 200, // long orchestration: many possible steps
"permission": {
"bash": "allow",
Expand All @@ -271,7 +271,7 @@
// @coder: implements plan phases. Reads, writes, and runs commands.
// No web access — works exclusively within the repository.
"coder": {
"model": "github-copilot/gpt-5.3-codex",
"model": "openrouter/deepseek/deepseek-chat-v3-0324",
"steps": 220, // multi-phase implementation: many file operations
"permission": {
"bash": "allow", // run commands (tests, build, typecheck)
Expand All @@ -288,7 +288,7 @@
// @fixer: fixes bugs and test failures using root-cause analysis.
// Similar access to @coder but fewer steps (targeted investigation).
"fixer": {
"model": "github-copilot/gpt-5.3-codex",
"model": "openrouter/deepseek/deepseek-chat-v3-0324",
"steps": 120, // targeted debugging — should not wander too long
"permission": {
"bash": "allow",
Expand All @@ -303,7 +303,7 @@
// @refactor: performs safe, incremental code refactoring.
// Preserves behavior and validates with tests.
"refactor": {
"model": "github-copilot/gpt-5.3-codex", // same model as @coder
"model": "openrouter/deepseek/deepseek-chat-v3-0324", // same model as @coder
"steps": 60,
"permission": {
"bash": "allow",
Expand All @@ -322,7 +322,7 @@
// @tdd-orchestrator: enforces the red-green-refactor cycle for a task.
// Delegated by @coder in /run-plan when the tdd-orchestrator skill is active.
"tdd-orchestrator": {
"model": "github-copilot/gpt-5.3-codex",
"model": "openrouter/deepseek/deepseek-chat-v3-0324",
"steps": 60, // RED→GREEN→REFACTOR cycle × N behaviors
"permission": {
"bash": "allow", // run tests at each step of the cycle
Expand All @@ -340,7 +340,7 @@
// @reviewer: validates code against spec + plan + quality heuristics.
// May modify the plan (adding a remediation phase) but not the source code.
"reviewer": {
"model": "github-copilot/gpt-5.3-codex",
"model": "openrouter/deepseek/deepseek-chat-v3-0324",
"temperature": 0.2, // deterministic review: reduces variability in findings
"steps": 30, // diff reading + report = bounded task
"permission": {
Expand All @@ -359,7 +359,7 @@
// @code-reviewer: targeted diff analysis — security, correctness, performance.
// Delegated by @reviewer and /git-workflow. Strict read-only: modifies NOTHING.
"code-reviewer": {
"model": "github-copilot/gpt-5.3-codex",
"model": "openrouter/deepseek/deepseek-chat-v3-0324",
"temperature": 0.2, // consistent and reproducible findings
"steps": 20, // bounded analysis — no action, report only
"permission": {
Expand All @@ -377,7 +377,7 @@
// @gap-analysis: artifact traceability analysis (spec/plan/test/code gaps).
// Similar to @code-reviewer but focused on lifecycle coverage.
"gap-analysis": {
"model": "github-copilot/gpt-5.3-codex", // same model as @reviewer
"model": "openrouter/deepseek/deepseek-chat-v3-0324", // same model as @reviewer
"temperature": 0.2, // deterministic analysis for reproducible reports
"steps": 25,
"permission": {
Expand All @@ -395,7 +395,7 @@

// @verdict: final GO/NO-GO evaluator based on gates and evidence.
"verdict": {
"model": "github-copilot/gpt-5.3-codex", // same model as @reviewer
"model": "openrouter/deepseek/deepseek-chat-v3-0324", // same model as @reviewer
"temperature": 0.1, // highly deterministic for consistent verdicts
"steps": 20,
"permission": {
Expand All @@ -412,7 +412,7 @@

// @jira-analysis: analyzes ticket quality and extracts requirements.
"jira-analysis": {
"model": "github-copilot/gpt-5.3-codex", // same model as @reviewer
"model": "openrouter/deepseek/deepseek-chat-v3-0324", // same model as @reviewer
"temperature": 0.2,
"steps": 20,
"permission": {
Expand All @@ -429,7 +429,7 @@

// @review-feedback-applier: applies review feedback after human validation.
"review-feedback-applier": {
"model": "github-copilot/gpt-5.2-codex",
"model": "openrouter/deepseek/deepseek-chat-v3-0324",
"steps": 30
// To enable GitHub MCP (read PR comments):
// "tools": { "github*": true }
Expand All @@ -439,7 +439,7 @@

// @committer: creates exactly one Conventional Commit. Simple and fast task.
"committer": {
"model": "github-copilot/gpt-5-mini", // lightweight model sufficient for git operations
"model": "openrouter/openai/gpt-5-nano", // lightweight model sufficient for git operations
"steps": 15, // git add + diff analysis + commit = few steps
"permission": {
"bash": "allow", // git status, git add, git commit
Expand All @@ -451,7 +451,7 @@

// @pr-manager: creates/updates the PR and stops before merge.
"pr-manager": {
"model": "github-copilot/claude-sonnet-4.5",
"model": "openrouter/deepseek/deepseek-chat",
"steps": 20
// To enable GitHub MCP (create PR via API):
// "tools": { "github*": true }
Expand All @@ -461,29 +461,29 @@

// @spec-writer: writes the change specification (chg-xxx-spec.md).
"spec-writer": {
"model": "github-copilot/claude-sonnet-4.6", // Claude: best for structured writing
"model": "openrouter/deepseek/deepseek-chat", // Claude: best for structured writing
"steps": 30,
"tools": { "socraticode*": true } // explore existing code before writing spec
},

// @test-plan-writer: writes the test plan (chg-xxx-test-plan.md).
"test-plan-writer": {
"model": "github-copilot/gpt-5.2",
"model": "openrouter/qwen/qwen3-plus",
"steps": 25,
"tools": { "socraticode*": true } // find existing test patterns and coverage
},

// @plan-writer: writes the implementation plan (chg-xxx-plan.md).
"plan-writer": {
"model": "github-copilot/gpt-5.2",
"model": "openrouter/qwen/qwen3-plus",
"steps": 50,
"tools": { "socraticode*": true } // understand codebase structure before planning
},

// @doc-syncer: synchronizes system documentation with delivered code.
// Reads the diff and updates doc/spec/. No web access.
"doc-syncer": {
"model": "github-copilot/claude-sonnet-4.5",
"model": "openrouter/deepseek/deepseek-chat",
"steps": 20,
"permission": {
"bash": "allow", // git diff to see what changed
Expand All @@ -499,7 +499,7 @@
// @runner: executes commands (build, tests, lint) and logs the results.
// Does not modify source files — read and execute only.
"runner": {
"model": "github-copilot/gpt-5-mini", // execution task, no complex reasoning required
"model": "openrouter/openai/gpt-5-nano", // execution task, no complex reasoning required
"steps": 25,
"permission": {
"bash": "allow", // run build, tests, lint, quality gates
Expand All @@ -514,48 +514,48 @@
// @architect: technical and architectural decisions. Produces ADRs.
// Most powerful model for complex reasoning.
"architect": {
"model": "github-copilot/gpt-5.4", // best model for architectural thinking
"model": "openrouter/deepseek/deepseek-v4-pro", // best model for architectural thinking
"steps": 40,
"color": "secondary",
"tools": { "socraticode*": true } // graph/impact for architectural analysis
},

// @bootstrapper: onboards a new project into the Samourai ecosystem.
"bootstrapper": {
"model": "github-copilot/claude-sonnet-4.6",
"model": "openrouter/deepseek/deepseek-chat",
"steps": 30
},

// @toolsmith: creates and improves kit tools, agents, and commands.
"toolsmith": {
"model": "github-copilot/gpt-5.3-codex",
"model": "openrouter/deepseek/deepseek-chat-v3-0324",
"steps": 40
},

// ── Content & Media ─────────────────────────────────────────────────────

// @editor: writes and translates user-facing content per copywriting.md.
"editor": {
"model": "github-copilot/claude-sonnet-4.6", // Claude: best for natural language
"model": "openrouter/deepseek/deepseek-chat", // Claude: best for natural language
"steps": 20
},

// @designer: UI/UX design, aligned with the design system.
"designer": {
"model": "github-copilot/gpt-4o", // GPT-4o: vision + design
"model": "openrouter/openai/gpt-4.1-nano", // GPT-4o: vision + design
"steps": 20,
"tools": { "puppeteer*": true } // enables Puppeteer MCP for UI screenshots
},

// @image-generator: image generation via text-to-image.
"image-generator": {
"model": "github-copilot/gpt-4o",
"model": "openrouter/openai/gpt-4.1-nano",
"steps": 10 // single generation = few steps
},

// @image-reviewer: analyzes screenshots and visual artifacts. Read-only.
"image-reviewer": {
"model": "github-copilot/gpt-4o", // GPT-4o: multimodal (vision)
"model": "openrouter/openai/gpt-4.1-nano", // GPT-4o: multimodal (vision)
"steps": 10,
"permission": {
"edit": "deny", // analysis only, modifies nothing
Expand All @@ -568,7 +568,7 @@
// @external-researcher: research via web and MCP (context7, deepwiki, etc.).
// Only agent authorized to leave the repository — webfetch and websearch enabled.
"external-researcher": {
"model": "github-copilot/gemini-3.1-pro-preview", // Gemini: large context window for research
"model": "openrouter/google/gemini-2.5-flash", // Gemini: large context window for research
"steps": 30,
"permission": {
"webfetch": "allow", // fetch web pages and documentation
Expand All @@ -584,7 +584,7 @@
// Agent Samourai distinct des agents internes du pipeline Kairos Mesh.
// Accède à l'API backend locale pour les données de marché si disponible.
"trading-analyst": {
"model": "github-copilot/claude-sonnet-4.6", // Claude: raisonnement nuancé pour l'analyse financière
"model": "openrouter/deepseek/deepseek-chat", // Claude: raisonnement nuancé pour l'analyse financière
"steps": 40,
"temperature": 0.2, // déterministe: analyse prudente, évite la sur-créativité
"permission": {
Expand All @@ -605,7 +605,7 @@
// Lit/modifie les skills (SKILL.md), les prompts DB via API, et la config LLM.
// ⚠️ Agents Binding (risk-manager, execution-manager): demander confirmation avant activation.
"kairos-agent-manager": {
"model": "github-copilot/claude-sonnet-4.6", // Claude: analyse structurée des prompts + skills
"model": "openrouter/deepseek/deepseek-chat", // Claude: analyse structurée des prompts + skills
"steps": 50,
"temperature": 0.2, // prudent: modifications ciblées, pas de sur-créativité
"permission": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Plan d'implémentation — GH-34 : Provider LLM OpenRouter

## Vue d'ensemble

Ajout d'OpenRouter comme 4ème provider LLM. Extension purement additive : aucun changement de comportement pour Ollama/OpenAI/Mistral.

---

## Phase 1 : Settings

### 1.1 `backend/app/core/config.py`
- [ ] Ajouter 6 champs à la classe `Settings` :
```python
openrouter_base_url: str = Field(default='https://openrouter.ai/api/v1', alias='OPENROUTER_BASE_URL')
openrouter_api_key: str = Field(default='', alias='OPENROUTER_API_KEY')
openrouter_model: str = Field(default='openrouter/auto', alias='OPENROUTER_MODEL')
openrouter_timeout_seconds: int = Field(default=30, alias='OPENROUTER_TIMEOUT_SECONDS')
openrouter_input_cost_per_1m_tokens: float = Field(default=0.0, alias='OPENROUTER_INPUT_COST_PER_1M_TOKENS')
openrouter_output_cost_per_1m_tokens: float = Field(default=0.0, alias='OPENROUTER_OUTPUT_COST_PER_1M_TOKENS')
```

---

## Phase 2 : Model Selector

### 2.1 `backend/app/services/llm/model_selector.py`
- [ ] Ligne 28 : `SUPPORTED_LLM_PROVIDERS = {'ollama', 'openai', 'mistral', 'openrouter'}`

---

## Phase 3 : Provider Client

### 3.1 `backend/app/services/llm/provider_client.py`
- [ ] `__init__` : `self.openrouter = OpenAICompatibleClient('openrouter')`
- [ ] `_provider_client()` : `if provider == 'openrouter': return self.openrouter`

### 3.2 `backend/app/services/llm/openai_compatible_client.py`
- [ ] `_normalized_api_key()` : branche `self.provider == 'openrouter'`
- [ ] `_normalized_base_url()` : branche `self.provider == 'openrouter'`
- [ ] `_default_model()` : branche `self.provider == 'openrouter'`
- [ ] `_timeout_seconds()` : branche `self.provider == 'openrouter'`
- [ ] `_estimate_cost_usd()` : branche `self.provider == 'openrouter'`

---

## Phase 4 : AgentScope

### 4.1 `backend/app/services/agentscope/model_factory.py`
- [ ] `build_model()` : `if provider in ("openai", "mistral", "openrouter"):`

### 4.2 `backend/app/services/agentscope/formatter_factory.py`
- [ ] `build_formatter()` : ajouter `openrouter` au dispatch (utilise `OpenAI*Formatter` comme OpenAI/Mistral)

---

## Phase 5 : Points d'intégration

### 5.1 `backend/app/services/benchmark/engine.py`
- [ ] `_resolve_provider_config()` : `if provider == 'openrouter': return provider, model_name, settings.openrouter_base_url, settings.openrouter_api_key`

### 5.2 `backend/app/services/market/news_provider.py`
- [ ] Résolution provider : ajouter cas `openrouter` pour base_url et api_key

### 5.3 `backend/app/api/routes/health.py`
- [ ] `health()` : `elif llm_provider == 'openrouter': llm_configured = bool((settings.openrouter_api_key or '').strip())`

### 5.4 `backend/app/services/strategy/optimizer_service.py`
- [ ] `_resolve_llm_config()` : `elif provider == 'openrouter': base_url = settings.openrouter_base_url; api_key = settings.openrouter_api_key`

---

## Phase 6 : Documentation

### 6.1 `docs/configuration.md`
- [ ] Ajouter section `### OpenRouter` après Mistral (ligne ~141)

### 6.2 `.env.example`
- [ ] Ajouter les 6 variables OpenRouter avec commentaires

---

## Phase 7 : Tests

### 7.1 `backend/tests/unit/test_openai_compatible_client.py`
- [ ] `test_openrouter_client_base_url()`
- [ ] `test_openrouter_client_default_model()`
- [ ] `test_openrouter_client_is_configured()`
- [ ] `test_openrouter_client_not_configured_without_key()`

### 7.2 `backend/tests/unit/test_llm_provider_client.py`
- [ ] `test_llm_client_uses_openrouter_provider()`

### 7.3 `backend/tests/unit/test_agent_model_selector.py`
- [ ] `test_agent_model_selector_supports_openrouter_provider()`
- [ ] `test_normalize_llm_provider_accepts_openrouter()`

### 7.4 `backend/tests/unit/test_agentscope_model_factory.py`
- [ ] `test_build_openrouter_model()`

---

## Phase 8 : Validation

- [ ] `cd backend && pytest -q` — pas de régression
- [ ] `cd frontend && npm run build` — pas d'impact frontend
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
change_id: GH-34
title: "Ajouter OpenRouter comme provider LLM (API OpenAI-compatible)"
phases:
clarify_scope: { started: "2026-07-04T15:45:00Z", completed: "2026-07-04T15:50:00Z" }
specification: { started: "2026-07-04T15:50:00Z", completed: "2026-07-04T15:55:00Z" }
test_planning: { started: "2026-07-04T15:55:00Z", completed: "2026-07-04T16:00:00Z" }
delivery_planning: { started: "2026-07-04T15:55:00Z", completed: "2026-07-04T16:00:00Z" }
delivery: { started: "2026-07-04T16:00:00Z", completed: null }
system_spec_update: { started: null, completed: null }
review_fix: { started: null, completed: null }
quality_gates: { started: null, completed: null }
dod_check: { started: null, completed: null }
pr_creation: { started: null, completed: null, url: null }
decisions: []
open_questions: []
blockers: []
notes:
- text: "Ticket créé via gh CLI — GitHub MCP auth KO"
type: info
date: "2026-07-04"
Loading
Loading