aurelian 0.3.2__py3-none-any.whl → 0.3.4__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/cli.py CHANGED
@@ -755,22 +755,190 @@ def draw(ui, query, **kwargs):
755
755
  @workdir_option
756
756
  @share_option
757
757
  @server_port_option
758
+ @click.option("--list", "-l", help="Comma-separated list of gene identifiers")
759
+ @click.option("--taxon", "-t", help="Species/taxon the genes belong to (e.g., 'Homo sapiens', 'Desulfovibrio vulgaris')", required=True)
758
760
  @click.argument("query", nargs=-1, required=False)
759
- def talisman(ui, query, **kwargs):
761
+ def talisman(ui, list, taxon, query, **kwargs):
760
762
  """Start the Talisman Agent for advanced gene analysis.
761
763
 
762
764
  The Talisman Agent retrieves descriptions for gene identifiers using UniProt and NCBI Entrez.
763
765
  It can process a single gene, protein ID, or a list of genes and returns detailed information.
764
766
  It also can analyze relationships between multiple genes to identify functional connections.
765
767
 
766
- Run with a query for direct mode or with --ui for interactive chat mode.
768
+ Run with --list and --taxon options for direct mode or with --ui for interactive chat mode.
769
+ The taxon/species parameter is required to provide proper context for gene analysis.
767
770
 
768
771
  Examples:
769
- aurelian talisman TP53
770
- aurelian talisman "TP53, MDM2"
771
- aurelian talisman "BRCA1, BRCA2, ATM, PARP1"
772
+ aurelian talisman --list "TP53" --taxon "Homo sapiens"
773
+ aurelian talisman --list "TP53, MDM2" --taxon "Homo sapiens"
774
+ aurelian talisman --list "DVUA0001, DVUA0002" --taxon "Desulfovibrio vulgaris"
772
775
  """
