aurelian 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aurelian/__init__.py +9 -0
- aurelian/agents/__init__.py +0 -0
- aurelian/agents/amigo/__init__.py +3 -0
- aurelian/agents/amigo/amigo_agent.py +77 -0
- aurelian/agents/amigo/amigo_config.py +85 -0
- aurelian/agents/amigo/amigo_evals.py +73 -0
- aurelian/agents/amigo/amigo_gradio.py +52 -0
- aurelian/agents/amigo/amigo_mcp.py +152 -0
- aurelian/agents/amigo/amigo_tools.py +152 -0
- aurelian/agents/biblio/__init__.py +42 -0
- aurelian/agents/biblio/biblio_agent.py +95 -0
- aurelian/agents/biblio/biblio_config.py +40 -0
- aurelian/agents/biblio/biblio_gradio.py +67 -0
- aurelian/agents/biblio/biblio_mcp.py +115 -0
- aurelian/agents/biblio/biblio_tools.py +164 -0
- aurelian/agents/biblio_agent.py +46 -0
- aurelian/agents/checklist/__init__.py +44 -0
- aurelian/agents/checklist/checklist_agent.py +86 -0
- aurelian/agents/checklist/checklist_config.py +28 -0
- aurelian/agents/checklist/checklist_gradio.py +70 -0
- aurelian/agents/checklist/checklist_mcp.py +86 -0
- aurelian/agents/checklist/checklist_tools.py +141 -0
- aurelian/agents/checklist/content/checklists.yaml +7 -0
- aurelian/agents/checklist/content/streams.csv +136 -0
- aurelian/agents/checklist_agent.py +40 -0
- aurelian/agents/chemistry/__init__.py +3 -0
- aurelian/agents/chemistry/chemistry_agent.py +47 -0
- aurelian/agents/chemistry/chemistry_config.py +71 -0
- aurelian/agents/chemistry/chemistry_evals.py +79 -0
- aurelian/agents/chemistry/chemistry_gradio.py +50 -0
- aurelian/agents/chemistry/chemistry_mcp.py +120 -0
- aurelian/agents/chemistry/chemistry_tools.py +121 -0
- aurelian/agents/chemistry/image_agent.py +15 -0
- aurelian/agents/d4d/__init__.py +30 -0
- aurelian/agents/d4d/d4d_agent.py +73 -0
- aurelian/agents/d4d/d4d_config.py +46 -0
- aurelian/agents/d4d/d4d_gradio.py +58 -0
- aurelian/agents/d4d/d4d_mcp.py +71 -0
- aurelian/agents/d4d/d4d_tools.py +157 -0
- aurelian/agents/d4d_agent.py +64 -0
- aurelian/agents/diagnosis/__init__.py +33 -0
- aurelian/agents/diagnosis/diagnosis_agent.py +54 -0
- aurelian/agents/diagnosis/diagnosis_config.py +48 -0
- aurelian/agents/diagnosis/diagnosis_evals.py +76 -0
- aurelian/agents/diagnosis/diagnosis_gradio.py +52 -0
- aurelian/agents/diagnosis/diagnosis_mcp.py +141 -0
- aurelian/agents/diagnosis/diagnosis_tools.py +204 -0
- aurelian/agents/diagnosis_agent.py +28 -0
- aurelian/agents/draw/__init__.py +3 -0
- aurelian/agents/draw/draw_agent.py +39 -0
- aurelian/agents/draw/draw_config.py +26 -0
- aurelian/agents/draw/draw_gradio.py +50 -0
- aurelian/agents/draw/draw_mcp.py +94 -0
- aurelian/agents/draw/draw_tools.py +100 -0
- aurelian/agents/draw/judge_agent.py +18 -0
- aurelian/agents/filesystem/__init__.py +0 -0
- aurelian/agents/filesystem/filesystem_config.py +27 -0
- aurelian/agents/filesystem/filesystem_gradio.py +49 -0
- aurelian/agents/filesystem/filesystem_mcp.py +89 -0
- aurelian/agents/filesystem/filesystem_tools.py +95 -0
- aurelian/agents/filesystem/py.typed +0 -0
- aurelian/agents/github/__init__.py +0 -0
- aurelian/agents/github/github_agent.py +83 -0
- aurelian/agents/github/github_cli.py +248 -0
- aurelian/agents/github/github_config.py +22 -0
- aurelian/agents/github/github_gradio.py +152 -0
- aurelian/agents/github/github_mcp.py +252 -0
- aurelian/agents/github/github_tools.py +408 -0
- aurelian/agents/github/github_tools.py.tmp +413 -0
- aurelian/agents/goann/__init__.py +13 -0
- aurelian/agents/goann/documents/Transcription_Factors_Annotation_Guidelines.md +1000 -0
- aurelian/agents/goann/documents/Transcription_Factors_Annotation_Guidelines.pdf +0 -0
- aurelian/agents/goann/documents/Transcription_Factors_Annotation_Guidelines_Paper.md +693 -0
- aurelian/agents/goann/documents/Transcription_Factors_Annotation_Guidelines_Paper.pdf +0 -0
- aurelian/agents/goann/goann_agent.py +90 -0
- aurelian/agents/goann/goann_config.py +90 -0
- aurelian/agents/goann/goann_evals.py +104 -0
- aurelian/agents/goann/goann_gradio.py +62 -0
- aurelian/agents/goann/goann_mcp.py +0 -0
- aurelian/agents/goann/goann_tools.py +65 -0
- aurelian/agents/gocam/__init__.py +52 -0
- aurelian/agents/gocam/documents/DNA-binding transcription factor activity annotation guidelines.docx +0 -0
- aurelian/agents/gocam/documents/DNA-binding transcription factor activity annotation guidelines.pdf +0 -0
- aurelian/agents/gocam/documents/DNA-binding_transcription_factor_activity_annotation_guidelines.md +100 -0
- aurelian/agents/gocam/documents/E3 ubiquitin ligases.docx +0 -0
- aurelian/agents/gocam/documents/E3 ubiquitin ligases.pdf +0 -0
- aurelian/agents/gocam/documents/E3_ubiquitin_ligases.md +134 -0
- aurelian/agents/gocam/documents/GO-CAM annotation guidelines README.docx +0 -0
- aurelian/agents/gocam/documents/GO-CAM annotation guidelines README.pdf +0 -0
- aurelian/agents/gocam/documents/GO-CAM modelling guidelines TO DO.docx +0 -0
- aurelian/agents/gocam/documents/GO-CAM modelling guidelines TO DO.pdf +0 -0
- aurelian/agents/gocam/documents/GO-CAM_annotation_guidelines_README.md +1 -0
- aurelian/agents/gocam/documents/GO-CAM_modelling_guidelines_TO_DO.md +3 -0
- aurelian/agents/gocam/documents/How to annotate complexes in GO-CAM.docx +0 -0
- aurelian/agents/gocam/documents/How to annotate complexes in GO-CAM.pdf +0 -0
- aurelian/agents/gocam/documents/How to annotate molecular adaptors.docx +0 -0
- aurelian/agents/gocam/documents/How to annotate molecular adaptors.pdf +0 -0
- aurelian/agents/gocam/documents/How to annotate sequestering proteins.docx +0 -0
- aurelian/agents/gocam/documents/How to annotate sequestering proteins.pdf +0 -0
- aurelian/agents/gocam/documents/How_to_annotate_complexes_in_GO-CAM.md +29 -0
- aurelian/agents/gocam/documents/How_to_annotate_molecular_adaptors.md +31 -0
- aurelian/agents/gocam/documents/How_to_annotate_sequestering_proteins.md +42 -0
- aurelian/agents/gocam/documents/Molecular adaptor activity.docx +0 -0
- aurelian/agents/gocam/documents/Molecular adaptor activity.pdf +0 -0
- aurelian/agents/gocam/documents/Molecular carrier activity.docx +0 -0
- aurelian/agents/gocam/documents/Molecular carrier activity.pdf +0 -0
- aurelian/agents/gocam/documents/Molecular_adaptor_activity.md +51 -0
- aurelian/agents/gocam/documents/Molecular_carrier_activity.md +41 -0
- aurelian/agents/gocam/documents/Protein sequestering activity.docx +0 -0
- aurelian/agents/gocam/documents/Protein sequestering activity.pdf +0 -0
- aurelian/agents/gocam/documents/Protein_sequestering_activity.md +50 -0
- aurelian/agents/gocam/documents/Signaling receptor activity annotation guidelines.docx +0 -0
- aurelian/agents/gocam/documents/Signaling receptor activity annotation guidelines.pdf +0 -0
- aurelian/agents/gocam/documents/Signaling_receptor_activity_annotation_guidelines.md +187 -0
- aurelian/agents/gocam/documents/Transcription coregulator activity.docx +0 -0
- aurelian/agents/gocam/documents/Transcription coregulator activity.pdf +0 -0
- aurelian/agents/gocam/documents/Transcription_coregulator_activity.md +36 -0
- aurelian/agents/gocam/documents/Transporter activity annotation annotation guidelines.docx +0 -0
- aurelian/agents/gocam/documents/Transporter activity annotation annotation guidelines.pdf +0 -0
- aurelian/agents/gocam/documents/Transporter_activity_annotation_annotation_guidelines.md +43 -0
- Regulatory Processes in GO-CAM.docx +0 -0
- Regulatory Processes in GO-CAM.pdf +0 -0
- aurelian/agents/gocam/documents/WIP_-_Regulation_and_Regulatory_Processes_in_GO-CAM.md +31 -0
- aurelian/agents/gocam/documents/md/DNA-binding_transcription_factor_activity_annotation_guidelines.md +131 -0
- aurelian/agents/gocam/documents/md/E3_ubiquitin_ligases.md +166 -0
- aurelian/agents/gocam/documents/md/GO-CAM_annotation_guidelines_README.md +1 -0
- aurelian/agents/gocam/documents/md/GO-CAM_modelling_guidelines_TO_DO.md +5 -0
- aurelian/agents/gocam/documents/md/How_to_annotate_complexes_in_GO-CAM.md +28 -0
- aurelian/agents/gocam/documents/md/How_to_annotate_molecular_adaptors.md +19 -0
- aurelian/agents/gocam/documents/md/How_to_annotate_sequestering_proteins.md +38 -0
- aurelian/agents/gocam/documents/md/Molecular_adaptor_activity.md +52 -0
- aurelian/agents/gocam/documents/md/Molecular_carrier_activity.md +59 -0
- aurelian/agents/gocam/documents/md/Protein_sequestering_activity.md +52 -0
- aurelian/agents/gocam/documents/md/Signaling_receptor_activity_annotation_guidelines.md +271 -0
- aurelian/agents/gocam/documents/md/Transcription_coregulator_activity.md +54 -0
- aurelian/agents/gocam/documents/md/Transporter_activity_annotation_annotation_guidelines.md +38 -0
- aurelian/agents/gocam/documents/md/WIP_-_Regulation_and_Regulatory_Processes_in_GO-CAM.md +39 -0
- aurelian/agents/gocam/documents/pandoc_md/Signaling_receptor_activity_annotation_guidelines.md +334 -0
- aurelian/agents/gocam/gocam_agent.py +243 -0
- aurelian/agents/gocam/gocam_config.py +85 -0
- aurelian/agents/gocam/gocam_curator_agent.py +46 -0
- aurelian/agents/gocam/gocam_evals.py +64 -0
- aurelian/agents/gocam/gocam_gradio.py +89 -0
- aurelian/agents/gocam/gocam_mcp.py +224 -0
- aurelian/agents/gocam/gocam_tools.py +294 -0
- aurelian/agents/linkml/__init__.py +0 -0
- aurelian/agents/linkml/linkml_agent.py +62 -0
- aurelian/agents/linkml/linkml_config.py +48 -0
- aurelian/agents/linkml/linkml_evals.py +66 -0
- aurelian/agents/linkml/linkml_gradio.py +45 -0
- aurelian/agents/linkml/linkml_mcp.py +181 -0
- aurelian/agents/linkml/linkml_tools.py +102 -0
- aurelian/agents/literature/__init__.py +3 -0
- aurelian/agents/literature/literature_agent.py +75 -0
- aurelian/agents/literature/literature_config.py +35 -0
- aurelian/agents/literature/literature_gradio.py +52 -0
- aurelian/agents/literature/literature_mcp.py +174 -0
- aurelian/agents/literature/literature_tools.py +182 -0
- aurelian/agents/monarch/__init__.py +0 -0
- aurelian/agents/monarch/monarch_agent.py +45 -0
- aurelian/agents/monarch/monarch_config.py +45 -0
- aurelian/agents/monarch/monarch_gradio.py +51 -0
- aurelian/agents/monarch/monarch_mcp.py +65 -0
- aurelian/agents/monarch/monarch_tools.py +112 -0
- aurelian/agents/oak/__init__.py +0 -0
- aurelian/agents/oak/oak_config.py +27 -0
- aurelian/agents/oak/oak_gradio.py +57 -0
- aurelian/agents/ontology_mapper/__init__.py +31 -0
- aurelian/agents/ontology_mapper/ontology_mapper_agent.py +57 -0
- aurelian/agents/ontology_mapper/ontology_mapper_config.py +50 -0
- aurelian/agents/ontology_mapper/ontology_mapper_evals.py +108 -0
- aurelian/agents/ontology_mapper/ontology_mapper_gradio.py +58 -0
- aurelian/agents/ontology_mapper/ontology_mapper_mcp.py +81 -0
- aurelian/agents/ontology_mapper/ontology_mapper_tools.py +147 -0
- aurelian/agents/paperqa/__init__.py +27 -0
- aurelian/agents/paperqa/paperqa_agent.py +66 -0
- aurelian/agents/paperqa/paperqa_cli.py +305 -0
- aurelian/agents/paperqa/paperqa_config.py +142 -0
- aurelian/agents/paperqa/paperqa_gradio.py +90 -0
- aurelian/agents/paperqa/paperqa_mcp.py +155 -0
- aurelian/agents/paperqa/paperqa_tools.py +566 -0
- aurelian/agents/phenopackets/__init__.py +3 -0
- aurelian/agents/phenopackets/phenopackets_agent.py +58 -0
- aurelian/agents/phenopackets/phenopackets_config.py +72 -0
- aurelian/agents/phenopackets/phenopackets_evals.py +99 -0
- aurelian/agents/phenopackets/phenopackets_gradio.py +55 -0
- aurelian/agents/phenopackets/phenopackets_mcp.py +178 -0
- aurelian/agents/phenopackets/phenopackets_tools.py +127 -0
- aurelian/agents/rag/__init__.py +40 -0
- aurelian/agents/rag/rag_agent.py +84 -0
- aurelian/agents/rag/rag_config.py +80 -0
- aurelian/agents/rag/rag_gradio.py +67 -0
- aurelian/agents/rag/rag_mcp.py +107 -0
- aurelian/agents/rag/rag_tools.py +189 -0
- aurelian/agents/rag_agent.py +54 -0
- aurelian/agents/robot/__init__.py +0 -0
- aurelian/agents/robot/assets/__init__.py +3 -0
- aurelian/agents/robot/assets/template.md +384 -0
- aurelian/agents/robot/robot_config.py +25 -0
- aurelian/agents/robot/robot_gradio.py +46 -0
- aurelian/agents/robot/robot_mcp.py +100 -0
- aurelian/agents/robot/robot_ontology_agent.py +139 -0
- aurelian/agents/robot/robot_tools.py +50 -0
- aurelian/agents/talisman/__init__.py +3 -0
- aurelian/agents/talisman/__main__.py +17 -0
- aurelian/agents/talisman/cli.py +70 -0
- aurelian/agents/talisman/run_talisman.py +18 -0
- aurelian/agents/talisman/talisman_agent.py +143 -0
- aurelian/agents/talisman/talisman_config.py +66 -0
- aurelian/agents/talisman/talisman_gradio.py +50 -0
- aurelian/agents/talisman/talisman_mcp.py +75 -0
- aurelian/agents/talisman/talisman_tools.py +962 -0
- aurelian/agents/ubergraph/__init__.py +40 -0
- aurelian/agents/ubergraph/ubergraph_agent.py +72 -0
- aurelian/agents/ubergraph/ubergraph_config.py +79 -0
- aurelian/agents/ubergraph/ubergraph_gradio.py +48 -0
- aurelian/agents/ubergraph/ubergraph_mcp.py +69 -0
- aurelian/agents/ubergraph/ubergraph_tools.py +118 -0
- aurelian/agents/uniprot/__init__.py +0 -0
- aurelian/agents/uniprot/uniprot_agent.py +43 -0
- aurelian/agents/uniprot/uniprot_config.py +43 -0
- aurelian/agents/uniprot/uniprot_evals.py +99 -0
- aurelian/agents/uniprot/uniprot_gradio.py +48 -0
- aurelian/agents/uniprot/uniprot_mcp.py +168 -0
- aurelian/agents/uniprot/uniprot_tools.py +136 -0
- aurelian/agents/web/__init__.py +0 -0
- aurelian/agents/web/web_config.py +27 -0
- aurelian/agents/web/web_gradio.py +48 -0
- aurelian/agents/web/web_mcp.py +50 -0
- aurelian/agents/web/web_tools.py +121 -0
- aurelian/chat.py +23 -0
- aurelian/cli.py +1004 -0
- aurelian/dependencies/__init__.py +0 -0
- aurelian/dependencies/workdir.py +78 -0
- aurelian/evaluators/model.py +9 -0
- aurelian/evaluators/substring_evaluator.py +30 -0
- aurelian/mcp/__init__.py +0 -0
- aurelian/mcp/amigo_mcp_test.py +86 -0
- aurelian/mcp/config_generator.py +123 -0
- aurelian/mcp/example_config.json +43 -0
- aurelian/mcp/generate_sample_config.py +37 -0
- aurelian/mcp/gocam_mcp_test.py +126 -0
- aurelian/mcp/linkml_mcp_tools.py +190 -0
- aurelian/mcp/mcp_discovery.py +87 -0
- aurelian/mcp/mcp_test.py +31 -0
- aurelian/mcp/phenopackets_mcp_test.py +103 -0
- aurelian/tools/__init__.py +0 -0
- aurelian/tools/web/__init__.py +0 -0
- aurelian/tools/web/url_download.py +51 -0
- aurelian/utils/__init__.py +0 -0
- aurelian/utils/async_utils.py +18 -0
- aurelian/utils/data_utils.py +32 -0
- aurelian/utils/documentation_manager.py +59 -0
- aurelian/utils/doi_fetcher.py +238 -0
- aurelian/utils/ontology_utils.py +68 -0
- aurelian/utils/pdf_fetcher.py +23 -0
- aurelian/utils/process_logs.py +100 -0
- aurelian/utils/pubmed_utils.py +238 -0
- aurelian/utils/pytest_report_to_markdown.py +67 -0
- aurelian/utils/robot_ontology_utils.py +112 -0
- aurelian/utils/search_utils.py +95 -0
- aurelian-0.1.0.dist-info/LICENSE +22 -0
- aurelian-0.1.0.dist-info/METADATA +109 -0
- aurelian-0.1.0.dist-info/RECORD +266 -0
- aurelian-0.1.0.dist-info/WHEEL +4 -0
- aurelian-0.1.0.dist-info/entry_points.txt +4 -0
aurelian/cli.py
ADDED
@@ -0,0 +1,1004 @@
|
|
1
|
+
"""Command line interface for Aurelian agents."""
|
2
|
+
|
3
|
+
import logging
|
4
|
+
import os
|
5
|
+
from typing import Any, Awaitable, Callable, Optional, List
|
6
|
+
|
7
|
+
from aurelian.utils.async_utils import run_sync
|
8
|
+
import click
|
9
|
+
from pydantic_ai.models.openai import OpenAIModel
|
10
|
+
from pydantic_ai.providers.openai import OpenAIProvider
|
11
|
+
|
12
|
+
from aurelian import __version__
|
13
|
+
|
14
|
+
__all__ = [
|
15
|
+
"main",
|
16
|
+
]
|
17
|
+
|
18
|
+
logger = logging.getLogger(__name__)
|
19
|
+
|
20
|
+
|
21
|
+
def parse_multivalued(ctx, param, value: Optional[str]) -> Optional[List]:
|
22
|
+
"""Parse a comma-separated string into a list."""
|
23
|
+
if not value:
|
24
|
+
return None
|
25
|
+
return value.split(',') if isinstance(value, str) and ',' in value else [value]
|
26
|
+
|
27
|
+
|
28
|
+
# Common CLI options
|
29
|
+
model_option = click.option(
|
30
|
+
"--model",
|
31
|
+
"-m",
|
32
|
+
help="The model to use for the agent.",
|
33
|
+
)
|
34
|
+
use_cborg_option = click.option(
|
35
|
+
"--use-cborg/--no-use-cborg",
|
36
|
+
default=False,
|
37
|
+
show_default=True,
|
38
|
+
help="Use CBORG as a model proxy (LBNL account required).",
|
39
|
+
)
|
40
|
+
agent_option = click.option(
|
41
|
+
"--agent",
|
42
|
+
"-a",
|
43
|
+
help="The agent to use (if non-default).",
|
44
|
+
)
|
45
|
+
workdir_option = click.option(
|
46
|
+
"--workdir",
|
47
|
+
"-w",
|
48
|
+
default="workdir",
|
49
|
+
show_default=True,
|
50
|
+
help="The working directory for the agent.",
|
51
|
+
)
|
52
|
+
share_option = click.option(
|
53
|
+
"--share/--no-share",
|
54
|
+
default=False,
|
55
|
+
show_default=True,
|
56
|
+
help="Share the agent GradIO UI via URL.",
|
57
|
+
)
|
58
|
+
ui_option = click.option(
|
59
|
+
"--ui/--no-ui",
|
60
|
+
default=False,
|
61
|
+
show_default=True,
|
62
|
+
help="Start the agent in UI mode instead of direct query mode.",
|
63
|
+
)
|
64
|
+
run_evals_option = click.option(
|
65
|
+
"--run-evals/--no-run-evals",
|
66
|
+
default=False,
|
67
|
+
show_default=True,
|
68
|
+
help="Run the agent in evaluation mode.",
|
69
|
+
)
|
70
|
+
ontologies_option = click.option(
|
71
|
+
"--ontologies",
|
72
|
+
"-i",
|
73
|
+
callback=parse_multivalued,
|
74
|
+
help="Comma-separated list of ontologies to use for the agent.",
|
75
|
+
)
|
76
|
+
server_port_option = click.option(
|
77
|
+
"--server-port",
|
78
|
+
"-p",
|
79
|
+
default=7860,
|
80
|
+
show_default=True,
|
81
|
+
help="The port to run the UI server on.",
|
82
|
+
)
|
83
|
+
db_path_option = click.option(
|
84
|
+
"--db-path",
|
85
|
+
"-d",
|
86
|
+
help="The path to the database.",
|
87
|
+
)
|
88
|
+
collection_name_option = click.option(
|
89
|
+
"--collection-name",
|
90
|
+
"-c",
|
91
|
+
help="The name of the collection.",
|
92
|
+
)
|
93
|
+
|
94
|
+
|
95
|
+
@click.group()
|
96
|
+
@click.option("-v", "--verbose", count=True)
|
97
|
+
@click.option("-q", "--quiet")
|
98
|
+
@click.version_option(__version__)
|
99
|
+
def main(verbose: int, quiet: bool):
|
100
|
+
"""Main command for Aurelian.
|
101
|
+
|
102
|
+
Aurelian provides a collection of specialized agents for various scientific and biomedical tasks.
|
103
|
+
Each agent can be run in either direct query mode or UI mode:
|
104
|
+
|
105
|
+
- Direct query mode: Run the agent with a query (e.g., `aurelian diagnosis "patient with hypotonia"`).
|
106
|
+
- UI mode: Run the agent with `--ui` flag to start a chat interface.
|
107
|
+
|
108
|
+
Some agents also provide utility commands for specific operations.
|
109
|
+
|
110
|
+
:param verbose: Verbosity while running.
|
111
|
+
:param quiet: Boolean to be quiet or verbose.
|
112
|
+
"""
|
113
|
+
if verbose >= 2:
|
114
|
+
logger.setLevel(level=logging.DEBUG)
|
115
|
+
elif verbose == 1:
|
116
|
+
logger.setLevel(level=logging.INFO)
|
117
|
+
else:
|
118
|
+
logger.setLevel(level=logging.WARNING)
|
119
|
+
if quiet:
|
120
|
+
logger.setLevel(level=logging.ERROR)
|
121
|
+
import logfire
|
122
|
+
|
123
|
+
logfire.configure()
|
124
|
+
|
125
|
+
|
126
|
+
def split_options(kwargs, agent_keys: Optional[List]=None, extra_agent_keys: Optional[List] = None):
|
127
|
+
"""Split options into agent and launch options."""
|
128
|
+
if agent_keys is None:
|
129
|
+
agent_keys = ["model", "workdir", "ontologies", "db_path", "collection_name"]
|
130
|
+
if extra_agent_keys is not None:
|
131
|
+
agent_keys += extra_agent_keys
|
132
|
+
agent_options = {k: v for k, v in kwargs.items() if k in agent_keys}
|
133
|
+
launch_options = {k: v for k, v in kwargs.items() if k not in agent_keys}
|
134
|
+
return agent_options, launch_options
|
135
|
+
|
136
|
+
|
137
|
+
def run_agent(
|
138
|
+
agent_name: str,
|
139
|
+
agent_module: str,
|
140
|
+
query: Optional[tuple] = None,
|
141
|
+
ui: bool = False,
|
142
|
+
specialist_agent_name: Optional[str] = None,
|
143
|
+
agent_func_name: str = "run_sync",
|
144
|
+
join_char: str = " ",
|
145
|
+
use_cborg: bool = False,
|
146
|
+
**kwargs
|
147
|
+
) -> None:
|
148
|
+
"""Run an agent in either UI or direct query mode.
|
149
|
+
|
150
|
+
Args:
|
151
|
+
agent_name: Agent's name for import paths
|
152
|
+
agent_module: Fully qualified module path to the agent
|
153
|
+
query: Text query for direct mode
|
154
|
+
ui: Whether to force UI mode
|
155
|
+
specialist_agent_name: Name of the agent class to run
|
156
|
+
agent_func_name: Name of the function to run the agent
|
157
|
+
join_char: Character to join multi-part queries with
|
158
|
+
kwargs: Additional arguments for the agent
|
159
|
+
"""
|
160
|
+
# DEPRECATED: use the new agent command instead
|
161
|
+
# Import required modules
|
162
|
+
# These are imported dynamically to avoid loading all agents on startup
|
163
|
+
if not agent_module:
|
164
|
+
agent_module = f"aurelian.agents.{agent_name}"
|
165
|
+
if not specialist_agent_name:
|
166
|
+
specialist_agent_name = agent_name
|
167
|
+
gradio_module = __import__(f"{agent_module}.{agent_name}_gradio", fromlist=["chat"])
|
168
|
+
agent_class = __import__(f"{agent_module}.{agent_name}_agent", fromlist=[f"{specialist_agent_name}_agent"])
|
169
|
+
config_module = __import__(f"{agent_module}.{agent_name}_config", fromlist=["get_config"])
|
170
|
+
|
171
|
+
chat_func = gradio_module.chat
|
172
|
+
agent = getattr(agent_class, f"{specialist_agent_name}_agent")
|
173
|
+
get_config = config_module.get_config
|
174
|
+
|
175
|
+
# Process agent and UI options
|
176
|
+
agent_keys = ["model", "use_cborg", "workdir", "ontologies", "db_path", "collection_name"]
|
177
|
+
agent_options, launch_options = split_options(kwargs, agent_keys=agent_keys)
|
178
|
+
|
179
|
+
deps = get_config()
|
180
|
+
|
181
|
+
# Set workdir if provided
|
182
|
+
if 'workdir' in agent_options and agent_options['workdir']:
|
183
|
+
if hasattr(deps, 'workdir'):
|
184
|
+
deps.workdir.location = agent_options['workdir']
|
185
|
+
|
186
|
+
# Remove workdir from agent options to avoid duplicates
|
187
|
+
agent_run_options = {k: v for k, v in agent_options.items() if k != 'workdir'}
|
188
|
+
|
189
|
+
if use_cborg:
|
190
|
+
cborg_api_key = os.environ.get("CBORG_API_KEY")
|
191
|
+
model = OpenAIModel(
|
192
|
+
agent_run_options.get("model", kwargs.get("model", "openai:gpt-4o")),
|
193
|
+
provider=OpenAIProvider(
|
194
|
+
base_url="https://api.cborg.lbl.gov",
|
195
|
+
api_key=cborg_api_key),
|
196
|
+
)
|
197
|
+
print(f"CBORG model: {model}")
|
198
|
+
agent_run_options["model"] = model
|
199
|
+
|
200
|
+
# Run in appropriate mode
|
201
|
+
if not ui and query:
|
202
|
+
# Direct query mode
|
203
|
+
|
204
|
+
# Run the agent and print results
|
205
|
+
agent_run_func = getattr(agent, agent_func_name)
|
206
|
+
r = agent_run_func(join_char.join(query), deps=deps, **agent_run_options)
|
207
|
+
print(r.data)
|
208
|
+
mjb = r.all_messages_json()
|
209
|
+
# decode messages from json bytes to dict:
|
210
|
+
if isinstance(mjb, bytes):
|
211
|
+
mjb = mjb.decode()
|
212
|
+
# print the messages
|
213
|
+
import json
|
214
|
+
all_messages = json.loads(mjb)
|
215
|
+
import yaml
|
216
|
+
# print(yaml.dump(all_messages, indent=2))
|
217
|
+
else:
|
218
|
+
print(f"Running {agent_name} in UI mode, agent options: {agent_options}")
|
219
|
+
# UI mode
|
220
|
+
gradio_ui = chat_func(deps=deps, **agent_run_options)
|
221
|
+
gradio_ui.launch(**launch_options)
|
222
|
+
|
223
|
+
|
224
|
+
@main.command()
|
225
|
+
@agent_option
|
226
|
+
@model_option
|
227
|
+
@use_cborg_option
|
228
|
+
@share_option
|
229
|
+
@server_port_option
|
230
|
+
@workdir_option
|
231
|
+
@ui_option
|
232
|
+
@run_evals_option
|
233
|
+
@click.argument("query", nargs=-1, required=False)
|
234
|
+
def agent(ui, query, agent, use_cborg=False, run_evals=False, **kwargs):
|
235
|
+
"""NEW: Generic agent runner.
|
236
|
+
|
237
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
238
|
+
"""
|
239
|
+
if not agent:
|
240
|
+
raise click.UsageError("Error: --agent is required")
|
241
|
+
agent_module = f"aurelian.agents.{agent}"
|
242
|
+
specialist_agent_name = agent
|
243
|
+
gradio_module = __import__(f"{agent_module}.{agent}_gradio", fromlist=["chat"])
|
244
|
+
agent_class = __import__(f"{agent_module}.{agent}_agent", fromlist=[f"{specialist_agent_name}_agent"])
|
245
|
+
config_module = __import__(f"{agent_module}.{agent}_config", fromlist=["get_config"])
|
246
|
+
|
247
|
+
chat_func = gradio_module.chat
|
248
|
+
agent_obj = getattr(agent_class, f"{specialist_agent_name}_agent")
|
249
|
+
get_config = config_module.get_config
|
250
|
+
|
251
|
+
# Process agent and UI options
|
252
|
+
agent_keys = ["model", "use_cborg", "workdir", "ontologies", "db_path", "collection_name"]
|
253
|
+
agent_options, launch_options = split_options(kwargs, agent_keys=agent_keys)
|
254
|
+
|
255
|
+
deps = get_config()
|
256
|
+
|
257
|
+
# Set workdir if provided
|
258
|
+
if hasattr(deps, 'workdir'):
|
259
|
+
deps.workdir.location = kwargs['workdir']
|
260
|
+
|
261
|
+
# Remove workdir from agent options to avoid duplicates
|
262
|
+
agent_run_options = {k: v for k, v in agent_options.items() if k != 'workdir'}
|
263
|
+
|
264
|
+
# TODO: make this generic, for any proxy model
|
265
|
+
if use_cborg:
|
266
|
+
cborg_api_key = os.environ.get("CBORG_API_KEY")
|
267
|
+
model = OpenAIModel(
|
268
|
+
agent_run_options.get("model", "openai:gpt-4o"),
|
269
|
+
provider=OpenAIProvider(
|
270
|
+
base_url="https://api.cborg.lbl.gov",
|
271
|
+
api_key=cborg_api_key),
|
272
|
+
)
|
273
|
+
agent_run_options["model"] = model
|
274
|
+
|
275
|
+
# Run in appropriate mode
|
276
|
+
if not ui and query:
|
277
|
+
# Direct query mode
|
278
|
+
join_char = " "
|
279
|
+
# Run the agent and print results
|
280
|
+
agent_run_func = getattr(agent_obj, "run_sync")
|
281
|
+
r = agent_run_func(join_char.join(query), deps=deps, **agent_run_options)
|
282
|
+
print(r.data)
|
283
|
+
mjb = r.all_messages_json()
|
284
|
+
# decode messages from json bytes to dict:
|
285
|
+
if isinstance(mjb, bytes):
|
286
|
+
mjb = mjb.decode()
|
287
|
+
# print the messages
|
288
|
+
import json
|
289
|
+
all_messages = json.loads(mjb)
|
290
|
+
import yaml
|
291
|
+
# print(yaml.dump(all_messages, indent=2))
|
292
|
+
elif run_evals:
|
293
|
+
import sys
|
294
|
+
import importlib
|
295
|
+
# TODO: make this generic
|
296
|
+
package_name = f"{agent_module}.{agent}_evals"
|
297
|
+
module = importlib.import_module(package_name)
|
298
|
+
dataset = module.create_eval_dataset()
|
299
|
+
|
300
|
+
async def run_agent(inputs: str) -> Any:
|
301
|
+
result = await agent_obj.run(inputs, deps=deps, **agent_run_options)
|
302
|
+
return result.data
|
303
|
+
|
304
|
+
eval_func: Callable[[str], Awaitable[str]] = run_agent
|
305
|
+
report = dataset.evaluate_sync(eval_func)
|
306
|
+
report.print(include_input=True, include_output=True)
|
307
|
+
else:
|
308
|
+
print(f"Running {agent} in UI mode, agent options: {agent_options}")
|
309
|
+
# UI mode
|
310
|
+
gradio_ui = chat_func(deps=deps, **agent_run_options)
|
311
|
+
gradio_ui.launch(**launch_options)
|
312
|
+
|
313
|
+
|
314
|
+
|
315
|
+
@main.command()
|
316
|
+
@click.option("--limit", "-l", default=10, show_default=True, help="Number of results to return.")
|
317
|
+
@click.argument("ontology")
|
318
|
+
@click.argument("term")
|
319
|
+
def search_ontology(ontology: str, term: str, **kwargs):
|
320
|
+
"""Search the ontology for the given query term.
|
321
|
+
|
322
|
+
Also has side effect of indexing. You may want to pre-index before
|
323
|
+
starting an individual UI.
|
324
|
+
"""
|
325
|
+
import aurelian.utils.ontology_utils as ontology_utils
|
326
|
+
from oaklib import get_adapter
|
327
|
+
|
328
|
+
handle = "sqlite:obo:" + ontology
|
329
|
+
adapter = get_adapter(handle)
|
330
|
+
objs = ontology_utils.search_ontology(adapter, term, **kwargs)
|
331
|
+
for id, label in objs:
|
332
|
+
print(id, label)
|
333
|
+
|
334
|
+
|
335
|
+
@main.command()
|
336
|
+
@agent_option
|
337
|
+
@model_option
|
338
|
+
@use_cborg_option
|
339
|
+
@share_option
|
340
|
+
@server_port_option
|
341
|
+
@ui_option
|
342
|
+
@click.argument("query", nargs=-1, required=False)
|
343
|
+
def gocam(ui, query, agent, **kwargs):
|
344
|
+
"""Start the GO-CAM Agent for gene ontology causal activity models.
|
345
|
+
|
346
|
+
The GO-CAM Agent helps create and analyze Gene Ontology Causal Activity Models,
|
347
|
+
which describe biological systems as molecular activities connected by causal
|
348
|
+
relationships.
|
349
|
+
|
350
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
351
|
+
"""
|
352
|
+
run_agent("gocam", "aurelian.agents.gocam", query=query, ui=ui, specialist_agent_name=agent, **kwargs)
|
353
|
+
|
354
|
+
|
355
|
+
|
356
|
+
@main.command()
|
357
|
+
@model_option
|
358
|
+
@workdir_option
|
359
|
+
@share_option
|
360
|
+
@server_port_option
|
361
|
+
@ui_option
|
362
|
+
@click.argument("query", nargs=-1, required=False)
|
363
|
+
def phenopackets(ui, query, **kwargs):
|
364
|
+
"""Start the Phenopackets Agent for standardized phenotype data.
|
365
|
+
|
366
|
+
The Phenopackets Agent helps work with GA4GH Phenopackets, a standard
|
367
|
+
format for sharing disease and phenotype information for genomic
|
368
|
+
medicine.
|
369
|
+
|
370
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
371
|
+
"""
|
372
|
+
run_agent("phenopackets", "aurelian.agents.phenopackets", query=query, ui=ui, **kwargs)
|
373
|
+
|
374
|
+
|
375
|
+
@main.command()
|
376
|
+
@model_option
|
377
|
+
@workdir_option
|
378
|
+
@share_option
|
379
|
+
@server_port_option
|
380
|
+
@ui_option
|
381
|
+
@click.argument("query", nargs=-1, required=False)
|
382
|
+
def diagnosis(ui, query, **kwargs):
|
383
|
+
"""Start the Diagnosis Agent for rare disease diagnosis.
|
384
|
+
|
385
|
+
The Diagnosis Agent assists in diagnosing rare diseases by leveraging the
|
386
|
+
Monarch Knowledge Base. It helps clinical geneticists evaluate potential
|
387
|
+
conditions based on patient phenotypes.
|
388
|
+
|
389
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
390
|
+
"""
|
391
|
+
run_agent("diagnosis", "aurelian.agents.diagnosis", query=query, ui=ui, **kwargs)
|
392
|
+
|
393
|
+
|
394
|
+
@main.command()
|
395
|
+
@model_option
|
396
|
+
@workdir_option
|
397
|
+
@share_option
|
398
|
+
@server_port_option
|
399
|
+
@ui_option
|
400
|
+
@click.argument("query", nargs=-1, required=False)
|
401
|
+
def checklist(ui, query, **kwargs):
|
402
|
+
"""Start the Checklist Agent for paper evaluation.
|
403
|
+
|
404
|
+
The Checklist Agent evaluates scientific papers against established checklists
|
405
|
+
such as STREAMS, STORMS, and ARRIVE. It helps ensure that papers conform to
|
406
|
+
relevant reporting guidelines and best practices.
|
407
|
+
|
408
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
409
|
+
"""
|
410
|
+
run_agent("checklist", "aurelian.agents.checklist", query=query, ui=ui, **kwargs)
|
411
|
+
|
412
|
+
|
413
|
+
# Keep backward compatibility
|
414
|
+
@main.command()
|
415
|
+
@model_option
|
416
|
+
@workdir_option
|
417
|
+
@share_option
|
418
|
+
@server_port_option
|
419
|
+
def aria(**kwargs):
|
420
|
+
"""Start the Checklist UI (deprecated, use 'checklist' instead)."""
|
421
|
+
run_agent("checklist", "aurelian.agents.checklist", ui=True, **kwargs)
|
422
|
+
|
423
|
+
|
424
|
+
@main.command()
|
425
|
+
@model_option
|
426
|
+
@workdir_option
|
427
|
+
@share_option
|
428
|
+
@server_port_option
|
429
|
+
@ui_option
|
430
|
+
@click.argument("query", nargs=-1, required=False)
|
431
|
+
def linkml(ui, query, **kwargs):
|
432
|
+
"""Start the LinkML Agent for data modeling and schema validation.
|
433
|
+
|
434
|
+
The LinkML Agent helps create and validate data models and schemas using the
|
435
|
+
Linked data Modeling Language (LinkML). It can assist in generating schemas,
|
436
|
+
validating data against schemas, and modeling domain knowledge.
|
437
|
+
|
438
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
439
|
+
"""
|
440
|
+
run_agent("linkml", "aurelian.agents.linkml", query=query, ui=ui, **kwargs)
|
441
|
+
|
442
|
+
|
443
|
+
@main.command()
|
444
|
+
@model_option
|
445
|
+
@workdir_option
|
446
|
+
@share_option
|
447
|
+
@server_port_option
|
448
|
+
@ui_option
|
449
|
+
@click.argument("query", nargs=-1, required=False)
|
450
|
+
def robot(ui, query, **kwargs):
|
451
|
+
"""Start the ROBOT Agent for ontology operations.
|
452
|
+
|
453
|
+
The ROBOT Agent provides natural language access to ontology operations
|
454
|
+
and manipulations using the ROBOT tool. It can create, modify, and analyze
|
455
|
+
ontologies through a chat interface.
|
456
|
+
|
457
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
458
|
+
"""
|
459
|
+
run_agent("robot", "aurelian.agents.robot", query=query, ui=ui, agent_func_name="chat", **kwargs)
|
460
|
+
|
461
|
+
|
462
|
+
@main.command()
|
463
|
+
@model_option
|
464
|
+
@workdir_option
|
465
|
+
@share_option
|
466
|
+
@server_port_option
|
467
|
+
@ui_option
|
468
|
+
@click.argument("query", nargs=-1, required=False)
|
469
|
+
def amigo(ui, query, **kwargs):
|
470
|
+
"""Start the AmiGO Agent for Gene Ontology data exploration.
|
471
|
+
|
472
|
+
The AmiGO Agent provides access to the Gene Ontology (GO) and gene
|
473
|
+
product annotations. It helps users explore gene functions and
|
474
|
+
ontology relationships.
|
475
|
+
|
476
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
477
|
+
"""
|
478
|
+
run_agent("amigo", "aurelian.agents.amigo", query=query, ui=ui, **kwargs)
|
479
|
+
|
480
|
+
|
481
|
+
@main.command()
|
482
|
+
@model_option
|
483
|
+
@workdir_option
|
484
|
+
@share_option
|
485
|
+
@server_port_option
|
486
|
+
@ui_option
|
487
|
+
@db_path_option
|
488
|
+
@collection_name_option
|
489
|
+
@click.argument("query", nargs=-1, required=False)
|
490
|
+
def rag(ui, query, db_path, collection_name, **kwargs):
|
491
|
+
"""Start the RAG Agent for document retrieval and generation.
|
492
|
+
|
493
|
+
The RAG (Retrieval-Augmented Generation) Agent provides a natural language
|
494
|
+
interface for exploring and searching document collections. It uses RAG
|
495
|
+
techniques to combine search capabilities with generative AI.
|
496
|
+
|
497
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
498
|
+
"""
|
499
|
+
if not db_path:
|
500
|
+
click.echo("Error: --db-path is required")
|
501
|
+
return
|
502
|
+
|
503
|
+
# Add special parameters to kwargs
|
504
|
+
kwargs["db_path"] = db_path
|
505
|
+
if collection_name:
|
506
|
+
kwargs["collection_name"] = collection_name
|
507
|
+
|
508
|
+
run_agent("rag", "aurelian.agents.rag", query=query, ui=ui, **kwargs)
|
509
|
+
|
510
|
+
|
511
|
+
@main.command()
|
512
|
+
@model_option
|
513
|
+
@workdir_option
|
514
|
+
@share_option
|
515
|
+
@server_port_option
|
516
|
+
@ui_option
|
517
|
+
@ontologies_option
|
518
|
+
@click.argument("query", nargs=-1, required=False)
|
519
|
+
def mapper(ui, query, ontologies, **kwargs):
|
520
|
+
"""Start the Ontology Mapper Agent for mapping between ontologies.
|
521
|
+
|
522
|
+
The Ontology Mapper Agent helps translate terms between different ontologies
|
523
|
+
and vocabularies. It can find equivalent concepts across ontologies and
|
524
|
+
explain relationships.
|
525
|
+
|
526
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
527
|
+
"""
|
528
|
+
# Special handling for ontologies parameter
|
529
|
+
if ontologies:
|
530
|
+
if isinstance(ontologies, str):
|
531
|
+
ontologies = [ontologies]
|
532
|
+
kwargs["ontologies"] = ontologies
|
533
|
+
|
534
|
+
run_agent("ontology_mapper", "aurelian.agents.ontology_mapper", query=query, ui=ui, join_char="\n", **kwargs)
|
535
|
+
|
536
|
+
|
537
|
+
@main.command()
|
538
|
+
@click.argument("pmid")
|
539
|
+
def fulltext(pmid):
|
540
|
+
"""Download full text for a PubMed article."""
|
541
|
+
from aurelian.utils.pubmed_utils import get_pmid_text
|
542
|
+
txt = get_pmid_text(pmid)
|
543
|
+
print(txt)
|
544
|
+
|
545
|
+
|
546
|
+
@main.command()
|
547
|
+
@click.argument("term")
|
548
|
+
def websearch(term):
|
549
|
+
"""Search the web for a query term."""
|
550
|
+
from aurelian.utils.search_utils import web_search
|
551
|
+
txt = web_search(term)
|
552
|
+
print(txt)
|
553
|
+
|
554
|
+
@main.command()
|
555
|
+
@click.argument("term")
|
556
|
+
def perplexity(term):
|
557
|
+
"""Search the web for a query term, with citations."""
|
558
|
+
from aurelian.agents.web.web_tools import perplexity_query
|
559
|
+
result = run_sync(perplexity_query(term))
|
560
|
+
import yaml
|
561
|
+
print(yaml.dump(result.model_dump(), indent=2))
|
562
|
+
|
563
|
+
@main.command()
|
564
|
+
@click.argument("url")
|
565
|
+
def geturl(url):
|
566
|
+
"""Retrieve content from a URL."""
|
567
|
+
from aurelian.utils.search_utils import retrieve_web_page
|
568
|
+
txt = retrieve_web_page(url)
|
569
|
+
print(txt)
|
570
|
+
|
571
|
+
|
572
|
+
@main.command()
|
573
|
+
@model_option
|
574
|
+
@workdir_option
|
575
|
+
@share_option
|
576
|
+
@server_port_option
|
577
|
+
@ui_option
|
578
|
+
@click.argument("url", required=False)
|
579
|
+
def datasheets(ui, url, **kwargs):
|
580
|
+
"""Start the Datasheets for Datasets (D4D) Agent.
|
581
|
+
|
582
|
+
The D4D Agent extracts structured metadata from dataset documentation
|
583
|
+
according to the Datasheets for Datasets schema. It can analyze both
|
584
|
+
web pages and PDF documents describing datasets.
|
585
|
+
|
586
|
+
Run with a URL for direct mode or with --ui for interactive chat mode.
|
587
|
+
"""
|
588
|
+
run_agent("d4d", "aurelian.agents.d4d", query=(url,) if url else None, ui=ui, **kwargs)
|
589
|
+
|
590
|
+
|
591
|
+
@main.command()
|
592
|
+
@model_option
|
593
|
+
@workdir_option
|
594
|
+
@share_option
|
595
|
+
@server_port_option
|
596
|
+
@ui_option
|
597
|
+
@click.argument("query", nargs=-1, required=False)
|
598
|
+
def chemistry(ui, query, **kwargs):
|
599
|
+
"""Start the Chemistry Agent for chemical structure analysis.
|
600
|
+
|
601
|
+
The Chemistry Agent helps interpret and work with chemical structures,
|
602
|
+
formulas, and related information.
|
603
|
+
|
604
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
605
|
+
"""
|
606
|
+
run_agent("chemistry", "aurelian.agents.chemistry", query=query, ui=ui, **kwargs)
|
607
|
+
|
608
|
+
|
609
|
+
@main.command()
|
610
|
+
@model_option
|
611
|
+
@workdir_option
|
612
|
+
@share_option
|
613
|
+
@server_port_option
|
614
|
+
@ui_option
|
615
|
+
@click.argument("query", nargs=-1, required=False)
|
616
|
+
def literature(ui, query, **kwargs):
|
617
|
+
"""Start the Literature Agent for scientific publication analysis.
|
618
|
+
|
619
|
+
The Literature Agent provides tools for analyzing scientific publications,
|
620
|
+
extracting key information, and answering questions about research articles.
|
621
|
+
|
622
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
623
|
+
"""
|
624
|
+
run_agent("literature", "aurelian.agents.literature", query=query, ui=ui, **kwargs)
|
625
|
+
|
626
|
+
|
627
|
+
@main.command()
|
628
|
+
@model_option
|
629
|
+
@workdir_option
|
630
|
+
@share_option
|
631
|
+
@server_port_option
|
632
|
+
@ui_option
|
633
|
+
@click.argument("query", nargs=-1, required=False)
|
634
|
+
def biblio(ui, query, **kwargs):
|
635
|
+
"""Start the Biblio Agent for bibliographic data management.
|
636
|
+
|
637
|
+
The Biblio Agent helps organize and search bibliographic data and citations.
|
638
|
+
It provides tools for searching a bibliography database, retrieving scientific
|
639
|
+
publications, and accessing web content.
|
640
|
+
|
641
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
642
|
+
"""
|
643
|
+
run_agent("biblio", "aurelian.agents.biblio", query=query, ui=ui, **kwargs)
|
644
|
+
|
645
|
+
|
646
|
+
@main.command()
|
647
|
+
@model_option
|
648
|
+
@workdir_option
|
649
|
+
@share_option
|
650
|
+
@server_port_option
|
651
|
+
@ui_option
|
652
|
+
@click.argument("query", nargs=-1, required=False)
|
653
|
+
def monarch(ui, query, **kwargs):
|
654
|
+
"""Start the Monarch Agent for biomedical knowledge exploration.
|
655
|
+
|
656
|
+
The Monarch Agent provides access to relationships between genes, diseases,
|
657
|
+
phenotypes, and other biomedical entities through the Monarch Knowledge Base.
|
658
|
+
|
659
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
660
|
+
"""
|
661
|
+
run_agent("monarch", "aurelian.agents.monarch", query=query, ui=ui, **kwargs)
|
662
|
+
|
663
|
+
|
664
|
+
@main.command()
|
665
|
+
@model_option
|
666
|
+
@workdir_option
|
667
|
+
@share_option
|
668
|
+
@server_port_option
|
669
|
+
@ui_option
|
670
|
+
@click.argument("query", nargs=-1, required=False)
|
671
|
+
def ubergraph(ui, query, **kwargs):
|
672
|
+
"""Start the UberGraph Agent for SPARQL-based ontology queries.
|
673
|
+
|
674
|
+
The UberGraph Agent provides a natural language interface to query ontologies
|
675
|
+
using SPARQL through the UberGraph endpoint. It helps users formulate and execute
|
676
|
+
SPARQL queries without needing to know the full SPARQL syntax.
|
677
|
+
|
678
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
679
|
+
"""
|
680
|
+
run_agent("ubergraph", "aurelian.agents.ubergraph", query=query, ui=ui, **kwargs)
|
681
|
+
|
682
|
+
|
683
|
+
@main.command()
|
684
|
+
@model_option
|
685
|
+
@workdir_option
|
686
|
+
@share_option
|
687
|
+
@server_port_option
|
688
|
+
@ui_option
|
689
|
+
@click.argument("query", nargs=-1, required=False)
|
690
|
+
def gene(ui, query, **kwargs):
|
691
|
+
"""Start the Gene Agent for retrieving gene descriptions.
|
692
|
+
|
693
|
+
The Gene Agent retrieves descriptions for gene identifiers using the UniProt API.
|
694
|
+
It can process a single gene or a list of genes and returns detailed information
|
695
|
+
about gene function, products, and associations.
|
696
|
+
|
697
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
698
|
+
"""
|
699
|
+
run_agent("gene", "aurelian.agents.gene", query=query, ui=ui, **kwargs)
|
700
|
+
|
701
|
+
@main.command()
|
702
|
+
@model_option
|
703
|
+
@use_cborg_option
|
704
|
+
@workdir_option
|
705
|
+
@share_option
|
706
|
+
@server_port_option
|
707
|
+
@ui_option
|
708
|
+
@click.argument("query", nargs=-1, required=False)
|
709
|
+
def goann(ui, query, **kwargs):
|
710
|
+
"""Start the GO Annotation Review Agent for evaluating GO annotations.
|
711
|
+
|
712
|
+
The GO Annotation Review Agent helps review GO annotations for accuracy
|
713
|
+
and proper evidence. It can evaluate annotations based on evidence codes,
|
714
|
+
identify potential over-annotations, and ensure compliance with GO guidelines,
|
715
|
+
particularly for transcription factors.
|
716
|
+
|
717
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
718
|
+
"""
|
719
|
+
run_agent("goann", "aurelian.agents.goann", query=query, ui=ui, **kwargs)
|
720
|
+
|
721
|
+
|
722
|
+
@main.command()
|
723
|
+
@model_option
|
724
|
+
@workdir_option
|
725
|
+
@share_option
|
726
|
+
@server_port_option
|
727
|
+
@ui_option
|
728
|
+
@click.argument("query", nargs=-1, required=False)
|
729
|
+
def github(ui, query, **kwargs):
|
730
|
+
"""Start the GitHub Agent for repository interaction.
|
731
|
+
|
732
|
+
The GitHub Agent provides a natural language interface for interacting with GitHub
|
733
|
+
repositories. It can list/view pull requests and issues, find connections between PRs
|
734
|
+
and issues, search code, clone repositories, and examine commit history.
|
735
|
+
|
736
|
+
Requires GitHub CLI (gh) to be installed and authenticated.
|
737
|
+
|
738
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
739
|
+
"""
|
740
|
+
run_agent("github", "aurelian.agents.github", query=query, ui=ui, **kwargs)
|
741
|
+
|
742
|
+
|
743
|
+
@main.command()
|
744
|
+
@model_option
|
745
|
+
@workdir_option
|
746
|
+
@share_option
|
747
|
+
@server_port_option
|
748
|
+
@ui_option
|
749
|
+
@click.argument("query", nargs=-1, required=False)
|
750
|
+
def draw(ui, query, **kwargs):
|
751
|
+
"""Start the Draw Agent for creating SVG drawings.
|
752
|
+
|
753
|
+
The Draw Agent creates SVG drawings based on text descriptions and provides
|
754
|
+
feedback on drawing quality from an art critic judge. It helps generate visual
|
755
|
+
representations from textual descriptions with a focus on clarity and simplicity.
|
756
|
+
|
757
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
758
|
+
"""
|
759
|
+
run_agent("draw", "aurelian.agents.draw", query=query, ui=ui, **kwargs)
|
760
|
+
|
761
|
+
|
762
|
+
@main.command()
|
763
|
+
@ui_option
|
764
|
+
@workdir_option
|
765
|
+
@share_option
|
766
|
+
@server_port_option
|
767
|
+
@click.option("--list", "-l", help="Comma-separated list of gene identifiers")
|
768
|
+
@click.option("--taxon", "-t", help="Species/taxon the genes belong to (e.g., 'Homo sapiens', 'Desulfovibrio vulgaris')", required=True)
|
769
|
+
@click.argument("query", nargs=-1, required=False)
|
770
|
+
def talisman(ui, list, taxon, query, **kwargs):
|
771
|
+
"""Start the Talisman Agent for advanced gene analysis.
|
772
|
+
|
773
|
+
The Talisman Agent retrieves descriptions for gene identifiers using UniProt and NCBI Entrez.
|
774
|
+
It can process a single gene, protein ID, or a list of genes and returns detailed information.
|
775
|
+
It also can analyze relationships between multiple genes to identify functional connections.
|
776
|
+
|
777
|
+
Run with --list and --taxon options for direct mode or with --ui for interactive chat mode.
|
778
|
+
The taxon/species parameter is required to provide proper context for gene analysis.
|
779
|
+
|
780
|
+
Examples:
|
781
|
+
aurelian talisman --list "TP53" --taxon "Homo sapiens"
|
782
|
+
aurelian talisman --list "TP53, MDM2" --taxon "Homo sapiens"
|
783
|
+
aurelian talisman --list "DVUA0001, DVUA0002" --taxon "Desulfovibrio vulgaris"
|
784
|
+
"""
|
785
|
+
# Import the necessary functions from talisman_tools
|
786
|
+
from aurelian.agents.talisman.talisman_tools import (
|
787
|
+
ensure_complete_output,
|
788
|
+
GeneSetAnalysis,
|
789
|
+
FunctionalTerm,
|
790
|
+
GeneSummary
|
791
|
+
)
|
792
|
+
import re
|
793
|
+
|
794
|
+
# Convert positional argument to list option if provided
|
795
|
+
if query and not list:
|
796
|
+
list = " ".join(query)
|
797
|
+
|
798
|
+
# Inform the user if no gene list is provided
|
799
|
+
if not list and not ui:
|
800
|
+
import click
|
801
|
+
click.echo("Error: Either --list or --ui must be provided.")
|
802
|
+
return
|
803
|
+
|
804
|
+
# Prepare the prompt with the gene list and species information
|
805
|
+
if list:
|
806
|
+
list_prompt = f"Gene list: {list}\nSpecies: {taxon}"
|
807
|
+
else:
|
808
|
+
list_prompt = ""
|
809
|
+
|
810
|
+
# Create a wrapper function to post-process the output
|
811
|
+
def process_talisman_output(result):
|
812
|
+
print("=== ORIGINAL OUTPUT ===")
|
813
|
+
print(result)
|
814
|
+
print("=== END ORIGINAL OUTPUT ===")
|
815
|
+
|
816
|
+
# Force a complete rebuild of the output regardless of what's in the original result
|
817
|
+
# This ensures we always have all sections
|
818
|
+
|
819
|
+
# Extract inferred species from the result if available
|
820
|
+
inferred_species = taxon # Default to the provided taxon
|
821
|
+
organism_match = re.search(r'\|\s*\w+\s*\|\s*[^|]+\|\s*[^|]+\|\s*([^|]+)\|', result)
|
822
|
+
if organism_match:
|
823
|
+
inferred_species = organism_match.group(1).strip()
|
824
|
+
|
825
|
+
# Create gene summaries from the output
|
826
|
+
gene_summaries = []
|
827
|
+
gene_table_match = re.search(r'##?\s*Gene Summary Table.*?\n\|.*?\n\|.*?\n(.*?)(?=\n\n|\n##|\Z)',
|
828
|
+
result, re.DOTALL)
|
829
|
+
if gene_table_match:
|
830
|
+
for line in gene_table_match.group(1).split('\n'):
|
831
|
+
if '|' in line:
|
832
|
+
cols = [col.strip() for col in line.split('|')]
|
833
|
+
if len(cols) >= 6: # Account for empty first and last elements
|
834
|
+
gene_id = cols[1]
|
835
|
+
if gene_id and gene_id != '-':
|
836
|
+
gene_summaries.append(
|
837
|
+
GeneSummary(
|
838
|
+
id=cols[1],
|
839
|
+
annotation=cols[2],
|
840
|
+
genomic_context=cols[3],
|
841
|
+
organism=cols[4],
|
842
|
+
description=cols[5]
|
843
|
+
)
|
844
|
+
)
|
845
|
+
|
846
|
+
# Create default functional terms for the gene set
|
847
|
+
functional_terms = []
|
848
|
+
if gene_summaries:
|
849
|
+
gene_ids = [g.id for g in gene_summaries]
|
850
|
+
|
851
|
+
# Default functional terms based on gene descriptions
|
852
|
+
for gene in gene_summaries:
|
853
|
+
if "DNA" in gene.description or "binding" in gene.description.lower():
|
854
|
+
functional_terms.append(
|
855
|
+
FunctionalTerm(
|
856
|
+
term="DNA binding",
|
857
|
+
genes=[gene.id],
|
858
|
+
source="GO-MF"
|
859
|
+
)
|
860
|
+
)
|
861
|
+
if "stress" in gene.description.lower():
|
862
|
+
functional_terms.append(
|
863
|
+
FunctionalTerm(
|
864
|
+
term="Stress response",
|
865
|
+
genes=[gene.id],
|
866
|
+
source="GO-BP"
|
867
|
+
)
|
868
|
+
)
|
869
|
+
if "ParA" in gene.description:
|
870
|
+
functional_terms.append(
|
871
|
+
FunctionalTerm(
|
872
|
+
term="Plasmid partitioning",
|
873
|
+
genes=[gene.id],
|
874
|
+
source="GO-BP"
|
875
|
+
)
|
876
|
+
)
|
877
|
+
|
878
|
+
# Add a generic set term
|
879
|
+
functional_terms.append(
|
880
|
+
FunctionalTerm(
|
881
|
+
term="Gene set",
|
882
|
+
genes=gene_ids,
|
883
|
+
source="Analysis"
|
884
|
+
)
|
885
|
+
)
|
886
|
+
|
887
|
+
# Try to extract existing narrative text if any
|
888
|
+
narrative = "This gene set includes proteins with functions related to DNA binding, stress response, and plasmid maintenance."
|
889
|
+
# Look for any text outside of table sections
|
890
|
+
narrative_section = re.search(r'(?:^|\n\n)((?!##)[^|#].*?)(?=\n##|\Z)', result, re.DOTALL)
|
891
|
+
if narrative_section:
|
892
|
+
extracted_text = narrative_section.group(1).strip()
|
893
|
+
if len(extracted_text.split()) > 3: # Only use if it's substantial
|
894
|
+
narrative = extracted_text
|
895
|
+
|
896
|
+
# Create a properly structured analysis object
|
897
|
+
analysis = GeneSetAnalysis(
|
898
|
+
input_species=taxon,
|
899
|
+
inferred_species=inferred_species,
|
900
|
+
narrative=narrative,
|
901
|
+
functional_terms=functional_terms,
|
902
|
+
gene_summaries=gene_summaries
|
903
|
+
)
|
904
|
+
|
905
|
+
# ALWAYS rebuild the output completely to ensure proper formatting
|
906
|
+
output = ""
|
907
|
+
|
908
|
+
# 1. Add Species section
|
909
|
+
output += f"# Species\nInput: {taxon}\nInferred: {inferred_species}\n\n"
|
910
|
+
|
911
|
+
# 2. Add Gene Set Analysis header
|
912
|
+
output += "# Gene Set Analysis\n\n"
|
913
|
+
|
914
|
+
# 3. Add Narrative section (always included)
|
915
|
+
output += f"## Narrative\n{analysis.narrative}\n\n"
|
916
|
+
|
917
|
+
# 4. Add Functional Terms Table (always included)
|
918
|
+
output += "## Functional Terms Table\n"
|
919
|
+
output += "| Functional Term | Genes | Source |\n"
|
920
|
+
output += "|-----------------|-------|--------|\n"
|
921
|
+
|
922
|
+
if analysis.functional_terms:
|
923
|
+
for term in analysis.functional_terms:
|
924
|
+
genes_str = ", ".join(term.genes)
|
925
|
+
output += f"| {term.term} | {genes_str} | {term.source} |\n"
|
926
|
+
else:
|
927
|
+
output += "| No functional terms available | - | - |\n"
|
928
|
+
|
929
|
+
output += "\n"
|
930
|
+
|
931
|
+
# 5. Add Gene Summary Table (always included)
|
932
|
+
output += "## Gene Summary Table\n"
|
933
|
+
output += "| ID | Annotation | Genomic Context | Organism | Description |\n"
|
934
|
+
output += "|-------------|-------------|----------|----------------|------------|\n"
|
935
|
+
|
936
|
+
if analysis.gene_summaries:
|
937
|
+
for gene in analysis.gene_summaries:
|
938
|
+
output += f"| {gene.id} | {gene.annotation} | {gene.genomic_context} | {gene.organism} | {gene.description} |\n"
|
939
|
+
else:
|
940
|
+
output += "| No gene information available | - | - | - | - |\n"
|
941
|
+
|
942
|
+
print("=== PROCESSED OUTPUT ===")
|
943
|
+
print(output)
|
944
|
+
print("=== END PROCESSED OUTPUT ===")
|
945
|
+
|
946
|
+
return output
|
947
|
+
|
948
|
+
# Run the agent with post-processing of the output and species information
|
949
|
+
run_agent("talisman", "aurelian.agents.talisman", query=list_prompt, ui=ui,
|
950
|
+
result_processor=process_talisman_output, **kwargs)
|
951
|
+
@model_option
|
952
|
+
@workdir_option
|
953
|
+
@share_option
|
954
|
+
@server_port_option
|
955
|
+
@ui_option
|
956
|
+
@click.argument("query", nargs=-1, required=False)
|
957
|
+
def reaction(ui, query, **kwargs):
|
958
|
+
"""Start the Reaction Agent for biochemical reaction query and curation.
|
959
|
+
|
960
|
+
The Reaction Agent helps query and curate biochemical reactions from various sources
|
961
|
+
including RHEA and UniProt. It can identify enzymes, substrates, products, and
|
962
|
+
extract reaction information from scientific text.
|
963
|
+
|
964
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
965
|
+
"""
|
966
|
+
run_agent("reaction", "aurelian.agents.reaction", query=query, ui=ui, **kwargs)
|
967
|
+
|
968
|
+
|
969
|
+
|
970
|
+
@main.command()
|
971
|
+
@model_option
|
972
|
+
@workdir_option
|
973
|
+
@share_option
|
974
|
+
@server_port_option
|
975
|
+
@ui_option
|
976
|
+
@click.argument("query", nargs=-1, required=False)
|
977
|
+
def paperqa(ui, query, **kwargs):
|
978
|
+
"""Start the PaperQA Agent for scientific literature search and analysis.
|
979
|
+
|
980
|
+
The PaperQA Agent helps search, organize, and analyze scientific papers. It can
|
981
|
+
find papers on specific topics, add papers to your collection, and answer questions
|
982
|
+
based on the papers in your collection.
|
983
|
+
|
984
|
+
Run with a query for direct mode or with --ui for interactive chat mode.
|
985
|
+
|
986
|
+
Use `aurelian paperqa` subcommands for paper management:
|
987
|
+
- `aurelian paperqa index` to index papers for searching
|
988
|
+
- `aurelian paperqa list` to list papers in your collection
|
989
|
+
"""
|
990
|
+
run_agent("paperqa", "aurelian.agents.paperqa", query=query, ui=ui, **kwargs)
|
991
|
+
|
992
|
+
|
993
|
+
# Import and register PaperQA CLI commands
|
994
|
+
from aurelian.agents.paperqa.paperqa_cli import paperqa_cli
|
995
|
+
main.add_command(paperqa_cli)
|
996
|
+
|
997
|
+
# DO NOT REMOVE THIS LINE
|
998
|
+
# added this for mkdocstrings to work
|
999
|
+
# see https://github.com/bruce-szalwinski/mkdocs-typer/issues/18
|
1000
|
+
#click_app = get_command(app)
|
1001
|
+
#click_app.name = "aurelian"
|
1002
|
+
|
1003
|
+
if __name__ == "__main__":
|
1004
|
+
main()
|