mirror of
https://github.com/open-jarvis/OpenJarvis.git
synced 2026-07-28 14:07:55 +00:00
* chore: create learning subdirectory structure (routing, agents, intelligence) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: extract classify_query to routing/_utils.py Move the classify_query() function and its regex patterns into a shared utility module so multiple routing policies can import it without depending on the full trace_policy module. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: move routing files to learning/routing/ subdirectory Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: create LearnedRouterPolicy merging trace-driven + SFT routing Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add conditional Algolia DocSearch integration Add Algolia DocSearch as an optional search upgrade — native lunr.js search remains the default until credentials are configured. Includes CDN assets, Jinja2 conditional config injection, init script with graceful fallback, light/dark theme CSS, improved search tokenization for snake_case/dotted identifiers, and search boosts for key pages. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: move agent_evolver and skill_discovery to learning/agents/ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: move learning/orchestrator to learning/intelligence/orchestrator Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: delete removed learning policies, rewrite __init__.py, clean up api_routes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add SFT/GRPO/DSPy/GEPA config dataclasses, update LearningConfig Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add general-purpose SFT trainer (intelligence/sft_trainer.py) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: update stale imports in multi_model_router example Update imports to use new learning/routing/ paths after the subdirectory reorganization. Replace BanditRouterPolicy with LearnedRouterPolicy. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add general-purpose GRPO trainer (intelligence/grpo_trainer.py) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add DSPy agent optimizer (agents/dspy_optimizer.py) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add GEPA agent optimizer (agents/gepa_optimizer.py) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add learning-dspy and learning-gepa optional dependency extras Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: update integration test to check for learned policy instead of grpo Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: clean up stale APIs and unused params in examples - deep_research: remove system_prompt and max_turns params not accepted by Jarvis.ask(), inline system prompt into the query instead - doc_qa: remove unused --top-k CLI arg that was never passed to the API - multi_model_router: fix select_model() call to match single-arg signature Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: import SFT/GRPO trainers in intelligence/__init__.py for registry Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: remove .md file changes from PR Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: restore search boost frontmatter for key docs pages Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
119 lines
3.2 KiB
Python
119 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Deep Research Assistant — multi-source research with memory-augmented orchestrator.
|
|
|
|
Usage:
|
|
python examples/deep_research/research.py "quantum computing advances"
|
|
python examples/deep_research/research.py "climate policy" \
|
|
--model gpt-4o --engine cloud
|
|
python examples/deep_research/research.py "rust vs go" \
|
|
--output report.md
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
|
|
import click
|
|
|
|
|
|
@click.command()
|
|
@click.argument("topic")
|
|
@click.option(
|
|
"--model",
|
|
default="qwen3:8b",
|
|
show_default=True,
|
|
help="Model to use for research.",
|
|
)
|
|
@click.option(
|
|
"--engine",
|
|
"engine_key",
|
|
default="ollama",
|
|
show_default=True,
|
|
help="Engine backend (ollama, cloud, vllm, etc.).",
|
|
)
|
|
@click.option(
|
|
"--output",
|
|
default=None,
|
|
type=click.Path(),
|
|
help="Optional file path to save the research report.",
|
|
)
|
|
def main(
|
|
topic: str,
|
|
model: str,
|
|
engine_key: str,
|
|
output: str | None,
|
|
) -> None:
|
|
"""Run a deep research session on TOPIC using an orchestrator agent.
|
|
|
|
The agent searches the web, stores findings in memory, cross-references
|
|
sources, and produces a comprehensive report with citations.
|
|
"""
|
|
# Lazy import so that --help works without a running engine or heavy deps.
|
|
try:
|
|
from openjarvis import Jarvis
|
|
except ImportError:
|
|
click.echo(
|
|
"Error: openjarvis is not installed. "
|
|
"Install it with: uv sync --extra dev",
|
|
err=True,
|
|
)
|
|
sys.exit(1)
|
|
|
|
tools = ["web_search", "think", "file_write", "memory_store", "memory_search"]
|
|
|
|
system_prompt = (
|
|
"You are a deep research assistant. When given a topic:\n"
|
|
"1. Search the web for recent, authoritative sources\n"
|
|
"2. Store key findings in memory for cross-referencing\n"
|
|
"3. Synthesize a comprehensive report with citations\n"
|
|
"4. Save the final report to a file\n\n"
|
|
"Always cite your sources and distinguish between established facts "
|
|
"and emerging claims."
|
|
)
|
|
|
|
click.echo(f"Researching: {topic}")
|
|
click.echo(f"Model: {model} | Engine: {engine_key}")
|
|
click.echo("-" * 60)
|
|
|
|
try:
|
|
j = Jarvis(model=model, engine_key=engine_key)
|
|
except Exception as exc:
|
|
click.echo(
|
|
f"Error: could not initialize Jarvis — {exc}\n\n"
|
|
"Make sure your engine is running. For Ollama:\n"
|
|
" ollama serve\n"
|
|
" ollama pull qwen3:8b\n\n"
|
|
"For cloud engines, ensure API keys are set in your .env file.",
|
|
err=True,
|
|
)
|
|
sys.exit(1)
|
|
|
|
try:
|
|
prompt = (
|
|
f"{system_prompt}\n\n"
|
|
"Research the following topic in depth "
|
|
f"and produce a report:\n\n{topic}"
|
|
)
|
|
response = j.ask(
|
|
prompt,
|
|
agent="orchestrator",
|
|
tools=tools,
|
|
temperature=0.5,
|
|
)
|
|
except Exception as exc:
|
|
click.echo(f"Error during research: {exc}", err=True)
|
|
sys.exit(1)
|
|
finally:
|
|
j.close()
|
|
|
|
click.echo(response)
|
|
|
|
if output:
|
|
with open(output, "w", encoding="utf-8") as fh:
|
|
fh.write(response)
|
|
click.echo(f"\nReport saved to {output}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|