773
- run_agent("talisman", "aurelian.agents.talisman", query=query, ui=ui, **kwargs)
776
+ # Import the necessary functions from talisman_tools
777
+ from aurelian.agents.talisman.talisman_tools import (
778
+ ensure_complete_output,
779
+ GeneSetAnalysis,
780
+ FunctionalTerm,
781
+ GeneSummary
782
+ )
783
+ import re
784
+
785
+ # Convert positional argument to list option if provided
786
+ if query and not list:
787
+ list = " ".join(query)
788
+
789
+ # Inform the user if no gene list is provided
790
+ if not list and not ui:
791
+ import click
792
+ click.echo("Error: Either --list or --ui must be provided.")
793
+ return
794
+
795
+ # Prepare the prompt with the gene list and species information
796
+ if list:
797
+ list_prompt = f"Gene list: {list}\nSpecies: {taxon}"
798
+ else:
799
+ list_prompt = ""
800
+
801
+ # Create a wrapper function to post-process the output
802
+ def process_talisman_output(result):
803
+ print("=== ORIGINAL OUTPUT ===")
804
+ print(result)
805
+ print("=== END ORIGINAL OUTPUT ===")
806
+
807
+ # Force a complete rebuild of the output regardless of what's in the original result
808
+ # This ensures we always have all sections
809
+
810
+ # Extract inferred species from the result if available
811
+ inferred_species = taxon # Default to the provided taxon
812
+ organism_match = re.search(r'\|\s*\w+\s*\|\s*[^|]+\|\s*[^|]+\|\s*([^|]+)\|', result)
813
+ if organism_match:
814
+ inferred_species = organism_match.group(1).strip()
815
+
816
+ # Create gene summaries from the output
817
+ gene_summaries = []
818
+ gene_table_match = re.search(r'##?\s*Gene Summary Table.*?\n\|.*?\n\|.*?\n(.*?)(?=\n\n|\n##|\Z)',
819
+ result, re.DOTALL)
820
+ if gene_table_match:
821
+ for line in gene_table_match.group(1).split('\n'):
822
+ if '|' in line:
823
+ cols = [col.strip() for col in line.split('|')]
824
+ if len(cols) >= 6: # Account for empty first and last elements
825
+ gene_id = cols[1]
826
+ if gene_id and gene_id != '-':
827
+ gene_summaries.append(
828
+ GeneSummary(
829
+ id=cols[1],
830
+ annotation=cols[2],
831
+ genomic_context=cols[3],
832
+ organism=cols[4],
833
+ description=cols[5]
834
+ )
835
+ )
836
+
837
+ # Create default functional terms for the gene set
838
+ functional_terms = []
839
+ if gene_summaries:
840
+ gene_ids = [g.id for g in gene_summaries]
841
+
842
+ # Default functional terms based on gene descriptions
843
+ for gene in gene_summaries:
844
+ if "DNA" in gene.description or "binding" in gene.description.lower():
845
+ functional_terms.append(
846
+ FunctionalTerm(
847
+ term="DNA binding",
848
+ genes=[gene.id],
849
+ source="GO-MF"
850
+ )
851
+ )
852
+ if "stress" in gene.description.lower():
853
+ functional_terms.append(
854
+ FunctionalTerm(
855
+ term="Stress response",
856
+ genes=[gene.id],
857
+ source="GO-BP"
858
+ )
859
+ )
860
+ if "ParA" in gene.description:
861
+ functional_terms.append(
862
+ FunctionalTerm(
863
+ term="Plasmid partitioning",
864
+ genes=[gene.id],
865
+ source="GO-BP"
866
+ )
867
+ )
868
+
869
+ # Add a generic set term
870
+ functional_terms.append(
871
+ FunctionalTerm(
872
+ term="Gene set",
873
+ genes=gene_ids,
874
+ source="Analysis"
875
+ )
876
+ )
877
+
878
+ # Try to extract existing narrative text if any
879
+ narrative = "This gene set includes proteins with functions related to DNA binding, stress response, and plasmid maintenance."
880
+ # Look for any text outside of table sections
881
+ narrative_section = re.search(r'(?:^|\n\n)((?!##)[^|#].*?)(?=\n##|\Z)', result, re.DOTALL)
882
+ if narrative_section:
883
+ extracted_text = narrative_section.group(1).strip()
884
+ if len(extracted_text.split()) > 3: # Only use if it's substantial
885
+ narrative = extracted_text
886
+
887
+ # Create a properly structured analysis object
888
+ analysis = GeneSetAnalysis(
889
+ input_species=taxon,
890
+ inferred_species=inferred_species,
891
+ narrative=narrative,
892
+ functional_terms=functional_terms,
893
+ gene_summaries=gene_summaries
894
+ )
895
+
896
+ # ALWAYS rebuild the output completely to ensure proper formatting
897
+ output = ""
898
+
899
+ # 1. Add Species section
900
+ output += f"# Species\nInput: {taxon}\nInferred: {inferred_species}\n\n"
901
+
902
+ # 2. Add Gene Set Analysis header
903
+ output += "# Gene Set Analysis\n\n"
904
+
905
+ # 3. Add Narrative section (always included)
906
+ output += f"## Narrative\n{analysis.narrative}\n\n"
907
+
908
+ # 4. Add Functional Terms Table (always included)
909
+ output += "## Functional Terms Table\n"
910
+ output += "| Functional Term | Genes | Source |\n"
911
+ output += "|-----------------|-------|--------|\n"
912
+
913
+ if analysis.functional_terms:
914
+ for term in analysis.functional_terms:
915
+ genes_str = ", ".join(term.genes)
916
+ output += f"| {term.term} | {genes_str} | {term.source} |\n"
917
+ else:
918
+ output += "| No functional terms available | - | - |\n"
919
+
920
+ output += "\n"
921
+
922
+ # 5. Add Gene Summary Table (always included)
923
+ output += "## Gene Summary Table\n"
924
+ output += "| ID | Annotation | Genomic Context | Organism | Description |\n"
925
+ output += "|-------------|-------------|----------|----------------|------------|\n"
926
+
927
+ if analysis.gene_summaries:
928
+ for gene in analysis.gene_summaries:
929
+ output += f"| {gene.id} | {gene.annotation} | {gene.genomic_context} | {gene.organism} | {gene.description} |\n"
930
+ else:
931
+ output += "| No gene information available | - | - | - | - |\n"
932
+
933
+ print("=== PROCESSED OUTPUT ===")
934
+ print(output)
935
+ print("=== END PROCESSED OUTPUT ===")
936
+
937
+ return output
938
+
939
+ # Run the agent with post-processing of the output and species information
940
+ run_agent("talisman", "aurelian.agents.talisman", query=list_prompt, ui=ui,
941
+ result_processor=process_talisman_output, **kwargs)
774
942
  @model_option
