File size: 6,149 Bytes
016b413
97d41ab
016b413
816af43
016b413
 
 
 
 
 
 
 
 
 
 
 
85f2fd9
016b413
 
 
 
 
92c8b3f
016b413
 
 
 
e568430
 
 
 
85f2fd9
e568430
85f2fd9
 
 
 
 
 
 
 
 
97d41ab
816af43
 
92c8b3f
 
810b62c
e427816
016b413
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11b3e28
 
 
 
 
5a8f820
c7402fb
11b3e28
d9162ac
016b413
 
 
 
 
 
 
 
 
 
 
e568430
016b413
85f2fd9
 
016b413
 
85f2fd9
016b413
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8fa2ce6
016b413
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8fa2ce6
016b413
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d9162ac
 
 
 
c7402fb
d9162ac
016b413
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
[project]
name = "determinator"
version = "0.1.0"
description = "The DETERMINATOR - the Deep Research Agent that Stops at Nothing"
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
    "pydantic>=2.7",
    "pydantic-settings>=2.2", # For BaseSettings (config)
    "pydantic-ai>=0.0.16", # Agent framework
    "openai>=1.0.0",
    "anthropic>=0.18.0",
    "httpx>=0.27", # Async HTTP client (PubMed)
    "beautifulsoup4>=4.12", # HTML parsing
    "xmltodict>=0.13", # PubMed XML -> dict
    "huggingface-hub>=0.20.0", # Hugging Face Inference API
    "gradio[mcp,oauth]>=6.0.0", # Chat interface with MCP server support (6.0 required for css in launch())
    "python-dotenv>=1.0", # .env loading
    "tenacity>=8.2", # Retry logic
    "structlog>=24.1", # Structured logging
    "requests>=2.32.5", # ClinicalTrials.gov (httpx blocked by WAF)
    "pydantic-graph>=1.22.0",
    "limits>=3.0", # Web search
    "llama-index-llms-huggingface>=0.6.1",
    "llama-index-llms-huggingface-api>=0.6.1",
    "llama-index-vector-stores-chroma>=0.5.3",
    "llama-index>=0.14.8",
    "gradio-client>=1.0.0", # For STT/OCR API calls
    "soundfile>=0.12.0", # For audio file I/O
    "pillow>=10.0.0", # For image processing
    "torch>=2.0.0", # Required by Kokoro TTS
    "transformers>=4.57.2", # Required by Kokoro TTS
    "modal>=0.63.0", # Required for TTS GPU execution
    "tokenizers>=0.22.0,<=0.23.0",
    "rpds-py>=0.29.0",
    "pydantic-ai-slim[huggingface]>=0.0.18",
    "agent-framework-core>=1.0.0b251120,<2.0.0",
    "chromadb>=0.4.0",
    "sentence-transformers>=2.2.0",
    "numpy<2.0",
    "llama-index-llms-openai>=0.6.9",
    "llama-index-embeddings-openai>=0.5.1",
    "ddgs>=9.9.2",
    "aiohttp>=3.13.2",
    "lxml>=6.0.2",
    "fake-useragent==2.2.0",
    "socksio==1.0.0",
    "neo4j>=6.0.3",
    "md2pdf>=1.0.1",
]

