Conversation
…te merges - No more stop-per-task; commit task-by-task continuously within a feature instead - Stop only at feature completion, with a concise bulleted (not verbose) summary - Claude now creates feature branches and merges them into the phase branch autonomously, and solo-handles PR creation + CI fixes for the phase -> develop -> main flow - Hard rule, no exceptions: every merge and every PR creation still requires an explicit go-ahead first
Only spawn subagents for genuinely independent work (parallel research, isolated implementation pieces, context-heavy lookups) — not sequential feature-building work, which is most of what this project's workflow looks like. Always announce before spawning one, never silently.
…was built Every explanation of completed work now includes: key architectural choices made, why each was made, and the deciding factor whenever a new library/framework/service is introduced. Same concise one-liner bullet standard as the rest of Communication Style — reasoning in one tight line, not a paragraph.
Keeps deliverables (code, docs, commits, app content) in normal prose per existing rules, but standardizes the final wrap-up line so task completion is always signaled the same terse way.
Stands up Argus as living infra: outcome ledger, supervisor graph, tool registry, chat API + UI. Architected so later phases (Cashflow, Goal Planning, Card Routing, Credit) plug in as new tools without rearchitecting this layer.
ai_predictions table logs every prediction Argus makes; resolve_due_predictions Celery task grades resolved predictions against actual account balances. Evaluation logic kept as a pure function (_evaluate_prediction) so accuracy checks are testable without hitting Supabase, matching the existing detect_bills/detect_subscriptions pattern in this codebase.
agents/tools.py is the registry pattern every later engine (Cashflow, Goal Planning, Card Routing, Credit) plugs into via @register_tool — decided on a decorator + dict registry over a class hierarchy so new phases add a function, not a subclass. Registers Phase 3.5's existing capabilities (bills, subscriptions, spending) as the first tools. agents/supervisor.py routes a chat query to whichever registered tools are relevant via keyword matching, falls back to all tools when nothing matches. Kept routing as a pure, deterministic function rather than an LLM tool-call loop for this skeleton phase — testable without mocking Anthropic, and the LangGraph node is a thin wrapper around it so an LLM-driven router can replace the matching logic later without touching the graph structure.
…ging agents/chat.py wires RAG context from three sources: supervisor_graph (live data via registered tools), user_financial_profiles (static profile), and the existing _retrieve_relevant_insights embedding search from the Phase 3.5 pipeline (distilled monthly summaries) — reused instead of duplicated since it already does pgvector retrieval against ai_insights. Also pulls the user's own outcome ledger (past predictions + accuracy) into context so Argus can calibrate against its own track record per the self-improving design in product-detail.md. Predictions are captured via a fenced ```prediction JSON block the system prompt asks Claude to emit after any verifiable claim — parsed by a pure, testable function (_extract_prediction_block) rather than trying to classify free text. Logged to ai_predictions, then stripped from the text shown to the user. Endpoint streams via SSE (StreamingResponse + text/event-stream) since the product spec requires live token-by-token chat, not request/response.
Added streamChat() to lib/api.ts as a separate path from the existing
apiFetch helper — SSE needs raw ReadableStream/TextDecoder parsing of
`data: {...}` frames, not JSON.parse on a single response body, so it
couldn't reuse the existing JSON-only client.
Chat page wraps useSearchParams() in Suspense (Next 16 build requirement
for any client component reading search params) so /argus?q=... deep
links from AskArgusBar prerender correctly. Wired the existing dashboard
AskArgusBar — previously routed to /intelligence as a placeholder — to
this new route now that the dedicated endpoint exists. Added Argus to
the app sidebar nav, mirroring the existing nav-item pattern.
No frontend test runner exists in this repo (eslint-only, no jest/
vitest configured for app/) — verified via next build (prerenders
clean) and eslint (no new violations) instead, matching how every
other page in app/(app)/ is currently validated.
Per the Specificity rule in product-detail.md, Argus answers should render as verdict cards, tables, or charts — never paragraphs. Added a second fenced-block convention (\`\`\`argus-card) alongside the existing prediction block: the system prompt now requires every answer to be one or more typed JSON cards (verdict/table/chart), parsed by _extract_card_blocks and stripped from the displayed text the same way predictions already were. SSE 'done' payload now carries a `cards` array the frontend renders directly, instead of dumping structured data into prose the UI would have to re-parse.
Cards.tsx adds the three card types matching the backend's argus-card contract. Used recharts for the chart card — already a project dependency, unused elsewhere yet, so no new dependency added. Chat page no longer streams raw text into the bubble: card JSON arrives fenced mid-stream and would render as garbage if shown live, so chunks now just keep a "thinking" indicator up until the done event delivers parsed cards. Falls back to a plain text bubble only for client-side errors (e.g. network failure) where there's no card to show.
Adds optional `page` field to ChatRequest, threaded through to _build_chat_brief as a CURRENT SCREEN line. Needed for the side panel, which is context-aware per the product spec — Argus should know what screen triggered the question (e.g. asked from /bills vs /subscriptions) without the frontend having to fold that into the query text itself.
ArgusSidePanel mounts once in app/(app)/layout.tsx — the shared layout that wraps every (app) route and doesn't remount on navigation in the App Router — so its message state survives moving between screens instead of resetting per route. Visibility is just a CSS transform (right: 14px vs -396px) rather than a conditional mount, which is what makes the persistence work: an unmounted component loses state, a hidden one doesn't. Cmd+K / Ctrl+K toggles it from any screen; Escape closes it. Passes the current pathname as `page` into streamChat so Argus knows what screen the question came from, using the page-context field added to the backend in the prior commit.
- Bullets and phase summaries now use caveman style, jargon-stripped - .agents/ and .continue/ skill configs tracked - skills-lock.json added Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Phase_6.5_UIOverhaul.md: 7-branch overhaul plan for all unstyled pages - product-plan.md: Phase 6.5 entry inserted after Phase 6 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Phase 5 complete: Argus Brain skeleton live — supervisor graph, outcome ledger, /argus/chat SSE endpoint with RAG, chat page, Cmd+K side panel. Phase 6.5 UI Overhaul plan added to roadmap. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Introduces the Phase 5 “Argus Brain” skeleton: an interactive Argus chat surface (page + Cmd/Ctrl+K side panel) backed by a new /argus/chat SSE endpoint, a minimal supervisor/tool registry for routing to existing Phase 3.5 capabilities, and an ai_predictions “outcome ledger” plus a Celery task to resolve/grade predictions. Also adds/updates roadmap and phase plan documentation, and vendors “caveman” skill content into the repo.
Changes:
- Add backend Argus chat stack: tool registry + supervisor graph, chat brief/context builder,
/argus/chatSSE router,ai_predictionsmigration, and prediction resolution Celery task. - Add frontend Argus experiences:
/arguschat page with card rendering, global side panel toggle from app layout, and API helper for streaming SSE. - Add Phase 5 + Phase 6.5 planning docs and vendored skill documentation/scripts.
Reviewed changes
Copilot reviewed 67 out of 67 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| skills-lock.json | Pins external skill sources/hashes used by the repo. |
| Phase Plans/Phase_6.5_UIOverhaul.md | Adds detailed Phase 6.5 UI overhaul execution plan. |
| Phase Plans/Phase_5_ArgusBrain.md | Adds Phase 5 “Argus Brain” plan including outcome ledger, supervisor, SSE chat, and UI surfaces. |
| frontend/lib/api.ts | Adds streamChat() helper to consume /argus/chat SSE responses. |
| frontend/app/(app)/layout.tsx | Adds Argus nav entry, global Cmd/Ctrl+K toggle, and mounts ArgusSidePanel. |
| frontend/app/(app)/dashboard/_components/AskArgusBar.tsx | Routes “Ask Argus” bar to /argus instead of /intelligence. |
| frontend/app/(app)/argus/page.tsx | New Argus chat page consuming SSE and rendering cards. |
| frontend/app/(app)/argus/_components/Cards.tsx | New card renderers for verdict/table/chart (Recharts). |
| frontend/app/(app)/_components/ArgusSidePanel.tsx | New slide-in Argus side panel, persists via layout. |
| backend/tests/test_supervisor.py | Tests tool selection and routing/dispatch behavior for supervisor. |
| backend/tests/test_resolve_predictions.py | Unit tests for prediction evaluation logic. |
| backend/tests/test_argus_router.py | Router-level tests for /argus/chat SSE behavior, cards, auth, and page passthrough. |
| backend/tests/test_argus_chat.py | Tests chat parsing (prediction/cards), brief building, logging, and context retrieval. |
| backend/tests/test_agent_tools.py | Tests tool registry + Supabase query behavior for a tool. |
| backend/tasks/resolve_predictions.py | Adds Celery task to resolve due predictions and write outcomes/accuracy. |
| backend/routers/argus.py | Adds /argus/chat SSE streaming endpoint integrating chat brief/context and logging. |
| backend/migrations/015_ai_predictions.sql | Adds ai_predictions outcome ledger table + index + RLS policy. |
| backend/main.py | Registers the new Argus router with the FastAPI app. |
| backend/agents/tools.py | Implements a tool registry and registers Phase 3.5 tools for Argus routing. |
| backend/agents/supervisor.py | Adds a minimal LangGraph supervisor graph that selects tools by keyword and executes them. |
| backend/agents/chat.py | Adds chat system prompt, context retrieval, brief building, card/prediction extraction, and prediction logging. |
| Argus Details/product-plan.md | Updates product plan with Phase 6.5 UI Overhaul section. |
| .continue/skills/caveman/SKILL.md | Vendors caveman “mode” skill instructions (Continue skill format). |
| .continue/skills/caveman/README.md | Documentation for caveman mode usage. |
| .continue/skills/caveman-stats/SKILL.md | Vendors caveman-stats skill instructions. |
| .continue/skills/caveman-stats/README.md | Documentation for caveman-stats. |
| .continue/skills/caveman-review/SKILL.md | Vendors caveman-review skill instructions. |
| .continue/skills/caveman-review/README.md | Documentation for caveman-review. |
| .continue/skills/caveman-help/SKILL.md | Vendors caveman-help skill instructions. |
| .continue/skills/caveman-help/README.md | Documentation for caveman-help. |
| .continue/skills/caveman-compress/SKILL.md | Vendors caveman-compress skill instructions. |
| .continue/skills/caveman-compress/SECURITY.md | Security notes for caveman-compress implementation. |
| .continue/skills/caveman-compress/scripts/validate.py | Validation script used by caveman-compress. |
| .continue/skills/caveman-compress/scripts/detect.py | File-type detection script used by caveman-compress. |
| .continue/skills/caveman-compress/scripts/compress.py | Compression orchestrator script used by caveman-compress. |
| .continue/skills/caveman-compress/scripts/cli.py | CLI wrapper for caveman-compress scripts. |
| .continue/skills/caveman-compress/scripts/benchmark.py | Benchmark helper for caveman-compress validation/token counts. |
| .continue/skills/caveman-compress/scripts/main.py | Module entrypoint for caveman-compress scripts. |
| .continue/skills/caveman-compress/scripts/init.py | Package init for caveman-compress scripts. |
| .continue/skills/caveman-compress/README.md | Documentation for caveman-compress. |
| .continue/skills/caveman-commit/SKILL.md | Vendors caveman-commit skill instructions. |
| .continue/skills/caveman-commit/README.md | Documentation for caveman-commit. |
| .continue/skills/cavecrew/SKILL.md | Vendors cavecrew delegation guide skill instructions. |
| .continue/skills/cavecrew/README.md | Documentation for cavecrew. |
| .claude/CLAUDE.md | Updates Claude project instructions (workflow/commit/merge behavior guidance). |
| .agents/skills/caveman/SKILL.md | Mirrors caveman skill instructions under .agents/. |
| .agents/skills/caveman/README.md | Mirrors caveman README under .agents/. |
| .agents/skills/caveman-stats/SKILL.md | Mirrors caveman-stats skill instructions under .agents/. |
| .agents/skills/caveman-stats/README.md | Mirrors caveman-stats README under .agents/. |
| .agents/skills/caveman-review/SKILL.md | Mirrors caveman-review skill instructions under .agents/. |
| .agents/skills/caveman-review/README.md | Mirrors caveman-review README under .agents/. |
| .agents/skills/caveman-help/SKILL.md | Mirrors caveman-help skill instructions under .agents/. |
| .agents/skills/caveman-help/README.md | Mirrors caveman-help README under .agents/. |
| .agents/skills/caveman-compress/SKILL.md | Mirrors caveman-compress skill instructions under .agents/. |
| .agents/skills/caveman-compress/SECURITY.md | Mirrors caveman-compress SECURITY notes under .agents/. |
| .agents/skills/caveman-compress/scripts/validate.py | Mirrors caveman-compress validate script under .agents/. |
| .agents/skills/caveman-compress/scripts/detect.py | Mirrors caveman-compress detect script under .agents/. |
| .agents/skills/caveman-compress/scripts/compress.py | Mirrors caveman-compress compress script under .agents/. |
| .agents/skills/caveman-compress/scripts/cli.py | Mirrors caveman-compress CLI script under .agents/. |
| .agents/skills/caveman-compress/scripts/benchmark.py | Mirrors caveman-compress benchmark script under .agents/. |
| .agents/skills/caveman-compress/scripts/main.py | Mirrors caveman-compress entrypoint under .agents/. |
| .agents/skills/caveman-compress/scripts/init.py | Mirrors caveman-compress package init under .agents/. |
| .agents/skills/caveman-compress/README.md | Mirrors caveman-compress README under .agents/. |
| .agents/skills/caveman-commit/SKILL.md | Mirrors caveman-commit skill instructions under .agents/. |
| .agents/skills/caveman-commit/README.md | Mirrors caveman-commit README under .agents/. |
| .agents/skills/cavecrew/SKILL.md | Mirrors cavecrew skill instructions under .agents/. |
| .agents/skills/cavecrew/README.md | Mirrors cavecrew README under .agents/. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+23
to
+46
| due = ( | ||
| supabase.table("ai_predictions") | ||
| .select("id, prediction_type, prediction_payload") | ||
| .lte("resolves_at", datetime.now(UTC).isoformat()) | ||
| .is_("actual_outcome", "null") | ||
| .execute() | ||
| ).data or [] | ||
|
|
||
| resolved = 0 | ||
| for prediction in due: | ||
| payload = prediction["prediction_payload"] | ||
| account_id = payload.get("account_id") | ||
| actual_balance = None | ||
|
|
||
| if account_id: | ||
| account = ( | ||
| supabase.table("accounts") | ||
| .select("balance") | ||
| .eq("id", account_id) | ||
| .execute() | ||
| ).data | ||
| if account: | ||
| actual_balance = account[0]["balance"] | ||
|
|
Comment on lines
+1
to
+8
| from contextlib import contextmanager | ||
| from unittest.mock import MagicMock, patch | ||
|
|
||
| from fastapi.testclient import TestClient | ||
|
|
||
| from main import app | ||
| from middleware.auth import get_current_user | ||
|
|
Comment on lines
+1
to
+37
| import json | ||
| import os | ||
| from collections.abc import AsyncGenerator | ||
|
|
||
| import anthropic | ||
| from fastapi import APIRouter, Depends | ||
| from fastapi.responses import StreamingResponse | ||
| from pydantic import BaseModel | ||
|
|
||
| from agents.chat import ( | ||
| _CHAT_SYSTEM_PROMPT, | ||
| _build_chat_brief, | ||
| _extract_card_blocks, | ||
| _extract_prediction_block, | ||
| _log_prediction, | ||
| _retrieve_chat_context, | ||
| _strip_card_blocks, | ||
| _strip_prediction_block, | ||
| ) | ||
| from middleware.auth import get_current_user | ||
|
|
||
| router = APIRouter(prefix="/argus", tags=["argus"]) | ||
|
|
||
|
|
||
| class ChatRequest(BaseModel): | ||
| query: str | ||
| page: str | None = None | ||
|
|
||
|
|
||
| async def _stream_chat_response( | ||
| user_id: str, query: str, page: str | None = None | ||
| ) -> AsyncGenerator[str, None]: | ||
| context = _retrieve_chat_context(user_id, query) | ||
| brief = _build_chat_brief(query, context, page=page) | ||
|
|
||
| client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"]) | ||
| full_text = "" |
Comment on lines
+166
to
+172
| function handleKeydown(e: KeyboardEvent) { | ||
| if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") { | ||
| e.preventDefault(); | ||
| setArgusPanelOpen((prev) => !prev); | ||
| } | ||
| if (e.key === "Escape") setArgusPanelOpen(false); | ||
| } |
Comment on lines
+82
to
+83
| <aside | ||
| style={{ |
Comment on lines
+104
to
+106
| <button onClick={onClose} className="text-gray-500 hover:text-white"> | ||
| <X size={16} /> | ||
| </button> |
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ai_predictionstable) — every prediction logged and later auto-gradedPOST /argus/chatSSE endpoint with RAG (hot transactions + summaries + profile + outcome ledger)Test plan
POST /argus/chatreturns streaming SSE response🤖 Generated with Claude Code