Skip to content
Merged
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
28 changes: 28 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip

- name: Install dependencies
run: pip install -e ".[dev]"

- name: Lint (ruff)
run: ruff check .

- name: Test (pytest)
run: pytest tests/
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ apps/*/output/

# Legacy directories (use canonical paths in apps/)
whatsapp_notion_bot/
interfaces/web/
deploy/
monarch_phase1/

# Local CI verification venv (not committed)
.venv-ci/

# Binary/docs
*.docx
*.pdf
Expand Down
6 changes: 3 additions & 3 deletions agents/architecture.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from agents.base import BaseAgent, SONNET_MODEL
from agents.base import OPUS_MODEL, BaseAgent
from core.task import Task

_SYSTEM = """You are the Architecture Agent for Monarch AI.
Expand Down Expand Up @@ -26,7 +26,7 @@
class ArchitectureAgent(BaseAgent):
name = "architecture"
display_name = "Carla - Arquitetura"
model = SONNET_MODEL
model = OPUS_MODEL
system_prompt = _SYSTEM

async def build_user_message(self, task: Task) -> str:
Expand All @@ -43,7 +43,7 @@ async def run(self, task: Task):
result = await super().run(task)
task.architecture = result.output
task.add_history(
agent=self.label,
agent=self.name,
action="architecture_complete",
detail=f"new_files={len(result.output.get('new_files', []))} modified={len(result.output.get('modified_files', []))}",
)
Expand Down
5 changes: 2 additions & 3 deletions agents/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import logging
import os
import re
import sys
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from pathlib import Path
Expand Down Expand Up @@ -251,7 +250,7 @@ async def _handle_ask_user(self, question: str) -> str:
print(f"{'='*60}\n")
if self._current_task:
self._current_task.add_history(
agent=self.label,
agent=self.name,
action="asked_user",
detail=f"Q: {question[:80]} | A: {answer[:80]}",
)
Expand Down Expand Up @@ -346,7 +345,7 @@ async def run(self, task: Task) -> AgentResult:
interactive = os.environ.get("MONARCH_INTERACTIVE", "0") == "1" or self._ask_user_fn is not None
extra = [_ASK_USER_TOOL] if interactive else []
all_tools = (self.tools or []) + extra
message = await self._call_claude_api(messages, all_tools or None)
message = await self._call_claude(messages, all_tools or None)

while message.stop_reason == "tool_use":
message = await self._handle_tool_use(message, messages)
Expand Down
5 changes: 2 additions & 3 deletions agents/deploy.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import json
import logging
from typing import Any

from agents.base import BaseAgent, SONNET_MODEL
from agents.base import SONNET_MODEL, BaseAgent
from core.task import Task
from tools.github_tools import GitHubTools

Expand Down Expand Up @@ -124,7 +123,7 @@ async def run(self, task: Task):

task.deploy_report = result.output
task.add_history(
agent=self.label,
agent=self.name,
action="deploy_config_complete",
detail=(
f"type={result.output.get('project_type')} "
Expand Down
6 changes: 3 additions & 3 deletions agents/devils_advocate.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from agents.base import BaseAgent, SONNET_MODEL
from agents.base import OPUS_MODEL, BaseAgent
from core.task import Task

_SYSTEM = """You are the Devil's Advocate Agent for Monarch AI.
Expand Down Expand Up @@ -29,7 +29,7 @@
class DevilsAdvocateAgent(BaseAgent):
name = "devils_advocate"
display_name = "Ewerton - Advogado do Diabo"
model = SONNET_MODEL
model = OPUS_MODEL
system_prompt = _SYSTEM

async def build_user_message(self, task: Task) -> str:
Expand All @@ -51,7 +51,7 @@ async def run(self, task: Task):
approved = result.output.get("approved", False)
issues_count = len(result.output.get("issues", []))
task.add_history(
agent=self.label,
agent=self.name,
action="review_complete",
detail=f"approved={approved} issues={issues_count}",
)
Expand Down
6 changes: 3 additions & 3 deletions agents/discovery.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from agents.base import BaseAgent, SONNET_MODEL
from agents.base import OPUS_MODEL, BaseAgent
from core.task import Task

_SYSTEM = """You are the Discovery Agent for Monarch AI — a multi-agent system that
Expand All @@ -24,7 +24,7 @@
class DiscoveryAgent(BaseAgent):
name = "discovery"
display_name = "Alice - Descoberta"
model = SONNET_MODEL
model = OPUS_MODEL
system_prompt = _SYSTEM

async def build_user_message(self, task: Task) -> str:
Expand All @@ -38,7 +38,7 @@ async def run(self, task: Task):
# Persist the structured requirements back onto the task
task.requirements = result.output
task.add_history(
agent=self.label,
agent=self.name,
action="discovery_complete",
detail=f"complexity={result.output.get('complexity')} confidence={result.confidence:.2f}",
)
Expand Down
7 changes: 3 additions & 4 deletions agents/documentation.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import json
import logging
from typing import Any

from agents.base import BaseAgent, SONNET_MODEL
from agents.base import HAIKU_MODEL, BaseAgent
from core.task import Task
from tools.github_tools import GitHubTools

Expand Down Expand Up @@ -33,7 +32,7 @@
class DocumentationAgent(BaseAgent):
name = "documentation"
display_name = "Karla - Documentação"
model = SONNET_MODEL
model = HAIKU_MODEL
system_prompt = _SYSTEM

def __init__(self) -> None:
Expand All @@ -54,7 +53,7 @@ async def build_user_message(self, task: Task) -> str:
async def run(self, task: Task):
result = await super().run(task)
task.add_history(
agent=self.label,
agent=self.name,
action="documentation_complete",
detail=f"changelog_entry={'yes' if result.output.get('changelog_entry') else 'no'}",
)
Expand Down
10 changes: 5 additions & 5 deletions agents/implementer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
import logging
from typing import Any

from agents.base import BaseAgent, SONNET_MODEL
from agents.base import OPUS_MODEL, BaseAgent
from config import config
from core.task import Task
from tools.github_tools import GitHubTools
from tools.fs_tools import FsTools
from tools.github_tools import GitHubTools

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -53,7 +53,7 @@
class ImplementerAgent(BaseAgent):
name = "implementer"
display_name = "Fernanda - Implementação"
model = config.implementer_model or SONNET_MODEL
model = config.implementer_model or OPUS_MODEL
max_tokens = config.implementer_max_tokens
system_prompt = _SYSTEM

Expand All @@ -63,7 +63,7 @@ def __init__(self) -> None:
self._fs = FsTools()

@property
def system_prompt(self) -> str: # type: ignore[override]
def system_prompt(self) -> str: # type: ignore[override] # noqa: F811 (property overrides the class-level default for local mode)
return _SYSTEM_LOCAL if config.local_mode else _SYSTEM

@property
Expand Down Expand Up @@ -236,7 +236,7 @@ async def run(self, task: Task):

files = result.output.get("files_written", [])
task.add_history(
agent=self.label,
agent=self.name,
action="implementation_complete",
detail=f"files_written={len(files)}",
)
Expand Down
7 changes: 3 additions & 4 deletions agents/observability.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import json
import logging
from typing import Any

from agents.base import BaseAgent, SONNET_MODEL
from agents.base import HAIKU_MODEL, BaseAgent
from core.task import Task

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -31,7 +30,7 @@
class ObservabilityAgent(BaseAgent):
name = "observability"
display_name = "Lucas - Observabilidade"
model = SONNET_MODEL
model = HAIKU_MODEL
system_prompt = _SYSTEM

async def build_user_message(self, task: Task) -> str:
Expand All @@ -48,7 +47,7 @@ async def run(self, task: Task):
result = await super().run(task)
metrics_count = len(result.output.get("metrics_to_add", []))
task.add_history(
agent=self.label,
agent=self.name,
action="observability_complete",
detail=f"metrics={metrics_count} alerts={len(result.output.get('alerts_to_configure', []))}",
)
Expand Down
6 changes: 3 additions & 3 deletions agents/planning.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from agents.base import BaseAgent, SONNET_MODEL
from agents.base import OPUS_MODEL, BaseAgent
from core.task import Task

_SYSTEM = """You are the Planning Agent for Monarch AI.
Expand Down Expand Up @@ -31,7 +31,7 @@
class PlanningAgent(BaseAgent):
name = "planning"
display_name = "Diego - Planejamento"
model = SONNET_MODEL
model = OPUS_MODEL
system_prompt = _SYSTEM

async def build_user_message(self, task: Task) -> str:
Expand All @@ -51,7 +51,7 @@ async def run(self, task: Task):
if result.output.get("branch_name"):
task.branch_name = result.output["branch_name"]
task.add_history(
agent=self.label,
agent=self.name,
action="planning_complete",
detail=f"steps={len(task.plan)} branch={task.branch_name}",
)
Expand Down
4 changes: 2 additions & 2 deletions agents/prioritization.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from agents.base import BaseAgent, SONNET_MODEL
from agents.base import SONNET_MODEL, BaseAgent
from core.task import Task

_SYSTEM = """You are the Prioritization Agent for Monarch AI.
Expand Down Expand Up @@ -38,7 +38,7 @@ async def run(self, task: Task):
result = await super().run(task)
task.priority = result.output.get("priority", "medium")
task.add_history(
agent=self.label,
agent=self.name,
action="prioritization_complete",
detail=f"priority={task.priority} score={result.output.get('priority_score')}",
)
Expand Down
8 changes: 3 additions & 5 deletions agents/reviewer.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import json
import logging
from typing import Any

from agents.base import BaseAgent, SONNET_MODEL
from agents.base import OPUS_MODEL, BaseAgent
from core.task import Task
from tools.github_tools import GitHubTools

Expand Down Expand Up @@ -36,7 +34,7 @@
class ReviewerAgent(BaseAgent):
name = "reviewer"
display_name = "Helena - Revisão"
model = SONNET_MODEL
model = OPUS_MODEL
system_prompt = _SYSTEM

def __init__(self) -> None:
Expand Down Expand Up @@ -65,7 +63,7 @@ async def run(self, task: Task):
task.review_report = result.output
approved = result.output.get("approved", False)
task.add_history(
agent=self.label,
agent=self.name,
action="review_complete",
detail=f"approved={approved} quality={result.output.get('overall_quality')}",
)
Expand Down
7 changes: 3 additions & 4 deletions agents/security.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import json
import logging
from typing import Any

from agents.base import BaseAgent, SONNET_MODEL
from agents.base import OPUS_MODEL, BaseAgent
from core.task import Task

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -36,7 +35,7 @@
class SecurityAgent(BaseAgent):
name = "security"
display_name = "Igor - Segurança"
model = SONNET_MODEL
model = OPUS_MODEL
system_prompt = _SYSTEM

async def build_user_message(self, task: Task) -> str:
Expand All @@ -56,7 +55,7 @@ async def run(self, task: Task):
approved = result.output.get("approved", False)
risk = result.output.get("risk_level", "unknown")
task.add_history(
agent=self.label,
agent=self.name,
action="security_review_complete",
detail=f"approved={approved} risk={risk}",
)
Expand Down
5 changes: 2 additions & 3 deletions agents/testing.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import json
import logging
from typing import Any

from agents.base import BaseAgent, SONNET_MODEL
from agents.base import SONNET_MODEL, BaseAgent
from core.task import Task
from tools.code_tools import CodeTools

Expand Down Expand Up @@ -50,7 +49,7 @@ async def run(self, task: Task):
task.test_results = result.output
all_passed = result.output.get("all_passed", False)
task.add_history(
agent=self.label,
agent=self.name,
action="testing_complete",
detail=f"all_passed={all_passed}",
)
Expand Down
3 changes: 1 addition & 2 deletions apps/achadinhos/achadinhos/cli.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
"""CLI para Achadinhos."""
import csv
import json
import sys
from pathlib import Path

import rich.console
import rich.table
import typer

from achadinhos.config import settings
from achadinhos.models import ProductCandidate, ProductShortlist
from achadinhos.models import ProductCandidate
from achadinhos.pipeline import build_shortlist, render_shortlist_markdown, score_candidate

app = typer.Typer(help="Achadinhos — descubra, catogue e priorize produtos.")
Expand Down
2 changes: 1 addition & 1 deletion apps/achadinhos/tests/test_models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Testes para modelos do Achadinhos."""
from achadinhos.models import ProductCandidate, ScoredCandidate
from achadinhos.models import ProductCandidate
from achadinhos.pipeline import score_candidate


Expand Down
Loading
Loading