775
943
  @workdir_option
776
944
  @share_option
@@ -790,6 +958,33 @@ def reaction(ui, query, **kwargs):
790
958
 
791
959
 
792
960
 
961
+ @main.command()
962
+ @model_option
963
+ @workdir_option
964
+ @share_option
965
+ @server_port_option
966
+ @ui_option
967
+ @click.argument("query", nargs=-1, required=False)
968
+ def paperqa(ui, query, **kwargs):
969
+ """Start the PaperQA Agent for scientific literature search and analysis.
970
+
971
+ The PaperQA Agent helps search, organize, and analyze scientific papers. It can
972
+ find papers on specific topics, add papers to your collection, and answer questions
973
+ based on the papers in your collection.
974
+
975
+ Run with a query for direct mode or with --ui for interactive chat mode.
976
+
977
+ Use `aurelian paperqa` subcommands for paper management:
978
+ - `aurelian paperqa index` to index papers for searching
979
+ - `aurelian paperqa list` to list papers in your collection
980
+ """
981
+ run_agent("paperqa", "aurelian.agents.paperqa", query=query, ui=ui, **kwargs)
982
+
983
+
984
+ # Import and register PaperQA CLI commands
985
+ from aurelian.agents.paperqa.paperqa_cli import paperqa_cli
986
+ main.add_command(paperqa_cli)
987
+
793
988
  # DO NOT REMOVE THIS LINE
794
989
  # added this for mkdocstrings to work
795
990
  # see https://github.com/bruce-szalwinski/mkdocs-typer/issues/18
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: aurelian
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: aurelian
5
5
  License: MIT
6
6
  Author: Author 1
@@ -33,6 +33,7 @@ Requires-Dist: markdownify (>=0.14.1)
33
33
  Requires-Dist: markitdown (>=0.0.1a4)
34
34
  Requires-Dist: mcp[cli] (>=1.3.0,<2.0.0)
35
35
  Requires-Dist: oaklib (>=0.6.19)
36
+ Requires-Dist: paper-qa (>=5.20.0,<6.0.0)
36
37
  Requires-Dist: pdfminer-six ; extra == "pdfminer"
37
38
  Requires-Dist: pydantic-ai (>=0.0.29)
38
39
  Requires-Dist: pypaperbot (>=1.4.1)
@@ -43,6 +44,7 @@ Requires-Dist: undetected-chromedriver (>=3.5.5)
43
44
  Requires-Dist: wikipedia (>=1.4.0)
44
45
  Description-Content-Type: text/markdown
45
46
 
