celltype-cli 0.1.2__tar.gz → 0.1.3__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.
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/PKG-INFO +4 -3
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/README.md +1 -1
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/install.sh +11 -8
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/pyproject.toml +3 -2
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/agent/config.py +10 -1
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/agent/doctor.py +6 -5
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/agent/runner.py +18 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/agent/sandbox.py +5 -2
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/cli.py +7 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/models/llm.py +6 -3
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_config.py +21 -1
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/commands/opsx/apply.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/commands/opsx/archive.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/commands/opsx/bulk-archive.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/commands/opsx/continue.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/commands/opsx/explore.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/commands/opsx/ff.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/commands/opsx/new.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/commands/opsx/onboard.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/commands/opsx/sync.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/commands/opsx/verify.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/settings.local.json +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/skills/openspec-apply-change/SKILL.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/skills/openspec-archive-change/SKILL.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/skills/openspec-bulk-archive-change/SKILL.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/skills/openspec-continue-change/SKILL.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/skills/openspec-explore/SKILL.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/skills/openspec-ff-change/SKILL.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/skills/openspec-new-change/SKILL.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/skills/openspec-onboard/SKILL.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/skills/openspec-sync-specs/SKILL.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/skills/openspec-verify-change/SKILL.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.dockerignore +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.github/workflows/ci.yml +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/.gitignore +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/CLAUDE.md +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/Dockerfile +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/Dockerfile.api +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/LICENSE +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/assets/bixbench_benchmark.png +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/assets/ct2.gif +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/docker-compose.yml +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/openspec/config.yaml +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/scripts/prepare_datasets.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/scripts/prepare_l1000.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/settings.json +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/__init__.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/agent/__init__.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/agent/case_studies.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/agent/knowledge.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/agent/loop.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/agent/mcp_server.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/agent/orchestrator.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/agent/session.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/agent/system_prompt.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/agent/trace_store.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/agent/trajectory.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/agent/types.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/agent/workflows.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/api/__init__.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/api/app.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/api/config.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/api/engine.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/data/__init__.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/data/compute_providers.json +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/data/cro_database.json +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/data/downloader.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/data/loaders.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/kb/__init__.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/kb/benchmarks.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/kb/governance.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/kb/ingest.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/kb/reasoning.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/kb/schema_monitor.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/kb/substrate.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/models/__init__.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/__init__.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/_compound_resolver.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/biomarker.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/cellxgene.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/chemistry.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/claude.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/clinical.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/clue.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/code.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/combination.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/compute.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/cro.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/data_api.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/design.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/dna.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/experiment.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/expression.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/files.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/genomics.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/http_client.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/imaging.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/intel.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/literature.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/network.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/notification.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/omics.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/ops.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/parity.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/pk.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/protein.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/regulatory.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/remote_data.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/report.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/repurposing.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/safety.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/shell.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/singlecell.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/statistics.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/structure.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/target.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/translational.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/tools/viability.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/ui/__init__.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/ui/markdown.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/ui/status.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/ui/suggestions.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/ui/terminal.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/src/ct/ui/traces.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/__init__.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/conftest.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/fixtures/plan_snapshot.txt +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/fixtures/trace_snapshot.txt +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_api_smoke.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_cellxgene.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_chemistry_new.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_claude.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_cli.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_clue.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_code.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_compute.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_cro.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_data_api.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_data_api_service.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_design.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_dna.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_doctor.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_downloader.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_engine.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_experiment.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_files.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_future_backends_todo.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_html_report.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_http_client.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_imaging.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_kb_benchmarks.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_kb_governance.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_kb_ingest.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_kb_reasoning.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_kb_schema_monitor.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_kb_substrate.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_knowledge.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_llm.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_mention_completer.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_network.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_notebook.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_notification.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_omics.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_ops.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_parity_tools.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_parkinsons_toolchain_smoke.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_patent_search.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_plan_display.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_protein.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_registry.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_remote_data.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_repurposing.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_sandbox.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_sdk_streaming.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_session.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_shell.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_singlecell.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_status.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_structure.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_target.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_terminal.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_terminal_integration.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_tools.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_trace_store.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_traces.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_trajectory.py +0 -0
- {celltype_cli-0.1.2 → celltype_cli-0.1.3}/tests/test_workflows.py +0 -0
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: celltype-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: CellType CLI — An autonomous agent for drug discovery research
|
|
5
5
|
Author: CellType Inc.
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
License-File: LICENSE
|
|
8
8
|
Requires-Python: >=3.10
|
|
9
|
-
Requires-Dist: anthropic>=0.
|
|
9
|
+
Requires-Dist: anthropic>=0.74.0
|
|
10
10
|
Requires-Dist: claude-agent-sdk>=0.1
|
|
11
11
|
Requires-Dist: httpx>=0.27
|
|
12
12
|
Requires-Dist: markdown>=3.5
|
|
13
|
+
Requires-Dist: matplotlib>=3.7
|
|
13
14
|
Requires-Dist: nbformat>=5.7
|
|
14
15
|
Requires-Dist: numpy>=1.24
|
|
15
16
|
Requires-Dist: openai>=1.0
|
|
@@ -71,7 +72,7 @@ Ask questions in natural language. celltype-cli plans the analysis, selects the
|
|
|
71
72
|
|
|
72
73
|
## Benchmark
|
|
73
74
|
|
|
74
|
-
CellType CLI achieves **90% accuracy** on [BixBench-Verified-50](https://
|
|
75
|
+
CellType CLI achieves **90% accuracy** on [BixBench-Verified-50](https://huggingface.co/datasets/phylobio/BixBench-Verified-50), outperforming all existing agentic systems for computational biology.
|
|
75
76
|
|
|
76
77
|

|
|
77
78
|
|
|
@@ -8,7 +8,7 @@ Ask questions in natural language. celltype-cli plans the analysis, selects the
|
|
|
8
8
|
|
|
9
9
|
## Benchmark
|
|
10
10
|
|
|
11
|
-
CellType CLI achieves **90% accuracy** on [BixBench-Verified-50](https://
|
|
11
|
+
CellType CLI achieves **90% accuracy** on [BixBench-Verified-50](https://huggingface.co/datasets/phylobio/BixBench-Verified-50), outperforming all existing agentic systems for computational biology.
|
|
12
12
|
|
|
13
13
|

|
|
14
14
|
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
set -euo pipefail
|
|
5
5
|
|
|
6
6
|
PACKAGE="celltype-cli"
|
|
7
|
+
REPO_URL="git+https://github.com/celltype/cli.git"
|
|
7
8
|
MIN_PYTHON="3.10"
|
|
8
9
|
|
|
9
10
|
# ── Helpers ────────────────────────────────────────────────────
|
|
@@ -45,17 +46,19 @@ esac
|
|
|
45
46
|
|
|
46
47
|
# ── Install package ────────────────────────────────────────────
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
ok "Installed with pipx"
|
|
52
|
-
elif command -v uv >/dev/null 2>&1; then
|
|
49
|
+
INSTALL_SPEC="${PACKAGE} @ ${REPO_URL}"
|
|
50
|
+
|
|
51
|
+
if command -v uv >/dev/null 2>&1; then
|
|
53
52
|
info "Installing ${PACKAGE} via uv..."
|
|
54
|
-
uv tool install "$
|
|
53
|
+
uv tool install "$INSTALL_SPEC" || uv tool install --force "$INSTALL_SPEC"
|
|
55
54
|
ok "Installed with uv"
|
|
55
|
+
elif command -v pipx >/dev/null 2>&1; then
|
|
56
|
+
info "Installing ${PACKAGE} via pipx..."
|
|
57
|
+
pipx install "$REPO_URL" || pipx install --force "$REPO_URL"
|
|
58
|
+
ok "Installed with pipx"
|
|
56
59
|
else
|
|
57
|
-
warn "pipx
|
|
58
|
-
"$PYTHON" -m pip install --user --upgrade "$
|
|
60
|
+
warn "uv/pipx not found — falling back to pip install --user"
|
|
61
|
+
"$PYTHON" -m pip install --user --upgrade "$INSTALL_SPEC"
|
|
59
62
|
ok "Installed with pip"
|
|
60
63
|
|
|
61
64
|
# Check if user bin is on PATH
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "celltype-cli"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.3"
|
|
8
8
|
description = "CellType CLI — An autonomous agent for drug discovery research"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -17,13 +17,14 @@ dependencies = [
|
|
|
17
17
|
"typer>=0.12",
|
|
18
18
|
"rich>=13.0",
|
|
19
19
|
"prompt-toolkit>=3.0",
|
|
20
|
-
"anthropic>=0.
|
|
20
|
+
"anthropic>=0.74.0",
|
|
21
21
|
"openai>=1.0",
|
|
22
22
|
"claude-agent-sdk>=0.1",
|
|
23
23
|
"httpx>=0.27",
|
|
24
24
|
"pandas>=2.0",
|
|
25
25
|
"numpy>=1.24",
|
|
26
26
|
"scipy>=1.10",
|
|
27
|
+
"matplotlib>=3.7",
|
|
27
28
|
"python-dotenv>=1.0",
|
|
28
29
|
"markdown>=3.5",
|
|
29
30
|
"nbformat>=5.7",
|
|
@@ -456,6 +456,13 @@ class Config:
|
|
|
456
456
|
if self.llm_api_key(provider):
|
|
457
457
|
return None
|
|
458
458
|
|
|
459
|
+
# Azure AI Foundry: Foundry-specific env vars are valid Anthropic auth
|
|
460
|
+
if provider == "anthropic" and (
|
|
461
|
+
os.environ.get("ANTHROPIC_FOUNDRY_API_KEY")
|
|
462
|
+
or os.environ.get("ANTHROPIC_FOUNDRY_RESOURCE")
|
|
463
|
+
):
|
|
464
|
+
return None
|
|
465
|
+
|
|
459
466
|
if provider == "openai":
|
|
460
467
|
return (
|
|
461
468
|
"OpenAI API key not configured. Set OPENAI_API_KEY or run:\n"
|
|
@@ -464,7 +471,9 @@ class Config:
|
|
|
464
471
|
|
|
465
472
|
return (
|
|
466
473
|
"Anthropic API key not configured. Set ANTHROPIC_API_KEY or run:\n"
|
|
467
|
-
" ct config set llm.api_key <key
|
|
474
|
+
" ct config set llm.api_key <key>\n"
|
|
475
|
+
"For Azure AI Foundry: set ANTHROPIC_FOUNDRY_API_KEY and "
|
|
476
|
+
"ANTHROPIC_FOUNDRY_RESOURCE"
|
|
468
477
|
)
|
|
469
478
|
|
|
470
479
|
def keys_table(self) -> Table:
|
|
@@ -6,6 +6,7 @@ Used by `ct doctor` and interactive `/doctor` to surface actionable setup issues
|
|
|
6
6
|
|
|
7
7
|
from dataclasses import dataclass
|
|
8
8
|
import logging
|
|
9
|
+
import os
|
|
9
10
|
from pathlib import Path
|
|
10
11
|
|
|
11
12
|
from rich.table import Table
|
|
@@ -67,12 +68,12 @@ def run_checks(config: Config | None = None, session=None) -> list[DoctorCheck]:
|
|
|
67
68
|
if llm_issue:
|
|
68
69
|
checks.append(DoctorCheck(name="llm", status="error", detail=llm_issue))
|
|
69
70
|
else:
|
|
71
|
+
if os.environ.get("ANTHROPIC_FOUNDRY_API_KEY") or os.environ.get("ANTHROPIC_FOUNDRY_RESOURCE"):
|
|
72
|
+
detail = f"provider=anthropic (Azure Foundry), model={model}"
|
|
73
|
+
else:
|
|
74
|
+
detail = f"provider={provider}, model={model}"
|
|
70
75
|
checks.append(
|
|
71
|
-
DoctorCheck(
|
|
72
|
-
name="llm",
|
|
73
|
-
status="ok",
|
|
74
|
-
detail=f"provider={provider}, model={model}",
|
|
75
|
-
)
|
|
76
|
+
DoctorCheck(name="llm", status="ok", detail=detail)
|
|
76
77
|
)
|
|
77
78
|
|
|
78
79
|
# 3) Output directory availability
|
|
@@ -357,6 +357,24 @@ class AgentRunner:
|
|
|
357
357
|
# Suppress warnings in SDK subprocess (matplotlib, pydeseq2, numpy, etc.)
|
|
358
358
|
clean_env["PYTHONWARNINGS"] = "ignore"
|
|
359
359
|
|
|
360
|
+
# Enable Foundry mode for Agent SDK subprocess if Foundry env vars present
|
|
361
|
+
if any(clean_env.get(v) for v in (
|
|
362
|
+
"ANTHROPIC_FOUNDRY_API_KEY",
|
|
363
|
+
"ANTHROPIC_FOUNDRY_RESOURCE",
|
|
364
|
+
"ANTHROPIC_FOUNDRY_BASE_URL",
|
|
365
|
+
)):
|
|
366
|
+
clean_env["CLAUDE_CODE_USE_FOUNDRY"] = "1"
|
|
367
|
+
# Pin model names for Foundry deployments
|
|
368
|
+
clean_env.setdefault(
|
|
369
|
+
"ANTHROPIC_DEFAULT_SONNET_MODEL", model
|
|
370
|
+
)
|
|
371
|
+
clean_env.setdefault(
|
|
372
|
+
"ANTHROPIC_DEFAULT_OPUS_MODEL", model
|
|
373
|
+
)
|
|
374
|
+
clean_env.setdefault(
|
|
375
|
+
"ANTHROPIC_DEFAULT_HAIKU_MODEL", model
|
|
376
|
+
)
|
|
377
|
+
|
|
360
378
|
# Plan mode: use SDK's built-in plan permission mode.
|
|
361
379
|
# In plan mode, Claude outputs a plan then calls ExitPlanMode.
|
|
362
380
|
# We intercept that to show the plan and ask for approval.
|
|
@@ -20,8 +20,11 @@ warnings.filterwarnings("ignore", message="Unable to import Axes3D")
|
|
|
20
20
|
warnings.filterwarnings("ignore", category=UserWarning, module="matplotlib")
|
|
21
21
|
|
|
22
22
|
# Force non-interactive matplotlib backend before any import
|
|
23
|
-
|
|
24
|
-
matplotlib
|
|
23
|
+
try:
|
|
24
|
+
import matplotlib
|
|
25
|
+
matplotlib.use("Agg")
|
|
26
|
+
except ImportError:
|
|
27
|
+
pass # matplotlib is a required dep; deferred error in _setup_namespace()
|
|
25
28
|
|
|
26
29
|
|
|
27
30
|
# Modules blocked from import inside the sandbox
|
|
@@ -128,6 +128,13 @@ def setup_cmd(
|
|
|
128
128
|
|
|
129
129
|
cfg = Config.load()
|
|
130
130
|
|
|
131
|
+
# Azure AI Foundry: skip interactive key prompt when Foundry is configured
|
|
132
|
+
if os.environ.get("ANTHROPIC_FOUNDRY_API_KEY") or os.environ.get("ANTHROPIC_FOUNDRY_RESOURCE"):
|
|
133
|
+
console.print("\n [green]Azure AI Foundry detected. No API key needed.[/green]")
|
|
134
|
+
cfg.set("llm.provider", "anthropic")
|
|
135
|
+
cfg.save()
|
|
136
|
+
return
|
|
137
|
+
|
|
131
138
|
console.print()
|
|
132
139
|
console.print(
|
|
133
140
|
Panel(
|
|
@@ -120,9 +120,12 @@ class LLMClient:
|
|
|
120
120
|
|
|
121
121
|
if self.provider == "anthropic":
|
|
122
122
|
import anthropic
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
123
|
+
if os.environ.get("ANTHROPIC_FOUNDRY_API_KEY") or os.environ.get("ANTHROPIC_FOUNDRY_RESOURCE"):
|
|
124
|
+
self._client = anthropic.AnthropicFoundry()
|
|
125
|
+
else:
|
|
126
|
+
self._client = anthropic.Anthropic(
|
|
127
|
+
api_key=self.api_key or os.environ.get("ANTHROPIC_API_KEY")
|
|
128
|
+
)
|
|
126
129
|
|
|
127
130
|
elif self.provider == "openai":
|
|
128
131
|
import openai
|
|
@@ -21,13 +21,33 @@ def test_load_invalid_json_does_not_crash(monkeypatch, tmp_path):
|
|
|
21
21
|
assert cfg.get("llm.provider") == "anthropic"
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
def test_llm_preflight_requires_anthropic_key():
|
|
24
|
+
def test_llm_preflight_requires_anthropic_key(monkeypatch):
|
|
25
|
+
monkeypatch.delenv("ANTHROPIC_API_KEY", raising=False)
|
|
26
|
+
monkeypatch.delenv("ANTHROPIC_FOUNDRY_API_KEY", raising=False)
|
|
27
|
+
monkeypatch.delenv("ANTHROPIC_FOUNDRY_RESOURCE", raising=False)
|
|
25
28
|
cfg = Config(data={"llm.provider": "anthropic"})
|
|
26
29
|
issue = cfg.llm_preflight_issue()
|
|
27
30
|
assert issue is not None
|
|
28
31
|
assert "Anthropic API key" in issue
|
|
29
32
|
|
|
30
33
|
|
|
34
|
+
def test_llm_preflight_accepts_foundry_env_vars(monkeypatch):
|
|
35
|
+
monkeypatch.delenv("ANTHROPIC_API_KEY", raising=False)
|
|
36
|
+
monkeypatch.setenv("ANTHROPIC_FOUNDRY_API_KEY", "test-key")
|
|
37
|
+
monkeypatch.setenv("ANTHROPIC_FOUNDRY_RESOURCE", "test-resource")
|
|
38
|
+
cfg = Config(data={"llm.provider": "anthropic"})
|
|
39
|
+
assert cfg.llm_preflight_issue() is None
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_llm_preflight_error_mentions_foundry(monkeypatch):
|
|
43
|
+
monkeypatch.delenv("ANTHROPIC_API_KEY", raising=False)
|
|
44
|
+
monkeypatch.delenv("ANTHROPIC_FOUNDRY_API_KEY", raising=False)
|
|
45
|
+
monkeypatch.delenv("ANTHROPIC_FOUNDRY_RESOURCE", raising=False)
|
|
46
|
+
cfg = Config(data={"llm.provider": "anthropic"})
|
|
47
|
+
issue = cfg.llm_preflight_issue()
|
|
48
|
+
assert "Foundry" in issue
|
|
49
|
+
|
|
50
|
+
|
|
31
51
|
def test_llm_preflight_requires_openai_key():
|
|
32
52
|
cfg = Config(data={"llm.provider": "openai"})
|
|
33
53
|
issue = cfg.llm_preflight_issue()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{celltype_cli-0.1.2 → celltype_cli-0.1.3}/.claude/skills/openspec-bulk-archive-change/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|