scmcp-shared 0.5.0__tar.gz → 0.6.0__tar.gz
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.
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/.github/workflows/test.yml +9 -3
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/PKG-INFO +5 -2
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/pyproject.toml +5 -2
- scmcp_shared-0.6.0/src/scmcp_shared/__init__.py +1 -0
- scmcp_shared-0.6.0/src/scmcp_shared/agent.py +47 -0
- scmcp_shared-0.6.0/src/scmcp_shared/kb.py +139 -0
- scmcp_shared-0.6.0/src/scmcp_shared/server/__init__.py +8 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/server/auto.py +5 -3
- scmcp_shared-0.6.0/src/scmcp_shared/server/rag.py +13 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/tests/conftest.py +2 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/tests/test_io.py +2 -2
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/tests/test_pp.py +17 -17
- scmcp_shared-0.6.0/tests/test_select_tool.py +16 -0
- scmcp_shared-0.5.0/src/scmcp_shared/__init__.py +0 -1
- scmcp_shared-0.5.0/src/scmcp_shared/agent.py +0 -80
- scmcp_shared-0.5.0/src/scmcp_shared/kb.py +0 -38
- scmcp_shared-0.5.0/src/scmcp_shared/server/__init__.py +0 -1
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/0-9499b1b5-85d4-44c2-8f05-1bcce87fe4ef.txn +0 -3
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/1-1632e7a3-4427-4077-8d03-57437144443d.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/10-dcf66479-eafb-4193-9358-198154aea1c1.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/11-2c6ddc17-49f5-47b5-8764-753297cf9e1b.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/12-f079d0a2-9c1c-4e7a-abf6-3e3c4cddac11.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/13-5bda9382-a06e-493d-85cb-e066172778ce.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/14-6f9c669f-25e2-4096-b7ea-9b421a37e110.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/15-2068cca9-31e8-45a3-86d1-bcb8924c72b9.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/16-72356bb2-5c98-424e-97aa-a92fa3453da6.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/17-9baa67ce-f6d3-478c-9511-20d01988d4d5.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/18-b9f2e28e-c4c5-4ce7-bf58-402d53a39558.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/19-d199d9f9-7990-4ec0-adde-e98c1c927202.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/2-3827747c-095e-41cb-af69-3814bab3a588.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/20-31c197a3-7a23-472f-a7e3-056c0ff11e3a.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/21-066e3024-36f8-4557-83ae-d2f338ec045c.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/22-1d1ccbe5-7c4c-4882-986a-c61ec2f7925e.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/23-b2c41628-b2d6-49f1-81b5-3cd9100894b4.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/24-e43e2e8d-9dd8-479f-b63c-d147e737c49f.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/25-188708e9-5ee1-4b5c-8e13-45dec8efd60d.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/26-4f4b6316-5680-4b31-8dd6-215cce66d7b5.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/27-c1855f86-abab-44ef-9e61-1312dffc9b06.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/28-650d2be0-e977-4177-b457-b733eea8b6ea.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/29-e47751d8-0e44-46da-82bd-4836b00a8431.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/3-518fc9b8-67de-48f7-94c8-f2398c63dbc5.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/30-0db3ea0f-deca-4b5b-9d70-9fb5f741f90c.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/31-ef76f0bb-bcfa-4031-b3ad-94b51ee818a9.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/32-a763e0f1-5c8d-460f-a455-0c6f6c4f1450.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/33-30bce2aa-8e6f-4f42-a323-c420133aa20f.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/34-f91ec2f9-d34b-4fcf-8bc7-564c28e50538.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/35-7f36a75c-96a7-4868-a4db-5d5f78ecf850.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/36-f2df7f99-a37c-458a-958d-7eb5e81eee18.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/37-e0af7415-955b-4167-8705-fa9ddb643e9a.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/38-6c24a9f0-ce71-4dda-8193-479aa23c5456.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/39-72b8a20c-3112-4cf1-8b05-b74a2c02c3f2.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/4-42904942-5a79-4f28-90ce-35a4ae8c40d1.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/40-95ac7526-6a2e-4914-9654-288c41bff370.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/41-13430464-5e62-4aa8-9709-513693a75095.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/42-cbb1ad83-a906-4540-bc37-4db158eac618.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/43-3c246401-d742-49a9-b24d-cfc457685461.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/44-11315c14-ecf4-4e3d-8690-46d57cb3e8c0.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/45-7bbf4bc6-96d4-425a-afa2-34aec7121c85.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/5-82dda0b4-7838-4f04-90f3-4b1e932c6891.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/6-c78352d8-16ba-4814-bd7f-74b8c0c5efe7.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/7-bb882b35-63f3-4c52-870f-6a64e3ac7f3c.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/8-fc84ad1b-1b59-4822-8fc7-70f4eb18f6d9.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_transactions/9-3404dcf1-bb17-40e6-9e5d-d9942dff90b2.txn +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/1.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/10.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/11.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/12.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/13.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/14.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/15.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/16.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/17.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/18.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/19.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/2.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/20.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/21.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/22.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/23.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/24.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/25.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/26.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/27.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/28.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/29.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/3.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/30.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/31.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/32.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/33.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/34.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/35.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/36.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/37.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/38.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/39.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/4.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/40.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/41.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/42.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/43.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/44.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/45.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/46.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/5.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/6.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/7.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/8.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/_versions/9.manifest +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/0cc94dc3-2ca3-403c-a9df-59753f24b3f2.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/254a1a71-cdd2-4cca-b7ec-a50540fed62c.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/2574d216-5f05-4794-9e1c-986fafde6ab4.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/26c7bbe7-5f97-4453-b065-123b764448b3.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/286595a6-88f6-4b05-861e-e4f607a6fcdb.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/33219b1a-7575-46ef-bb64-2bdbde1e692b.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/344ad7dd-98bb-41de-b347-2f17bf5735cb.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/395b1ecb-68fe-4dd3-a770-4b3ed393ae0c.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/3db97f4c-9c35-44b7-9042-82b4006c5a22.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/4540246e-b0bb-4f4d-8f98-60a64f1c42ed.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/4643dbc0-9e45-4b63-81e1-e06cf9bddcec.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/4f28eb52-d409-43f2-ae17-d1826f209006.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/4fda4a22-35f0-4897-b4c5-6cedefba66e6.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/51ee77b6-ab24-44c0-916e-b81ff3912731.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/539d15c9-e88b-400c-9ab7-08f5e8dca10d.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/54007132-91f5-4909-8678-c471ef4d100f.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/546d88ec-0d5c-42bb-bccc-3271f3f183a4.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/6912ad8a-343c-4ca1-b1b7-4300125e688e.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/6b72e4f7-3051-40a4-a492-6d9eff1c647d.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/6d7ee320-ae1c-4e49-8ce5-c85971b11ce6.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/6ea47b70-69d4-43e9-b2c6-442fe50e4dd1.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/72adb5ed-bf11-4d06-b146-0272d333db08.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/745907df-e261-4f4b-a757-2c01c058bf27.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/78988307-4c66-4ad7-b295-7463ecd53609.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/798ce305-6d60-4f28-b82a-e1f647907abf.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/7c159cce-2741-442b-9c63-f44bf2996718.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/7cd7a818-e68b-4fa8-bad3-23b60c386670.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/7ec553ed-0c7a-4bac-99b2-2ad976b40466.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/83efdc85-d990-4762-b69a-fb1c3938f60f.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/8c1613b3-8d69-49c5-bfd0-a021bb516faf.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/95cd1b22-1f93-4133-9841-de21549ad8c5.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/9a2ea5d4-087e-4d3a-b64b-6c568b8a0010.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/b1c47dc6-450a-4dca-b465-badb6a3619c2.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/b21d183a-c51d-463b-932e-9beb2e0da9aa.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/b2598625-8683-4c33-be40-6f1a7555dc2c.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/b7297b39-1fc5-4886-be21-708b369bef59.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/b7d90085-5bd6-48f9-8a73-17eb7cf556fa.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/b988ceee-57fc-423b-8e67-5729086c6946.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/bfd68ea6-ddf4-44bb-aa87-2669f0462f7d.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/cb8ac58e-0e59-4391-95ab-6195e71b9625.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/d0f10434-afb5-49c5-9e77-d39a4f8cca94.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/d3f89fec-5795-4e11-8c15-bc2206a7fae2.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/e063c8a4-5ef1-4933-a049-b41049d9be5f.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/e2348b24-f290-4fe2-a6c8-e98009ae4c1b.lance +0 -0
- scmcp_shared-0.5.0/src/scmcp_shared/vector_db/decoupler.lance/data/e5d3f893-6763-40dc-9d02-04e2f56a4883.lance +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/.github/release.yml +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/.github/workflows/publish.yml +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/.pre-commit-config.yaml +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/LICENSE +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/README.md +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/backend.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/cli.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/logging_config.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/mcp_base.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/schema/__init__.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/schema/io.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/schema/pl.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/schema/pp.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/schema/preset/__init__.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/schema/preset/io.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/schema/preset/pl.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/schema/preset/pp.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/schema/preset/tl.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/schema/preset/util.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/schema/tl.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/schema/tool.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/schema/util.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/server/code.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/server/preset/__init__.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/server/preset/io.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/server/preset/pl.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/server/preset/pp.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/server/preset/tl.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/server/preset/util.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/src/scmcp_shared/util.py +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/tests/data/hg19/barcodes.tsv +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/tests/data/hg19/genes.tsv +0 -0
- {scmcp_shared-0.5.0 → scmcp_shared-0.6.0}/tests/data/hg19/matrix.mtx +0 -0
@@ -2,13 +2,20 @@ name: test package
|
|
2
2
|
|
3
3
|
on:
|
4
4
|
push:
|
5
|
-
branches: [
|
5
|
+
branches: ["main"]
|
6
6
|
pull_request:
|
7
|
-
branches: [
|
7
|
+
branches: ["main"]
|
8
8
|
|
9
9
|
jobs:
|
10
10
|
test:
|
11
11
|
runs-on: ubuntu-latest
|
12
|
+
env:
|
13
|
+
MODEL: ${{ vars.MODEL }}
|
14
|
+
BASE_URL: ${{ vars.BASE_URL }}
|
15
|
+
API_KEY: ${{ secrets.API_KEY }}
|
16
|
+
EMBEDDER_MODEL: ${{ vars.EMBEDDER_MODEL }}
|
17
|
+
EMBEDDER_BASE_URL: ${{ vars.EMBEDDER_BASE_URL }}
|
18
|
+
EMBEDDER_API_KEY: ${{ secrets.EMBEDDER_API_KEY }}
|
12
19
|
strategy:
|
13
20
|
matrix:
|
14
21
|
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
@@ -31,4 +38,3 @@ jobs:
|
|
31
38
|
|
32
39
|
- name: Run pytest
|
33
40
|
run: uv run --no-sync pytest
|
34
|
-
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: scmcp_shared
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.6.0
|
4
4
|
Summary: A shared function libray for scmcphub
|
5
5
|
Project-URL: Homepage, http://scmcphub.org/
|
6
6
|
Project-URL: Repository, https://github.com/scmcphub/scmcp-shared
|
@@ -38,12 +38,15 @@ License-File: LICENSE
|
|
38
38
|
Keywords: AI,agent,bioinformatics,llm,mcp,model context protocol,scRNA-seq,single cell
|
39
39
|
Requires-Python: >=3.10
|
40
40
|
Requires-Dist: abcoder
|
41
|
+
Requires-Dist: agno
|
41
42
|
Requires-Dist: fastmcp>=2.7.0
|
42
43
|
Requires-Dist: igraph
|
43
|
-
Requires-Dist:
|
44
|
+
Requires-Dist: lancedb
|
44
45
|
Requires-Dist: leidenalg
|
45
46
|
Requires-Dist: mcp>=1.8.0
|
46
47
|
Requires-Dist: nest-asyncio
|
48
|
+
Requires-Dist: openai
|
49
|
+
Requires-Dist: requests
|
47
50
|
Requires-Dist: scanpy
|
48
51
|
Description-Content-Type: text/markdown
|
49
52
|
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "0.6.0"
|
@@ -0,0 +1,47 @@
|
|
1
|
+
from .schema.tool import ToolList
|
2
|
+
import os
|
3
|
+
|
4
|
+
|
5
|
+
from agno.agent import Agent
|
6
|
+
from agno.models.openai import OpenAILike
|
7
|
+
from scmcp_shared.kb import load_kb
|
8
|
+
|
9
|
+
model = OpenAILike(
|
10
|
+
id=os.getenv("MODEL"),
|
11
|
+
base_url=os.getenv("BASE_URL"),
|
12
|
+
api_key=os.getenv("API_KEY"),
|
13
|
+
)
|
14
|
+
|
15
|
+
|
16
|
+
def rag_agent(task, software=None):
|
17
|
+
knowledge_base = load_kb(software=software)
|
18
|
+
agent = Agent(
|
19
|
+
model=model,
|
20
|
+
knowledge=knowledge_base,
|
21
|
+
show_tool_calls=True,
|
22
|
+
search_knowledge=True,
|
23
|
+
)
|
24
|
+
query = f"""
|
25
|
+
<task>
|
26
|
+
{task}
|
27
|
+
</task>
|
28
|
+
查询知识库,给出一个用于解决任务的代码示例。返回结果格式为:
|
29
|
+
<code_example>
|
30
|
+
[code_example]
|
31
|
+
</code_example>
|
32
|
+
"""
|
33
|
+
rep = agent.run(query)
|
34
|
+
return rep.content
|
35
|
+
|
36
|
+
|
37
|
+
def select_tool(query):
|
38
|
+
agent = Agent(
|
39
|
+
model=model,
|
40
|
+
response_model=ToolList,
|
41
|
+
use_json_mode=True,
|
42
|
+
instructions="""
|
43
|
+
you are a bioinformatician, you are given a task and a list of tools, you need to select the most directly relevant tools to use to solve the task
|
44
|
+
""",
|
45
|
+
)
|
46
|
+
rep = agent.run(query)
|
47
|
+
return rep.content
|
@@ -0,0 +1,139 @@
|
|
1
|
+
from agno.document.chunking.agentic import AgenticChunking
|
2
|
+
from agno.embedder.openai import OpenAIEmbedder
|
3
|
+
from agno.models.deepseek import DeepSeek
|
4
|
+
from agno.vectordb.lancedb import LanceDb
|
5
|
+
from agno.knowledge.agent import AgentKnowledge
|
6
|
+
import importlib.resources
|
7
|
+
import os
|
8
|
+
import requests
|
9
|
+
import zipfile
|
10
|
+
import tempfile
|
11
|
+
import shutil
|
12
|
+
from pathlib import Path
|
13
|
+
import logging
|
14
|
+
|
15
|
+
logger = logging.getLogger(__name__)
|
16
|
+
|
17
|
+
embedder_id = os.getenv("EMBEDDER_MODEL")
|
18
|
+
embedder_api_key = os.getenv("EMBEDDER_API_KEY")
|
19
|
+
embedder_base_url = os.getenv("EMBEDDER_BASE_URL")
|
20
|
+
model_id = os.getenv("MODEL")
|
21
|
+
model_api_key = os.getenv("API_KEY")
|
22
|
+
model_base_url = os.getenv("BASE_URL")
|
23
|
+
|
24
|
+
# 配置信息
|
25
|
+
config = {
|
26
|
+
"local_dir": "vector_db",
|
27
|
+
"huggingface_url": "https://huggingface.co/datasets/huangshing/scmcp_vector_db/resolve/main/vector_db.zip",
|
28
|
+
}
|
29
|
+
|
30
|
+
|
31
|
+
def download_vector_db(source="huggingface"):
|
32
|
+
"""
|
33
|
+
下载向量数据库文件
|
34
|
+
|
35
|
+
Args:
|
36
|
+
source: 下载源 ("huggingface" 或 "github")
|
37
|
+
"""
|
38
|
+
|
39
|
+
# 获取本地存储路径
|
40
|
+
package_path = importlib.resources.path("scmcp_shared", "")
|
41
|
+
local_dir = Path(package_path) / config["local_dir"]
|
42
|
+
local_dir.mkdir(exist_ok=True)
|
43
|
+
|
44
|
+
# 检查是否已存在
|
45
|
+
if (local_dir / "scmcp.lance").exists():
|
46
|
+
logger.info("Vector database already exists locally")
|
47
|
+
return str(local_dir)
|
48
|
+
|
49
|
+
logger.info(f"Downloading vector database from {source}...")
|
50
|
+
|
51
|
+
# 创建临时目录用于下载和解压
|
52
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
53
|
+
temp_path = Path(temp_dir)
|
54
|
+
zip_path = temp_path / "vector_db.zip"
|
55
|
+
|
56
|
+
try:
|
57
|
+
# 下载文件
|
58
|
+
if source == "huggingface":
|
59
|
+
url = config["huggingface_url"]
|
60
|
+
else:
|
61
|
+
raise ValueError(f"Unsupported source: {source}")
|
62
|
+
|
63
|
+
logger.info(f"Downloading from: {url}")
|
64
|
+
response = requests.get(url, stream=True)
|
65
|
+
response.raise_for_status()
|
66
|
+
|
67
|
+
with open(zip_path, "wb") as f:
|
68
|
+
for chunk in response.iter_content(chunk_size=8192):
|
69
|
+
f.write(chunk)
|
70
|
+
|
71
|
+
# 解压文件
|
72
|
+
logger.info("Extracting downloaded archive...")
|
73
|
+
_extract_archive(zip_path, local_dir)
|
74
|
+
|
75
|
+
logger.info(f"Vector database downloaded and extracted to: {local_dir}")
|
76
|
+
return str(local_dir)
|
77
|
+
|
78
|
+
except requests.RequestException as e:
|
79
|
+
raise RuntimeError(f"Failed to download vector database: {e}")
|
80
|
+
except Exception as e:
|
81
|
+
raise RuntimeError(f"Failed to process vector database: {e}")
|
82
|
+
|
83
|
+
|
84
|
+
def _extract_archive(archive_path, extract_dir):
|
85
|
+
"""解压归档文件"""
|
86
|
+
with zipfile.ZipFile(archive_path, "r") as zip_ref:
|
87
|
+
zip_ref.extractall(extract_dir)
|
88
|
+
|
89
|
+
# 如果解压后只有一个子目录,移动内容到目标目录
|
90
|
+
extracted_items = list(Path(extract_dir).iterdir())
|
91
|
+
if len(extracted_items) == 1 and extracted_items[0].is_dir():
|
92
|
+
subdir = extracted_items[0]
|
93
|
+
for item in subdir.iterdir():
|
94
|
+
shutil.move(str(item), str(extract_dir / item.name))
|
95
|
+
subdir.rmdir()
|
96
|
+
|
97
|
+
|
98
|
+
def load_kb(software=None, auto_download=True, download_source="huggingface"):
|
99
|
+
"""
|
100
|
+
加载知识库
|
101
|
+
|
102
|
+
Args:
|
103
|
+
software: 软件名称
|
104
|
+
auto_download: 是否自动下载向量数据库
|
105
|
+
download_source: 下载源 ("huggingface" 或 "github")
|
106
|
+
"""
|
107
|
+
# 获取向量数据库路径
|
108
|
+
try:
|
109
|
+
vector_db_path = importlib.resources.path("scmcp_shared", "vector_db")
|
110
|
+
except FileNotFoundError:
|
111
|
+
if auto_download:
|
112
|
+
logger.info("Vector database not found in package, attempting download...")
|
113
|
+
vector_db_path = download_vector_db(download_source)
|
114
|
+
else:
|
115
|
+
raise FileNotFoundError(
|
116
|
+
"Vector database not found. Set auto_download=True to download automatically, "
|
117
|
+
"or manually place the vector database in the scmcp_shared package."
|
118
|
+
)
|
119
|
+
|
120
|
+
vector_db = LanceDb(
|
121
|
+
table_name=software,
|
122
|
+
uri=vector_db_path,
|
123
|
+
embedder=OpenAIEmbedder(
|
124
|
+
id=embedder_id,
|
125
|
+
base_url=embedder_base_url,
|
126
|
+
api_key=embedder_api_key,
|
127
|
+
),
|
128
|
+
)
|
129
|
+
model = DeepSeek(
|
130
|
+
id=model_id,
|
131
|
+
base_url=model_base_url,
|
132
|
+
api_key=model_api_key,
|
133
|
+
)
|
134
|
+
knowledge_base = AgentKnowledge(
|
135
|
+
chunking_strategy=AgenticChunking(model=model),
|
136
|
+
vector_db=vector_db,
|
137
|
+
)
|
138
|
+
|
139
|
+
return knowledge_base
|
@@ -15,17 +15,19 @@ def search_tool(
|
|
15
15
|
"""search the tools and get tool parameters that can be used to solve the user's tasks or questions"""
|
16
16
|
ctx = get_context()
|
17
17
|
fastmcp = ctx.fastmcp
|
18
|
-
|
18
|
+
if hasattr(fastmcp._tool_manager, "_all_tools"):
|
19
|
+
all_tools = fastmcp._tool_manager._all_tools
|
20
|
+
else:
|
21
|
+
all_tools = fastmcp._tool_manager._tools
|
19
22
|
auto_tools = fastmcp._tool_manager._tools
|
20
23
|
fastmcp._tool_manager._tools = all_tools
|
21
24
|
query = f"<task>{task}</task>\n"
|
22
25
|
for name in all_tools:
|
23
26
|
tool = all_tools[name]
|
24
27
|
query += f"<Tool>\n<name>{name}</name>\n<description>{tool.description}</description>\n</Tool>\n"
|
25
|
-
|
26
28
|
results = select_tool(query)
|
27
29
|
tool_list = []
|
28
|
-
for tool in results:
|
30
|
+
for tool in results.tools:
|
29
31
|
tool = tool.model_dump()
|
30
32
|
tool["parameters"] = all_tools[tool["name"]].parameters
|
31
33
|
tool_list.append(tool)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
from fastmcp import FastMCP
|
2
|
+
from ..agent import rag_agent
|
3
|
+
from pydantic import Field
|
4
|
+
|
5
|
+
rag_mcp = FastMCP("RAG-Server")
|
6
|
+
|
7
|
+
|
8
|
+
@rag_mcp.tool(tags={"rag"})
|
9
|
+
def retrieve_knowledge(
|
10
|
+
task: str = Field(description="The tasks or questions that needs to be solved"),
|
11
|
+
):
|
12
|
+
"""search function and parameters that can be used to solve the user's tasks or questions"""
|
13
|
+
return rag_agent(task, software="scmcp")
|
@@ -6,6 +6,7 @@ from scmcp_shared.server.preset import ScanpyPreprocessingMCP
|
|
6
6
|
from scmcp_shared.server.preset import ScanpyToolsMCP
|
7
7
|
from scmcp_shared.server.preset import ScanpyPlottingMCP
|
8
8
|
from scmcp_shared.server.preset import ScanpyUtilMCP
|
9
|
+
from scmcp_shared.server.auto import auto_mcp
|
9
10
|
|
10
11
|
|
11
12
|
class ScanpyMCPManager(BaseMCPManager):
|
@@ -19,6 +20,7 @@ class ScanpyMCPManager(BaseMCPManager):
|
|
19
20
|
"tl": ScanpyToolsMCP().mcp,
|
20
21
|
"pl": ScanpyPlottingMCP().mcp,
|
21
22
|
"ul": ScanpyUtilMCP().mcp,
|
23
|
+
"auto": auto_mcp,
|
22
24
|
}
|
23
25
|
|
24
26
|
|
@@ -15,9 +15,9 @@ async def test_read_and_write(mcp):
|
|
15
15
|
async with Client(mcp) as client:
|
16
16
|
# tools = await client.list_tools()
|
17
17
|
# client._tools = tools
|
18
|
-
print(mcp._tool_manager._tools, 123)
|
19
18
|
result = await client.call_tool("io_read", {"request": {"filename": test_dir}})
|
20
|
-
|
19
|
+
print(result)
|
20
|
+
assert "AnnData" in result.content[0].text
|
21
21
|
|
22
22
|
result = await client.call_tool("io_write", {"request": {"filename": outfile}})
|
23
23
|
assert outfile.exists()
|
@@ -13,17 +13,17 @@ async def test_complete_workflow(mcp):
|
|
13
13
|
async with Client(mcp) as client:
|
14
14
|
# Load the data
|
15
15
|
result = await client.call_tool("io_read", {"request": {"filename": test_dir}})
|
16
|
-
assert "AnnData" in result[0].text
|
16
|
+
assert "AnnData" in result.content[0].text
|
17
17
|
|
18
18
|
# Filter cells and genes
|
19
19
|
result = await client.call_tool(
|
20
20
|
"pp_subset_cells", {"request": {"min_genes": 200}}
|
21
21
|
)
|
22
|
-
assert "AnnData" in result[0].text
|
22
|
+
assert "AnnData" in result.content[0].text
|
23
23
|
result = await client.call_tool(
|
24
24
|
"pp_subset_genes", {"request": {"min_cells": 3}}
|
25
25
|
)
|
26
|
-
assert "AnnData" in result[0].text
|
26
|
+
assert "AnnData" in result.content[0].text
|
27
27
|
|
28
28
|
# Add mitochondrial genes and calculate QC metrics
|
29
29
|
result = await client.call_tool(
|
@@ -36,73 +36,73 @@ async def test_complete_workflow(mcp):
|
|
36
36
|
}
|
37
37
|
},
|
38
38
|
)
|
39
|
-
assert "mt" in result[0].text
|
39
|
+
assert "mt" in result.content[0].text
|
40
40
|
result = await client.call_tool(
|
41
41
|
"pp_calculate_qc_metrics",
|
42
42
|
{"request": {"qc_vars": ["mt"], "percent_top": None, "log1p": False}},
|
43
43
|
)
|
44
|
-
assert "total_counts" in result[0].text
|
44
|
+
assert "total_counts" in result.content[0].text
|
45
45
|
|
46
46
|
# Filter based on QC metrics
|
47
47
|
result = await client.call_tool(
|
48
48
|
"pp_subset_cells", {"request": {"max_genes": 2500, "max_mt_percent": 5}}
|
49
49
|
)
|
50
|
-
assert "AnnData" in result[0].text
|
50
|
+
assert "AnnData" in result.content[0].text
|
51
51
|
|
52
52
|
# Normalize and transform
|
53
53
|
result = await client.call_tool(
|
54
54
|
"pp_normalize_total", {"request": {"target_sum": 1e4}}
|
55
55
|
)
|
56
|
-
assert "AnnData" in result[0].text
|
56
|
+
assert "AnnData" in result.content[0].text
|
57
57
|
result = await client.call_tool("pp_log1p", {"request": {}})
|
58
|
-
assert "log1p" in result[0].text
|
58
|
+
assert "log1p" in result.content[0].text
|
59
59
|
|
60
60
|
# Find highly variable genes
|
61
61
|
result = await client.call_tool(
|
62
62
|
"pp_highly_variable_genes",
|
63
63
|
{"request": {"min_mean": 0.0125, "max_mean": 3, "min_disp": 0.5}},
|
64
64
|
)
|
65
|
-
assert "highly_variable" in result[0].text
|
65
|
+
assert "highly_variable" in result.content[0].text
|
66
66
|
|
67
67
|
# Subset to highly variable genes
|
68
68
|
result = await client.call_tool(
|
69
69
|
"pp_subset_genes", {"request": {"highly_variable": True}}
|
70
70
|
)
|
71
|
-
assert "AnnData" in result[0].text
|
71
|
+
assert "AnnData" in result.content[0].text
|
72
72
|
|
73
73
|
# Regress out effects
|
74
74
|
result = await client.call_tool(
|
75
75
|
"pp_regress_out", {"request": {"keys": ["total_counts", "pct_counts_mt"]}}
|
76
76
|
)
|
77
|
-
assert "AnnData" in result[0].text
|
77
|
+
assert "AnnData" in result.content[0].text
|
78
78
|
|
79
79
|
# Scale the data
|
80
80
|
result = await client.call_tool("pp_scale", {"request": {"max_value": 10}})
|
81
|
-
assert "AnnData" in result[0].text
|
81
|
+
assert "AnnData" in result.content[0].text
|
82
82
|
|
83
83
|
# PCA
|
84
84
|
result = await client.call_tool(
|
85
85
|
"tl_pca", {"request": {"n_comps": 50, "svd_solver": "arpack"}}
|
86
86
|
)
|
87
|
-
assert "X_pca" in result[0].text
|
87
|
+
assert "X_pca" in result.content[0].text
|
88
88
|
|
89
89
|
# Compute neighborhood graph
|
90
90
|
result = await client.call_tool(
|
91
91
|
"pp_neighbors", {"request": {"n_neighbors": 10, "n_pcs": 40}}
|
92
92
|
)
|
93
|
-
assert "neighbors" in result[0].text
|
93
|
+
assert "neighbors" in result.content[0].text
|
94
94
|
|
95
95
|
# Leiden clustering
|
96
96
|
result = await client.call_tool("tl_leiden", {"request": {}})
|
97
|
-
assert "leiden" in result[0].text
|
97
|
+
assert "leiden" in result.content[0].text
|
98
98
|
|
99
99
|
# UMAP
|
100
100
|
result = await client.call_tool("tl_umap", {"request": {}})
|
101
|
-
assert "X_umap" in result[0].text
|
101
|
+
assert "X_umap" in result.content[0].text
|
102
102
|
|
103
103
|
# Plot UMAP
|
104
104
|
result = await client.call_tool(
|
105
105
|
"pl_embedding",
|
106
106
|
{"request": {"basis": "umap", "color": ["leiden", "NKG7", "PPBP"]}},
|
107
107
|
)
|
108
|
-
assert "figure" in result[0].text
|
108
|
+
assert "figure" in result.content[0].text
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import pytest
|
2
|
+
from fastmcp import Client
|
3
|
+
import nest_asyncio
|
4
|
+
|
5
|
+
# Apply nest_asyncio at module level
|
6
|
+
nest_asyncio.apply()
|
7
|
+
|
8
|
+
|
9
|
+
@pytest.mark.asyncio
|
10
|
+
async def test_tool_selection(mcp):
|
11
|
+
task = """
|
12
|
+
read the file /date/test.h5ad , filter the cells with ncells>100
|
13
|
+
"""
|
14
|
+
async with Client(mcp) as client:
|
15
|
+
result = await client.call_tool("auto_search_tool", {"task": task})
|
16
|
+
assert "io_read" in result.content[0].text
|
@@ -1 +0,0 @@
|
|
1
|
-
__version__ = "0.5.0"
|
@@ -1,80 +0,0 @@
|
|
1
|
-
import instructor
|
2
|
-
from openai import OpenAI
|
3
|
-
from scmcp_shared.schema.tool import ToolList
|
4
|
-
import os
|
5
|
-
|
6
|
-
|
7
|
-
from agno.agent import Agent
|
8
|
-
from agno.models.openai import OpenAILike
|
9
|
-
from scmcp_shared.kb import load_kb
|
10
|
-
|
11
|
-
model = OpenAILike(
|
12
|
-
id=os.getenv("MODEL"),
|
13
|
-
base_url=os.getenv("BASE_URL"),
|
14
|
-
api_key=os.getenv("API_KEY"),
|
15
|
-
)
|
16
|
-
|
17
|
-
|
18
|
-
def rag_agent(task, software=None):
|
19
|
-
knowledge_base = load_kb(software=software)
|
20
|
-
agent = Agent(
|
21
|
-
model=model,
|
22
|
-
knowledge=knowledge_base,
|
23
|
-
show_tool_calls=True,
|
24
|
-
search_knowledge=True,
|
25
|
-
)
|
26
|
-
query = f"""
|
27
|
-
<task>
|
28
|
-
{task}
|
29
|
-
</task>
|
30
|
-
拆分任务,分别查询知识库,查找完成每个子任务所需要的函数以及参数, 给出一个总的用于解决任务的代码示例。返回结果格式为:
|
31
|
-
<function_list>
|
32
|
-
<function>
|
33
|
-
<package>.<module>.<function_name>
|
34
|
-
<package>.<module>.<function_name>(<param1>[, <param2>=<default>][, ...][, **kwargs])
|
35
|
-
<一句话描述函数的主要功能>。
|
36
|
-
|
37
|
-
<可选:补充说明/实现细节/依赖等>
|
38
|
-
|
39
|
-
Parameters
|
40
|
-
:
|
41
|
-
<param1> (<type>) – <param1 的说明>
|
42
|
-
|
43
|
-
<param2> (<type> (default: <default>)) – <param2 的说明>
|
44
|
-
|
45
|
-
<param3> (<type> (default: <default>)) – <param3 的说明>
|
46
|
-
|
47
|
-
...(按需继续列出其他参数)
|
48
|
-
|
49
|
-
**kwargs – <对底层实现传递的其他关键字参数的说明;如无需说明可简写为“其他关键字参数”。>
|
50
|
-
</function>
|
51
|
-
...
|
52
|
-
</function_list>
|
53
|
-
<code_example>
|
54
|
-
[code_example]
|
55
|
-
</code_example>
|
56
|
-
"""
|
57
|
-
rep = agent.run(query)
|
58
|
-
return rep.content
|
59
|
-
|
60
|
-
|
61
|
-
def select_tool(query):
|
62
|
-
API_KEY = os.environ.get("API_KEY", None)
|
63
|
-
BASE_URL = os.environ.get("BASE_URL", None)
|
64
|
-
MODEL = os.environ.get("MODEL", None)
|
65
|
-
|
66
|
-
client = OpenAI(api_key=API_KEY, base_url=BASE_URL)
|
67
|
-
client = instructor.from_openai(client)
|
68
|
-
|
69
|
-
response = client.chat.completions.create(
|
70
|
-
model=MODEL,
|
71
|
-
messages=[
|
72
|
-
{
|
73
|
-
"role": "system",
|
74
|
-
"content": "you are a bioinformatician, you are given a task and a list of tools, you need to select the most directly relevant tools to use to solve the task",
|
75
|
-
},
|
76
|
-
{"role": "user", "content": query},
|
77
|
-
],
|
78
|
-
response_model=ToolList,
|
79
|
-
)
|
80
|
-
return response.tools
|
@@ -1,38 +0,0 @@
|
|
1
|
-
from agno.document.chunking.agentic import AgenticChunking
|
2
|
-
from agno.embedder.openai import OpenAIEmbedder
|
3
|
-
from agno.models.deepseek import DeepSeek
|
4
|
-
from agno.vectordb.lancedb import LanceDb
|
5
|
-
from agno.knowledge.agent import AgentKnowledge
|
6
|
-
import importlib.resources
|
7
|
-
import os
|
8
|
-
|
9
|
-
|
10
|
-
embedder_id = os.getenv("EMBEDDER_MODEL")
|
11
|
-
embedder_api_key = os.getenv("EMBEDDER_API_KEY")
|
12
|
-
embedder_base_url = os.getenv("EMBEDDER_BASE_URL")
|
13
|
-
model_id = os.getenv("MODEL")
|
14
|
-
model_api_key = os.getenv("API_KEY")
|
15
|
-
model_base_url = os.getenv("BASE_URL")
|
16
|
-
|
17
|
-
|
18
|
-
def load_kb(software=None):
|
19
|
-
vector_db = LanceDb(
|
20
|
-
table_name=software,
|
21
|
-
uri=importlib.resources.path("scmcp_shared", "vector_db"),
|
22
|
-
embedder=OpenAIEmbedder(
|
23
|
-
id=embedder_id,
|
24
|
-
base_url=embedder_base_url,
|
25
|
-
api_key=embedder_api_key,
|
26
|
-
),
|
27
|
-
)
|
28
|
-
model = DeepSeek(
|
29
|
-
id=model_id,
|
30
|
-
base_url=model_base_url,
|
31
|
-
api_key=model_api_key,
|
32
|
-
)
|
33
|
-
knowledge_base = AgentKnowledge(
|
34
|
-
chunking_strategy=AgenticChunking(model=model),
|
35
|
-
vector_db=vector_db,
|
36
|
-
)
|
37
|
-
|
38
|
-
return knowledge_base
|
@@ -1 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|