47
+ [![DOI](https://zenodo.org/badge/932483388.svg)](https://doi.org/10.5281/zenodo.15299996)
46
48
 
47
49
  # Aurelian: Agentic Universal Research Engine for Literature, Integration, Annotation, and Navigation
48
50
 
@@ -172,6 +172,13 @@ aurelian/agents/ontology_mapper/ontology_mapper_evals.py,sha256=6kympT8LV570rRoz
172
172
  aurelian/agents/ontology_mapper/ontology_mapper_gradio.py,sha256=nzkwPvK3k6Sze8oNS2R8z4k2XeXj4LU2wjV4G_Jn-Ec,1819
173
173
  aurelian/agents/ontology_mapper/ontology_mapper_mcp.py,sha256=YnXCKU2Yzy_RPqEba8hJPWwtb1H07Wo-zlZY-nnKurw,2208
174
174
  aurelian/agents/ontology_mapper/ontology_mapper_tools.py,sha256=S0azD3wR0pTh-9ipjVBUiNRkgsDEb30n1KMZD0qWvyw,4272
175
+ aurelian/agents/paperqa/__init__.py,sha256=Dfff3fyx9PeoeqA4DcvyE_loW-UXegYM281alttwLvI,590
176
+ aurelian/agents/paperqa/paperqa_agent.py,sha256=LimGkiN89gK-kD-AdrBXqIHw9FdC2JkBZTDZAuP1YX4,2615
177
+ aurelian/agents/paperqa/paperqa_cli.py,sha256=A0cwGUUTVcFVO1e_PsXusvBae9N5ElyeCtsZuQh-eGo,10357
178
+ aurelian/agents/paperqa/paperqa_config.py,sha256=CUj3BARcII8AippAYJXAq9MsqrQlkRm36ucHyuCGnII,4554
179
+ aurelian/agents/paperqa/paperqa_gradio.py,sha256=Thz82905TBeUQSiKcT40ZFs9MOqlN3YzYrJ5LNZPjHs,2844
180
+ aurelian/agents/paperqa/paperqa_mcp.py,sha256=ApnH43iZpM4ToPpSpE1KQf2mF4o7HCTXPb_X6tjX0ic,4665
181
+ aurelian/agents/paperqa/paperqa_tools.py,sha256=k0WtWPhkyAndnpPjP7XRF5llkW-Ktkxx2JhChO-SKU4,20238
175
182
  aurelian/agents/phenopackets/__init__.py,sha256=TrXNpK2KDUjxok4nCuhepVPGH4RvALOZJoXjD4S-i1g,73
176
183
  aurelian/agents/phenopackets/phenopackets_agent.py,sha256=R--xoY558TaVcAG2HoQvj7lWwCr_PrpfG7xl33rCIpk,2229
177
184
  aurelian/agents/phenopackets/phenopackets_config.py,sha256=hpc3m2IboYlQoJselVMPf_EK0Z1YJBNp7qbj3TLk7PM,2304
@@ -195,11 +202,14 @@ aurelian/agents/robot/robot_mcp.py,sha256=KkYg_l-VfHM0cTAeBrfWuv0zN3U6S7oxGZGd6R
195
202
  aurelian/agents/robot/robot_ontology_agent.py,sha256=DNdo1zlkYEUqByVXY6-vrSTvBRl--R1hmlbdwFbB8gY,5733
196
203
  aurelian/agents/robot/robot_tools.py,sha256=6V4jCUb2e6SvK_JndUnVATVBVpiHGj8yUbHhHYh1yDU,1821
197
204
  aurelian/agents/talisman/__init__.py,sha256=oeaxm4LKY4-I3h14ecRXJll2S8ywz1eQRyc3sAAK6-E,88
198
- aurelian/agents/talisman/talisman_agent.py,sha256=i-pJhEOs6liJ0qb48XCbBjLESV6uXRZWOJu3lfLB8KQ,5855
205
+ aurelian/agents/talisman/__main__.py,sha256=iHcq-LxdMI5yWQ92ADFOq7yC-3oCVOF5fN1U3cXbUHQ,499
206
+ aurelian/agents/talisman/cli.py,sha256=iMEnxfgSkm3CaoOtv8aJZIDTd9izlbZJj7hYqO8KFwY,3324
207
+ aurelian/agents/talisman/run_talisman.py,sha256=K_GX9eqA2wrhXIDjtTfpCh7UHRObniSYDq1T9tr4SWw,518
208
+ aurelian/agents/talisman/talisman_agent.py,sha256=KBvCCkzl-j_PObfMBrsyXg3kvCDmCpi2DAOnuaURdMI,6641
199
209
  aurelian/agents/talisman/talisman_config.py,sha256=bYjgMecVrKXwwZwv7n7Leseks6DFEfqVEZF9MqgoShQ,2301
200
210
  aurelian/agents/talisman/talisman_gradio.py,sha256=ogpFwnxVngvu5UmQ1GKz2JdbpCWlIK7duQDLJGisWs8,1617
201
211
  aurelian/agents/talisman/talisman_mcp.py,sha256=dOLpklOqDRmsvm4ZFGZwKrcrrsx_FcahxcIOUnvJYm8,4612
202
- aurelian/agents/talisman/talisman_tools.py,sha256=jYHQXu4JHsKoy1xtyQFlhpMcU_qEXS0pezyc8UxJeGY,31531
212
+ aurelian/agents/talisman/talisman_tools.py,sha256=ZzvpFxZBXpeZrIFV9aqtwVqa6O3z_5WvUReWOHh-aS4,42256
203
213
  aurelian/agents/ubergraph/__init__.py,sha256=Nl81e1H7XKBSQ2nIHoY0UCHgcOW5N-PJ1AugKh_YGOs,767
204
214
  aurelian/agents/ubergraph/ubergraph_agent.py,sha256=UUu-PQz9MPFZZIuRw0KPSokTaFh_cMVNjRVj3BsG1ek,3038
205
215
  aurelian/agents/ubergraph/ubergraph_config.py,sha256=Fi2hFVu92v55IinNYFlLjdvt9THXtRFPkSEcXtTrC10,2774
@@ -219,7 +229,7 @@ aurelian/agents/web/web_gradio.py,sha256=T7qzuRuBaWCYckWjpLu3L0LzHPLEKkxUYp2rj-O
219
229
  aurelian/agents/web/web_mcp.py,sha256=3mrUlxBqeMSOmtpnD2wWedsOiRJbtveEnbyJqQdfEXQ,1163
220
230
  aurelian/agents/web/web_tools.py,sha256=BfJJWlHz7tKh9VDjymIwzziahFKrqr2ZUO0QH3IcL6U,4070
221
231
  aurelian/chat.py,sha256=hg9eGKiz_NAjwG5jNGwNqoFrhhx029XX3dWdMRrk-EU,563
222
- aurelian/cli.py,sha256=Ymdmt2uFx0lcUAI5zuk54z4qeIzr7b8cjxx5xZulJUA,26262
232
+ aurelian/cli.py,sha256=nRCLPZb__FpMsHqNnDeoYCc0KspESumIKQlrDe97594,34510
223
233
  aurelian/dependencies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
224
234
  aurelian/dependencies/workdir.py,sha256=G_eGlxKpHRjO3EL2hHN8lvtticgSZvJe300KkJP4vZQ,2228
225
235
  aurelian/mcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -247,8 +257,8 @@ aurelian/utils/pubmed_utils.py,sha256=Gk00lu1Lv0GRSNeF5M4zplp3UMSpe5byCaVKCJimUH
247
257
  aurelian/utils/pytest_report_to_markdown.py,sha256=WH1NlkVYj0UfUqpXjRD1KMpkMgEW3qev3fDdPvZG9Yw,1406
248
258
  aurelian/utils/robot_ontology_utils.py,sha256=aaRe9eyLgJCtj1EfV13v4Q7khFTWzUoFFEE_lizGuGg,3591
249
259
  aurelian/utils/search_utils.py,sha256=9MloT3SzOE4JsElsYlCznp9N6fv_OQK7YWOU8MIy1WU,2818
250
- aurelian-0.3.2.dist-info/LICENSE,sha256=FB6RpUUfbUeKS4goWrvpp1QmOtyywrMiNBsYPMlLT3A,1086
251
- aurelian-0.3.2.dist-info/METADATA,sha256=JGCNT-mSHzJpDVepHnUrCHt8z3ZrXWFOXZ111Q_EViU,3339
252
- aurelian-0.3.2.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
253
- aurelian-0.3.2.dist-info/entry_points.txt,sha256=BInUyPfLrHdmH_Yvi71dx21MhkcNCEOPiqvpEIb2U5k,46
254
- aurelian-0.3.2.dist-info/RECORD,,
260
+ aurelian-0.3.4.dist-info/LICENSE,sha256=FB6RpUUfbUeKS4goWrvpp1QmOtyywrMiNBsYPMlLT3A,1086
261
+ aurelian-0.3.4.dist-info/METADATA,sha256=o6MapyVbBF6DMGrYZMYBNc-JKm2q-uv3qjSVCwuXR0E,3471
262
+ aurelian-0.3.4.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
263
+ aurelian-0.3.4.dist-info/entry_points.txt,sha256=BInUyPfLrHdmH_Yvi71dx21MhkcNCEOPiqvpEIb2U5k,46
264
+ aurelian-0.3.4.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.1.2
2
+ Generator: poetry-core 2.1.3
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any