KoalaTrapLord
e1bb2e7209
feat(coach): Phase 1 sim stats pass-through in prompt template ( #108 )
...
Surfaces previously-computed-but-unused stats into the Claude prompt:
1. USER_PROMPT_TEMPLATE gains a new '### Sim Insights' section that shows:
- Deck-level opening hand quality: avg keptInOpeningHandRate across all
cards, plus the 3 worst offenders with their actual rates
- Curve velocity: avg avgTurnCast weighted by castRate, flagging cards
cast on avg turn > 6 as 'late'
- Synergy outliers: bottom-3 synergyScore cards flagged as 'isolated'
- Archetype weak spots: archetypes with winRate < 40% flagged explicitly
2. _format_archetypes() now annotates weak spots with [WEAK SPOT] and
strong matchups with [STRENGTH] so Claude sees them immediately.
3. _format_top_cards() adds keptInOpeningHandRate to each line so
the 'good' cards also show their hand-keepability signal.
4. New helper _format_sim_insights() computes all deck-level aggregates
from CardPerformance list — no new fields on DeckMeta needed.
No schema changes. Fully backward-compatible with existing DeckReport.
2026-03-29 05:55:51 -04:00
KoalaTrapLord
aefd0cace6
feat(rag): Phase 1 — rewrite build_card_text to natural-language format ( #137 )
...
* feat(rag): Phase 1 — rewrite build_card_text to natural-language format
* feat(rag): Phase 2 — Forge-enriched ChromaDB RAG store (2a–2e)
Phase 2a: Forge lazy import guard (_try_import_forge_lookup)
Phase 2b: _build_document appends Forge trigger/replacement/static/keyword tags
Phase 2c: _build_metadata adds has_trigger, has_replacement, has_static, trigger_modes fields
Phase 2d: query_cards extended with require_trigger, require_replacement, require_static params + ChromaDB where clause support
Phase 2e: get_rag_stats reports forge_enriched and forge_coverage; _write_build_meta tracks coverage; build loop counts enriched cards
* feat(rag): Phase 3 — add mtgrules second ChromaDB collection
Adds build_rules_index() and query_rules() operating on a separate
'mtgrules' ChromaDB collection. Chunks MagicCompRules.txt by rule-number
boundaries, embeds each chunk, and exposes semantic search. Completely
independent from the mtg_oracle card collection.
* feat(coach): Phase 4 — behavior-aware RAG + rules context in coach_service
Phase 4a: run_coaching_session uses dual RAG query
- Primary: commander synergy (n=10)
- Secondary: require_replacement=True for graveyard/protection cards (n=5)
- Deduplicates by name before merging
Phase 4b: query_rules() fetches 3 Commander rules chunks to ground the prompt
- Passed as rules_context kwarg to build_user_prompt()
* feat(rag): Phase 5 — add /api/rag/build-rules and /api/rag/query-rules endpoints
2026-03-29 02:11:38 -04:00
KoalaTrapLord
22cf23b24d
fix: correct query_cards kwarg names in coach_service (n= -> n_results=, colors= -> color_identity=)
2026-03-27 20:17:14 -04:00
KoalaTrapLord
0010b0f394
refactor: RAG improvements — shared card_text, Chroma fallback, staleness monitor ( fixes #133 , #134 , #135 ) ( #136 )
...
* refactor: add shared build_card_text() utility
* refactor: unify _build_document via shared card_text + add is_chroma_available/check_staleness (fixes #133 , #134 , #135 )
* refactor: delegate embeddings._build_card_text to shared utility
* feat: add background RAG staleness monitor to lab_api lifespan (fixes #135 )
2026-03-27 16:46:33 -04:00
KoalaTrapLord
d0cdafa66a
feat(rag): Phase 3 — inject RAG cards into coach prompts ( #132 )
...
* feat(rag): add RAG card injection to prompt_template.py
* feat(rag): wire RAG query into coach_service.py
* test(rag): add Phase 3 RAG injection tests
2026-03-27 15:20:49 -04:00
KoalaTrapLord
83502ce726
feat: Phase 3/5 deep analysis + Quick Digest endpoint (issue #108 ) ( #119 )
...
* feat(coach): Phase 3/5 JSON schema + QUICK_DIGEST prompt (issue #108 )
- Append removalCoverage, rampQuality, drawEngineProfile, winConditions,
antiSynergyFlags, podPresence, tempoAssessment, metaMatchups to schema
- Add 8 new RULES for Phase 3/5 analysis
- Add QUICK_DIGEST_SYSTEM_PROMPT constant
- Add build_quick_system_prompt() function
* feat(coach): Phase 3/5 JSON parsing + run_quick_digest() (issue #108 )
* feat(routes): add POST /api/coach/decks/{deck_id}/quick endpoint (issue #108 )
* feat(coach): Phase 3/5 parsing + run_quick_digest() (issue #108 )
* feat(coach): Phase 3/5 parsing + run_quick_digest() (issue #108 )
- Import RemovalCoverage, RampQuality, DrawEngineProfile, WinCondition,
AntiSynergyFlag, PodPresence, TempoAssessment, MetaMatchup
- Add Phase 3/5 blocks to _populate_session_from_json()
- Add run_quick_digest() method
* feat(ui): Top Priority card + Quick/Deep buttons in coach.html (issue #108 )
* feat(coach): Phase 3/5 parsing + run_quick_digest() (issue #108 )
* feat(ui): wire Quick Digest button + displayTopPriority() (issue #108 )
2026-03-27 07:51:01 -04:00
KoalaTrapLord
864cefb8d1
feat(coach): Phase 5 - add PodPresence, TempoAssessment, MetaMatchup models + isQuickDigest flag ( #108 )
2026-03-27 04:22:23 -04:00
KoalaTrapLord
4b92a5f364
Update models.pyfeat(coach): Phase 3 - add RemovalCoverage, RampQuality, DrawEngineProfile, WinCondition, AntiSynergyFlag models ( #108 )
2026-03-27 04:01:25 -04:00
KoalaTrapLord
da0193eb11
Update coach_service.pyfeat(coach): Phase 2 - parse upgradePriority, commanderDependency, mulliganAnalysis in coach_service ( #108 )feat(coach): Phase 2 - parse new fields in coach_service ( #108 )
2026-03-27 03:45:32 -04:00
KoalaTrapLord
71e0db4985
feat(coach): Phase 2 - add upgradePriority, commanderDependency, mulliganAnalysis to prompt schema ( #108 )
2026-03-27 03:32:03 -04:00
KoalaTrapLord
825946ae75
fix(deckgen): Phase 1 - non-destructive smart substitution + 99-card guarantee ( #111 )
...
- Add SubstitutionMethod enum to track how each card was resolved
- smart_substitute() now always returns a valid card string (never None/drops)
fallback chain: exact -> fuzzy -> functional analog -> original kept -> basic land
- apply_substitutions() loop no longer silently drops cards on failure
- _pad_to_99() circuit breaker added before BuildResult validation
- Pre-validation count logging per category for fast regression diagnosis
- Startup assertion: sum(SLOT_BUDGET) == 99 raises on app boot if misconfigured
- Prompt injection: slot budget + exact card count requirement sent to LLM
- run_substitution() anthropic fallback failure now pads with basic land instead of leaving slot missing
- SubstitutionBatchResult gains padded_slots field (> 0 = circuit breaker fired)
2026-03-27 03:27:52 -04:00
KoalaTrapLord
bd4df0c263
Update models.pyfeat(coach): Phase 2 - add UpgradePriority, CommanderDependency, MulliganAnalysis models ( #108 )
2026-03-27 02:52:01 -04:00
KoalaTrapLord
3f6d71ecbc
fix(coach): switch all Anthropic calls to streaming to prevent 10-min timeout error ( closes #109 )
...
- anthropic_client.py: all 4 methods (chat_structured, chat_plain, achat_structured, achat_plain) now use .messages.stream() context manager
- coach_service.py: inline aclient.messages.create() replaced with async streaming via aclient.messages.stream()
- _parse_response() updated to accept pre-extracted text string (since stream gives us text directly)
- check_status() left as non-streaming (max_tokens=10, safe from the 10min rule)
2026-03-27 02:36:22 -04:00
KoalaTrapLord
cd9d2eebd8
feat(coach): Phase 1 - pass richer card stats to Claude prompt ( #108 )
...
- _format_underperformers: add synergyScore, clunkinessScore, avgTurnCast, keptInOpeningHandRate
- _format_top_cards: add synergyScore and avgTurnCast
- _format_matchups: append perArchetypeWinRates block from DeckMeta
- USER_PROMPT_TEMPLATE: add ### Archetype Win Rates section placeholder
2026-03-27 01:32:51 -04:00
KoalaTrapLord
a01a70f725
Use DEFAULT_MAX_TOKENS config for Anthropic max_tokens
2026-03-26 22:50:10 -04:00
KoalaTrapLord
4da58681a4
Enhance coach prompt for more detailed reports
2026-03-26 22:41:23 -04:00
KoalaTrapLord
224b4b5d5b
feat: increase coach detail limits (MAX_UNDERPERFORMERS=8, MAX_TOKENS=16384)
2026-03-26 22:33:18 -04:00
KoalaTrapLord
8ec7db1612
fix: correct malformed string literals in config.py model defaults
2026-03-26 15:42:34 -04:00
KoalaTrapLord
e0a75e2d04
fix: correct Anthropic model ID from claude-opus-4-0 to claude-opus-4
2026-03-26 15:36:23 -04:00
KoalaTrapLord
15bd6f42bb
fix: resolve all ruff linting errors across coach module
2026-03-26 15:30:27 -04:00
KoalaTrapLord
0aa57ab7d2
fix: remove duplicate resp token on line 284 in run_coaching_session ( #105 )
2026-03-26 14:23:52 -04:00
KoalaTrapLord
9f5eb4a99f
fix: add missing resp= assignment on line 284 ( #105 )
2026-03-26 14:11:35 -04:00
KoalaTrapLord
a9f18f53da
fix: correct indentation of try/except/else block in run_coaching_session ( #105 )
2026-03-26 14:06:27 -04:00
KoalaTrapLord
c9e932ef43
fix: correct try: block indentation in run_coaching_session ( #105 )
2026-03-26 13:44:33 -04:00
KoalaTrapLord
2e316548e7
fix: repair resp= assignment and _re.sub typo in coach_service.py ( #105 )
2026-03-26 13:11:55 -04:00
KoalaTrapLord
af2a71d1a5
fix: eliminate event-loop-blocking sync calls in async FastAPI routes ( #106 )
...
* feat: add async DB wrapper and eliminate event-loop blocking
* fix: rewrite llm_client.py with native async httpx - removes urlopen and run_in_executor
* fix: rewrite routes/coach.py - replace all sync DB/HTTP with async (aiosqlite + httpx)
* fix: add async DB shutdown hook to lab_api.py
* feat: add aiosqlite>=0.19.0 to requirements
2026-03-25 19:17:41 -04:00
KoalaTrapLord
c9227dac70
Update substitution_prompt.pyfeat: update substitution_prompt.py docstring from Perplexity to Claude Opus ( #105 )
2026-03-25 16:41:47 -04:00
KoalaTrapLord
34b1ea2e30
feat: update deck_gen_user.py docstring from Perplexity to Claude Opus ( #105 )
2026-03-25 16:41:24 -04:00
KoalaTrapLord
1c6454dce5
feat: update substitution_schema.py source field from perplexity to anthropic ( #105 )
2026-03-25 16:39:16 -04:00
KoalaTrapLord
464dd732d5
feat: update deck_schema.py docstring from Perplexity to Claude Opus ( #105 )
2026-03-25 16:36:22 -04:00
KoalaTrapLord
c58f561df4
feat: replace PerplexityClient with AnthropicClient in deck_generator.py ( #105 )
2026-03-25 14:34:18 -04:00
KoalaTrapLord
6cf1e58018
feat: replace Perplexity with Anthropic Claude in coach_service.py ( #105 )
2026-03-25 14:30:40 -04:00
KoalaTrapLord
1382d25e46
feat: update clients __init__.py comment to reference Anthropic ( #105 )
2026-03-25 12:25:56 -04:00
KoalaTrapLord
55379a98ef
feat: replace Perplexity config with Anthropic Claude settings ( #105 )
2026-03-25 12:20:33 -04:00
KoalaTrapLord
34dee24399
feat: add AnthropicClient as drop-in replacement for PerplexityClient ( closes #105 phase 1)
2026-03-25 12:16:14 -04:00
KoalaTrapLord
e710287c35
fix: run_coaching_session respects COACH_PROVIDER for Perplexity API
...
The coaching pipeline in coach_service.py was always calling self.llm (Ollama) regardless of COACH_PROVIDER setting. Now branches on COACH_PROVIDER == 'perplexity' to call the Perplexity API directly via httpx, matching the pattern used in routes/coach.py coach_chat endpoint.
2026-03-25 10:42:49 -04:00
KoalaTrapLord
21f032d32e
fix: set DECK_GEN_PROVIDER default to perplexity and DECK_GEN_MODEL to sonar-pro
2026-03-25 10:29:54 -04:00
KoalaTrapLord
2881309d41
fix: set COACH_PROVIDER default to perplexity, remove stale DeepSeek comment
2026-03-25 10:13:58 -04:00
KoalaTrapLord
e7ffccf3e8
feat: persist coach sessions to SQLite with disk fallback
2026-03-24 23:44:20 -04:00
KoalaTrapLord
d70d74d753
feat: add Scryfall on-the-fly embedding fallback for unknown cards
2026-03-24 20:09:27 -04:00
KoalaTrapLord
41b711c17e
fix: normalize deck report slug matching (spaces/hyphens/underscores)
2026-03-24 13:31:52 -04:00
KoalaTrapLord
a6940ca61a
fix: update get_status() to check Perplexity connection when COACH_PROVIDER=perplexity
2026-03-24 13:29:16 -04:00
KoalaTrapLord
a515049542
feat: add COACH_PROVIDER config for Perplexity-powered coach chat
2026-03-24 12:50:21 -04:00
KoalaTrapLord
5a499442e6
feat: add PPLX_MODEL env var for configurable Perplexity model
2026-03-24 12:45:40 -04:00
KoalaTrapLord
f9007effa3
rename: update report_generator.py glob from batch- to ml-decision-
2026-03-23 23:05:25 -04:00
KoalaTrapLord and Claude Code
f0dfb41f2f
fix: default Ollama endpoints to localhost instead of 192.168.0.240 ( #98 )
...
The hardcoded 192.168.0.240 IP was a developer-specific LAN address
that breaks out-of-the-box for anyone running Ollama locally or via
WSL2 on Windows. Switch every default and docstring reference to
localhost so the project works without manual configuration.
Files changed:
- coach/config.py: LLM_URL and DECK_GEN_BASE_URL defaults
- ui/simulator.html: API endpoint input value and placeholder
- lab_api.py: remove LAN IP from default CORS origins
- routes/coach.py: warning message text
- src/commander_ai_lab/sim/deepseek_brain.py: docstrings
- src/commander_ai_lab/sim/deepseek_engine.py: docstring example
- src/commander_ai_lab/sim/validator_brain.py: docstring example
Co-authored-by: Claude Code <noreply@anthropic.com >
2026-03-23 21:03:17 -04:00
2b6d4dcdb1
fix: deduplicate LLM duplicate cards in _check_ownership ( #78 ) ( #79 )
...
Co-authored-by: Claude <claude@anthropic.com >
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-23 09:42:33 -04:00
KoalaTrapLord
f986d236ab
Reduce coach prompt limits and raise LLM timeout for R1 compatibility
2026-03-21 19:08:24 -04:00
KoalaTrapLord
cb4b48e362
refactor: rename LMStudioClient to LLMClient in coach_service.py
2026-03-21 13:33:00 -04:00
KoalaTrapLord
4a8db4db6b
refactor: rename LM_STUDIO/LMStudioClient to LLM/LLMClient in llm_client.py
2026-03-21 13:31:32 -04:00