[project.optional-dependencies]
dev = [
    # Testing
    "pytest>=8.0",
    "pytest-asyncio>=0.23",
    "pytest-sugar>=1.0",
    "pytest-cov>=5.0",
    "pytest-mock>=3.12",
    "respx>=0.21",                   # Mock httpx requests
    "typer>=0.9.0",                  # Gradio CLI dependency for smoke tests

    # Quality
    "ruff>=0.4.0",
    "mypy>=1.10",
    "pre-commit>=3.7",
    
    # Documentation
    "mkdocs>=1.6.0",
    "mkdocs-material>=9.0.0",
    "mkdocs-mermaid2-plugin>=1.1.0",
    "mkdocs-codeinclude-plugin>=0.2.0",
    "mkdocs-git-revision-date-localized-plugin>=1.2.0",
    "mkdocs-minify-plugin>=0.8.0",
    "pymdown-extensions>=10.17.2",
]
magentic = [
    "agent-framework-core>=1.0.0b251120,<2.0.0",  # Microsoft Agent Framework (PyPI)
]
embeddings = [
    "chromadb>=0.4.0",
    "sentence-transformers>=2.2.0",
    "numpy<2.0",  # chromadb compatibility: uses np.float_ removed in NumPy 2.0
]
modal = [
    # Mario's Modal code execution + LlamaIndex RAG
    # Note: modal>=0.63.0 is now in main dependencies for TTS support
    "llama-index>=0.11.0",
    "llama-index-llms-openai>=0.6.9",
    "llama-index-embeddings-openai>=0.5.1",
    "llama-index-vector-stores-chroma",
    "chromadb>=0.4.0",
    "numpy<2.0", # chromadb compatibility: uses np.float_ removed in NumPy 2.0
]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["src"]

# ============== RUFF CONFIG ==============
[tool.ruff]
line-length = 100
target-version = "py311"
src = ["src"]
exclude = [
    "tests/",
    "examples/",
    "reference_repos/",
    "folder/",
]

[tool.ruff.lint]
select = [
    "E",    # pycodestyle errors
    "F",    # pyflakes
    "B",    # flake8-bugbear
    "I",    # isort
    "N",    # pep8-naming
    "UP",   # pyupgrade
    "PL",   # pylint
    "RUF",  # ruff-specific
]
ignore = [
    "PLR0913",  # Too many arguments (agents need many params)
    "PLR0912",  # Too many branches (complex orchestrator logic)
    "PLR0911",  # Too many return statements (complex agent logic)
    "PLR0915",  # Too many statements (Gradio UI setup functions)
    "PLR2004",  # Magic values (statistical constants like p-values)
    "PLW0603",  # Global statement (singleton pattern for Modal)
    "PLC0415",  # Lazy imports for optional dependencies
    "E402",     # Module level import not at top (needed for pytest.importorskip)
    "E501",     # Line too long (ignore line length violations)
    "RUF100",   # Unused noqa (version differences between local/CI)
]

[tool.ruff.lint.isort]
known-first-party = ["src"]

# ============== MYPY CONFIG ==============
[tool.mypy]
python_version = "3.11"
strict = true
ignore_missing_imports = true
disallow_untyped_defs = true
warn_return_any = true
warn_unused_ignores = false
explicit_package_bases = true
mypy_path = "."
exclude = [
    "^reference_repos/",
    "^examples/",
    "^folder/",
    "^src/app.py",
]

# ============== PYTEST CONFIG ==============
[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
addopts = [
    "-v",
    "--tb=short",
    "--strict-markers",
    "-p",
    "no:logfire",
]
markers = [
    "unit: Unit tests (mocked)",
    "integration: Integration tests (real APIs)",
    "slow: Slow tests",
    "openai: Tests that require OpenAI API key",
    "huggingface: Tests that require HuggingFace API key or use HuggingFace models",
    "embedding_provider: Tests that require API-based embedding providers (OpenAI, etc.)",
    "local_embeddings: Tests that use local embeddings (sentence-transformers, ChromaDB)",
]

# ============== COVERAGE CONFIG ==============
[tool.coverage.run]
source = ["src"]
omit = ["*/__init__.py"]

[tool.coverage.report]
exclude_lines = [
    "pragma: no cover",
    "if TYPE_CHECKING:",
    "raise NotImplementedError",
]

[dependency-groups]
dev = [
    "mkdocs>=1.6.1",
    "mkdocs-codeinclude-plugin>=0.2.1",
    "mkdocs-material>=9.7.0",
    "mkdocs-mermaid2-plugin>=1.2.3",
    "mkdocs-git-revision-date-localized-plugin>=1.2.0",
    "mkdocs-minify-plugin>=0.8.0",
    "structlog>=25.5.0",
    "ty>=0.0.1a28",
]

# Note: agent-framework-core is optional for magentic mode (multi-agent orchestration)
# Version pinned to 1.0.0b* to avoid breaking changes. CI skips tests via pytest.importorskip