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
18 changes: 8 additions & 10 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,20 @@
# MCP servers have their own build contexts (./mcp/*) and are unaffected.

.git/
node_modules/
chroma_data/
data/
src/
mcp/
scripts/

# Node.js dependencies and build artifacts
src/node_modules
src/dist

# Python virtual environments and caches
backend/venv/
backend/.venv/
backend/__pycache__/
**/__pycache__/
**/*.pyc
**/*.pyo
**/*.pyd
backend/venv
backend/.venv
backend/__pycache__

# Runtime data that should not be baked into the image
backend/logs/
backend/logs
backend/.env
708 changes: 0 additions & 708 deletions .github/agents/Agent-Developer-Assistant/memory/MEMORY.md

This file was deleted.

3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ backend/logs/sessions/*.json
# Generated reports and retrieved docs
data/reports/*
data/benchmarks/*
data/documents/*
data/documents/*
data/neo4j_data/*
4 changes: 1 addition & 3 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,8 @@ COPY docs /app/docs
# written inside the container are immediately visible on the host.
RUN mkdir -p /app/logs/sessions


# Expose API port
EXPOSE 9999

# Run the API server
CMD ["uvicorn", "api_server:app", "--host", "0.0.0.0", "--port", "9999"]

CMD ["uvicorn", "api_server:app", "--host", "0.0.0.0", "--port", "9999"]
23 changes: 16 additions & 7 deletions backend/orchestrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -868,8 +868,15 @@ async def plan(self, query: str) -> AsyncIterator[ResponseMessage]:
"\n\nRelevant prior research context (from long-term memory — "
"use to avoid re-investigating already-covered ground):\n"
+ prior_memories
+ "\n\n"
)

# Inject the current date to aid root agent with its temporal reasoning and source evaluation
# (e.g. "if your training cutoff is in 2021 but today's date is 2024, you should prioritize
# current sources and be skeptical of outdated info in your training data").
current_time = datetime.now(timezone.utc).today().strftime("%m:%d:%Y")
plan_prompt += f"\n\nCurrent date: {current_time}\n\n"

root_messages = [
Message(role="system", content=self._root_system_prompt()),
Message(role="user", content=plan_prompt),
Expand Down Expand Up @@ -1797,7 +1804,7 @@ async def synthesize(self) -> AsyncIterator[ResponseMessage]:
"- A short section title\n"
"- One sentence describing what the section will cover\n\n"
"Return a JSON object:\n"
'{"sections": [{"title": "...", "description": "..."}, ...]}'
'{"report_title": "...", "sections": [{"title": "...", "description": "..."}, ...]}'
)

outline_response = await self.agents.report.run(
Expand All @@ -1822,6 +1829,7 @@ async def synthesize(self) -> AsyncIterator[ResponseMessage]:
# Guard against None/empty content — both produce a JSONDecodeError or
# TypeError that the except block would swallow silently.
sections: List[Dict[str, str]] = []
report_title: str = query
try:
raw = outline_response.content or ""
if raw.startswith("```"):
Expand All @@ -1831,7 +1839,9 @@ async def synthesize(self) -> AsyncIterator[ResponseMessage]:
elif "```" in raw:
raw = raw.split("```")[1].split("```")[0].strip()
if raw:
sections = json.loads(raw).get("sections", [])
parsed = json.loads(raw)
sections = parsed.get("sections", [])
report_title = parsed.get("report_title", query)
else:
logger.warning(
"[Orchestrator] Outline response was empty after retry; using defaults"
Expand Down Expand Up @@ -2103,7 +2113,7 @@ async def synthesize(self) -> AsyncIterator[ResponseMessage]:
]

doc_parts: List[str] = [
f"RESEARCH REPORT",
f"RESEARCH REPORT: {report_title}",
f"Query: {query}",
"",
]
Expand Down Expand Up @@ -2147,14 +2157,13 @@ async def synthesize(self) -> AsyncIterator[ResponseMessage]:
try:
from report_exporter import export_report_pdf

await export_report_pdf(document, query, self.session_id)
await export_report_pdf(document, query, report_title, self.session_id)
except Exception as _pdf_exc:
logger.warning("[Orchestrator] PDF export error: %s", _pdf_exc)

# ── Extract structured metadata for downstream consumers ────────────
# title: query is the ground truth; report header carries no LLM-derived
# title in the multi-pass flow, so use the query directly.
report_title = query
# title was derived from the outline prompt during Phase A; falls back
# to the original query if the LLM did not supply one.

# key_findings: content of the first section whose title contains
# "finding" (case-insensitive), empty string if no such section exists.
Expand Down
4 changes: 3 additions & 1 deletion backend/report_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ def footer(self) -> None:
async def export_report_pdf(
document: str,
query: str,
title: str = "",
session_id: Optional[str] = None,
) -> Optional[Path]:
"""
Expand All @@ -244,7 +245,8 @@ async def export_report_pdf(
try:
reports_dir = _get_reports_dir()
date_str = datetime.now(timezone.utc).strftime("%Y-%m-%d")
slug = _query_to_slug(query)
slug_base = title or query
slug = _query_to_slug(slug_base)
sid_part = (session_id or "cli")[:8]
filename = f"{date_str}_{sid_part}_{slug}.pdf"
output_path = reports_dir / filename
Expand Down
8 changes: 4 additions & 4 deletions docker-compose-full.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ services:
- NEO4J_PLUGINS=["apoc"]
- NEO4J_server_memory_heap_max__size=1G
volumes:
- neo4j_data:/data
- ./data/neo4j_data:/data
restart: unless-stopped
networks:
- research-network
Expand Down Expand Up @@ -103,7 +103,7 @@ services:
networks:
- research-network
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:9393/health" ]
test: ["CMD", "curl", "-f", "http://localhost:9393/health"]
interval: 5s
timeout: 3s
retries: 10
Expand All @@ -120,7 +120,7 @@ services:
networks:
- research-network
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:9292/health" ]
test: ["CMD", "curl", "-f", "http://localhost:9292/health"]
interval: 5s
timeout: 3s
retries: 10
Expand All @@ -139,7 +139,7 @@ services:
networks:
- research-network
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:9191/health" ]
test: ["CMD", "curl", "-f", "http://localhost:9191/health"]
interval: 5s
timeout: 3s
retries: 10
Expand Down
Loading