Merge pull request #243 from ggozad/chore/ty

replace pyright with ty type checker
This commit is contained in:
Yiorgis Gozadinos 2026-01-19 16:32:34 +02:00 committed by GitHub
commit e32b48d142
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 214 additions and 170 deletions

View file

@ -23,7 +23,7 @@ jobs:
- name: Lint
run: uv run ruff check
- name: Type check
run: uv run pyright
run: uv run ty check
lint-frontend:
runs-on: ubuntu-latest

View file

@ -16,10 +16,14 @@ repos:
# Run the formatter.
- id: ruff-format
- repo: https://github.com/RobertCraigie/pyright-python
rev: v1.1.407
- repo: local
hooks:
- id: pyright
- id: ty
name: ty check
entry: uvx ty check
language: system
types: [python]
pass_filenames: false
- repo: local
hooks:

View file

@ -1,6 +1,20 @@
# Changelog
## [Unreleased]
### Changed
- **Type Checker**: Replaced pyright with [ty](https://github.com/astral-sh/ty), Astral's extremely fast Python type checker
- Added explicit `Agent[Deps, Output]` type annotations to all pydantic-ai agents for better type inference
- Removed ~24 unnecessary `# type: ignore` comments that ty correctly infers
- **Dependencies**: Updated to latest versions
- `pydantic-ai-slim`: 1.39.0 → 1.44.0
- `docling`: 2.67.0 → 2.68.0
- `pathspec`: 0.12.1 → 1.0.3
- `textual`: 7.0.0 → 7.3.0
- `datasets`: 4.4.2 → 4.5.0
- `ruff`: 0.14.11 → 0.14.13
- `opencv-python-headless`: 4.12.0.88 → 4.13.0.90
## [0.26.6] - 2026-01-19
### Changed

View file

@ -226,7 +226,7 @@ app = Starlette(
],
middleware=[
Middleware(
CORSMiddleware,
CORSMiddleware, # type: ignore[invalid-argument-type]
allow_origins=["http://localhost:3000", "http://frontend:3000"],
allow_credentials=True,
allow_methods=["*"],

View file

@ -1,7 +1,7 @@
from collections.abc import Mapping
from typing import Any, cast
from datasets import Dataset, DatasetDict, load_dataset
from datasets import Dataset, load_dataset
from pydantic_evals import Case
from evaluations.config import DatasetSpec, DocumentPayload, RetrievalSample
@ -9,8 +9,8 @@ from evaluations.evaluators import MAPEvaluator
def load_hotpotqa_validation() -> Dataset:
dataset_dict = cast(DatasetDict, load_dataset("hotpotqa/hotpot_qa", "distractor"))
return cast(Dataset, dataset_dict["validation"])
dataset_dict = load_dataset("hotpotqa/hotpot_qa", "distractor")
return dataset_dict["validation"]
def extract_unique_documents(dataset: Dataset) -> list[dict[str, Any]]:

View file

@ -1,7 +1,7 @@
from collections.abc import Mapping
from typing import Any, cast
from typing import Any
from datasets import Dataset, DatasetDict, load_dataset
from datasets import Dataset, load_dataset
from pydantic_evals import Case
from evaluations.config import DatasetSpec, DocumentPayload, RetrievalSample
@ -9,8 +9,8 @@ from evaluations.evaluators import MRREvaluator
def load_repliqa_corpus() -> Dataset:
dataset_dict = cast(DatasetDict, load_dataset("ServiceNow/repliqa"))
dataset = cast(Dataset, dataset_dict["repliqa_3"])
dataset_dict = load_dataset("ServiceNow/repliqa")
dataset = dataset_dict["repliqa_3"]
return dataset.filter(lambda doc: doc["document_topic"] == "News Stories")

View file

@ -1,8 +1,8 @@
import json
from collections.abc import Iterable, Mapping
from typing import Any, cast
from typing import Any
from datasets import Dataset, DatasetDict, load_dataset
from datasets import Dataset, load_dataset
from pydantic_evals import Case
from evaluations.config import DatasetSpec, DocumentPayload, RetrievalSample
@ -10,8 +10,8 @@ from evaluations.evaluators import MAPEvaluator
def load_wix_corpus() -> Dataset:
dataset_dict = cast(DatasetDict, load_dataset("Wix/WixQA", "wix_kb_corpus"))
return cast(Dataset, dataset_dict["train"])
dataset_dict = load_dataset("Wix/WixQA", "wix_kb_corpus")
return dataset_dict["train"]
def map_wix_document(doc: Mapping[str, Any]) -> DocumentPayload:
@ -35,8 +35,8 @@ def map_wix_document(doc: Mapping[str, Any]) -> DocumentPayload:
def load_wix_qa() -> Dataset:
dataset_dict = cast(DatasetDict, load_dataset("Wix/WixQA", "wixqa_expertwritten"))
return cast(Dataset, dataset_dict["train"])
dataset_dict = load_dataset("Wix/WixQA", "wixqa_expertwritten")
return dataset_dict["train"]
def map_wix_retrieval(doc: Mapping[str, Any]) -> RetrievalSample | None:

View file

@ -40,7 +40,7 @@ class LLMJudge:
model_obj = get_model(model_config, config)
# Create Pydantic AI agent
self._agent = Agent(
self._agent: Agent[None, LLMJudgeResponseSchema] = Agent(
model=model_obj,
output_type=LLMJudgeResponseSchema,
system_prompt=ANSWER_EQUIVALENCE_RUBRIC,

View file

@ -9,8 +9,8 @@ requires-python = ">=3.12"
dependencies = [
"haiku.rag-slim",
"pydantic-ai-slim[evals,logfire]>=1.39.0",
"datasets>=4.4.2",
"pydantic-ai-slim[evals,logfire]>=1.44.0",
"datasets>=4.5.0",
"typer>=0.19.2,<0.20.0",
"python-dotenv>=1.2.1",
]

View file

@ -32,7 +32,7 @@ class QuestionAnswerAgent:
self._client = client
model_obj = get_model(model_config, config)
self._agent = Agent(
self._agent: Agent[Dependencies, RawSearchAnswer] = Agent(
model=model_obj,
deps_type=Dependencies,
output_type=ToolOutput(RawSearchAnswer, max_retries=3),
@ -75,5 +75,6 @@ class QuestionAnswerAgent:
"""
deps = Dependencies(client=self._client, search_filter=filter)
result = await self._agent.run(question, deps=deps)
citations = resolve_citations(result.output.cited_chunks, deps.search_results)
return result.output.answer, citations
output = result.output
citations = resolve_citations(output.cited_chunks, deps.search_results)
return output.answer, citations

View file

@ -105,7 +105,7 @@ async def _plan_step_logic(
else plan_prompt
)
plan_agent = Agent(
plan_agent: Agent[ResearchDependencies, ResearchPlan] = Agent(
model=get_model(model_config, config),
output_type=ResearchPlan,
instructions=effective_plan_prompt,
@ -151,7 +151,8 @@ async def _plan_step_logic(
agent_deps = ResearchDependencies(client=deps.client, context=state.context)
plan_result = await plan_agent.run(prompt, deps=agent_deps)
state.context.sub_questions = list(plan_result.output.sub_questions)
output = plan_result.output
state.context.sub_questions = list(output.sub_questions)
async def _search_one_step_logic(
@ -168,7 +169,7 @@ async def _search_one_step_logic(
deps.semaphore = asyncio.Semaphore(state.max_concurrency)
async with deps.semaphore:
agent = Agent(
agent: Agent[ResearchDependencies, RawSearchAnswer] = Agent(
model=get_model(model_config, config),
output_type=ToolOutput(RawSearchAnswer, max_retries=3),
instructions=search_prompt,
@ -289,7 +290,7 @@ def build_research_graph(
state = ctx.state
deps = ctx.deps
agent = Agent(
agent: Agent[ResearchDependencies, EvaluationResult] = Agent(
model=get_model(model_config, config),
output_type=EvaluationResult,
instructions=decision_prompt,
@ -350,7 +351,7 @@ def build_research_graph(
state = ctx.state
deps = ctx.deps
agent = Agent(
agent: Agent[ResearchDependencies, ResearchReport] = Agent(
model=get_model(model_config, config),
output_type=ResearchReport,
instructions=synthesis_prompt,
@ -488,7 +489,7 @@ def build_conversational_graph(
state = ctx.state
deps = ctx.deps
agent = Agent(
agent: Agent[ResearchDependencies, ConversationalAnswer] = Agent(
model=get_model(config.research.model, config),
output_type=ConversationalAnswer,
instructions=conversational_prompt,

View file

@ -494,7 +494,7 @@ class HaikuRAGApp:
# Confidence (from last evaluation)
if state.last_eval:
conf = state.last_eval.confidence_score # type: ignore[attr-defined]
conf = state.last_eval.confidence_score
self.console.print(f"[bold cyan]Confidence:[/bold cyan] {conf:.1%}")
self.console.print()

View file

@ -51,7 +51,7 @@ except ImportError:
App = object # type: ignore
class ChatApp(App): # type: ignore[misc]
class ChatApp(App):
"""Textual TUI for conversational RAG."""
TITLE = "haiku.rag Chat"

View file

@ -26,7 +26,7 @@ except ImportError:
App = object # type: ignore
class InspectorApp(App): # type: ignore[misc] # pragma: no cover
class InspectorApp(App): # pragma: no cover
"""Textual TUI for inspecting LanceDB data."""
TITLE = "haiku.rag DB Inspector"

View file

@ -4,7 +4,6 @@ from pathlib import Path
from typing import TYPE_CHECKING
import pathspec
from pathspec.patterns.gitwildmatch import GitWildMatchPattern
from watchfiles import Change, DefaultFilter, awatch
from haiku.rag.client import HaikuRAG
@ -37,12 +36,12 @@ class FileFilter(DefaultFilter):
self.extensions = tuple(supported_extensions)
self.ignore_spec = (
pathspec.PathSpec.from_lines(GitWildMatchPattern, ignore_patterns)
pathspec.PathSpec.from_lines("gitwildmatch", ignore_patterns)
if ignore_patterns
else None
)
self.include_spec = (
pathspec.PathSpec.from_lines(GitWildMatchPattern, include_patterns)
pathspec.PathSpec.from_lines("gitwildmatch", include_patterns)
if include_patterns
else None
)

View file

@ -258,7 +258,7 @@ class Store:
}
# Documents table stats
doc_stats: dict = self.documents_table.stats() # type: ignore[assignment]
doc_stats: dict = self.documents_table.stats()
stats_dict["documents"] = {
"exists": True,
"num_rows": doc_stats.get("num_rows", 0),
@ -266,7 +266,7 @@ class Store:
}
# Chunks table stats
chunk_stats: dict = self.chunks_table.stats() # type: ignore[assignment]
chunk_stats: dict = self.chunks_table.stats()
stats_dict["chunks"] = {
"exists": True,
"num_rows": chunk_stats.get("num_rows", 0),

View file

@ -177,6 +177,10 @@ def get_model(
return OpenAIChatModel(model_name=model, settings=openai_settings)
elif provider == "anthropic":
from anthropic.types.beta import (
BetaThinkingConfigDisabledParam,
BetaThinkingConfigEnabledParam,
)
from pydantic_ai.models.anthropic import AnthropicModel, AnthropicModelSettings
anthropic_settings: Any = None
@ -184,12 +188,19 @@ def get_model(
# Apply thinking control
if model_config.enable_thinking is not None:
if model_config.enable_thinking:
thinking_config: BetaThinkingConfigEnabledParam = {
"type": "enabled",
"budget_tokens": 4096,
}
anthropic_settings = AnthropicModelSettings(
anthropic_thinking={"type": "enabled", "budget_tokens": 4096}
anthropic_thinking=thinking_config
)
else:
thinking_disabled: BetaThinkingConfigDisabledParam = {
"type": "disabled"
}
anthropic_settings = AnthropicModelSettings(
anthropic_thinking={"type": "disabled"}
anthropic_thinking=thinking_disabled
)
anthropic_settings = apply_common_settings(

View file

@ -25,9 +25,9 @@ dependencies = [
"docling-core==2.59.0",
"httpx>=0.28.1",
"lancedb==0.26.1",
"pathspec>=0.12.1",
"pathspec>=1.0.3",
"pydantic>=2.12.5",
"pydantic-ai-slim[openai,fastmcp,logfire,ag-ui]>=1.39.0",
"pydantic-ai-slim[openai,fastmcp,logfire,ag-ui]>=1.44.0",
"python-dotenv>=1.2.1",
"pyyaml>=6.0.3",
"rich>=14.2.0",
@ -37,7 +37,7 @@ dependencies = [
[project.optional-dependencies]
# Document processing
docling = ["docling==2.67.0", "opencv-python-headless>=4.12.0.88"]
docling = ["docling==2.68.0", "opencv-python-headless>=4.13.0.90"]
# Embedding providers
voyageai = ["voyageai>=0.3.7"]
# Rerankers
@ -45,7 +45,7 @@ mxbai = ["mxbai-rerank>=0.1.6"]
cohere = ["cohere>=5.20.1"]
zeroentropy = ["zeroentropy>=0.1.0a7"]
# TUI (chat and inspect commands)
tui = ["textual>=7.0.0", "textual-image>=0.8.5"]
tui = ["textual>=7.3.0", "textual-image>=0.8.5"]
# Model providers (delegated to pydantic-ai-slim)
anthropic = ["pydantic-ai-slim[anthropic]"]
groq = ["pydantic-ai-slim[groq]"]

View file

@ -67,7 +67,7 @@ members = ["haiku_rag_slim", "evaluations"]
[dependency-groups]
dev = [
"haiku.rag-evals",
"datasets>=4.4.2",
"datasets>=4.5.0",
"mkdocs>=1.6.1",
"mkdocs-material>=9.7.1",
"pre-commit>=4.5.1",
@ -75,12 +75,12 @@ dev = [
"pydantic-ai-slim[bedrock]",
"pydantic-ai-slim[google]",
"pydantic-ai-slim[groq]",
"pyright>=1.1.408",
"ty>=0.0.12",
"pytest>=9.0.2",
"pytest-asyncio>=1.3.0",
"pytest-cov>=7.0.0",
"pytest-recording>=0.13.4",
"ruff>=0.14.11",
"ruff>=0.14.13",
]
[tool.ruff]
@ -110,10 +110,12 @@ indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"
[tool.pyright]
venvPath = "."
venv = ".venv"
pythonVersion = "3.12"
[tool.ty.src]
exclude = ["examples/**"]
[tool.ty.environment]
python-version = "3.12"
python = ".venv"
[tool.pytest.ini_options]
asyncio_default_fixture_loop_scope = "session"

View file

@ -81,9 +81,10 @@ def test_chat_agent_has_dynamic_system_prompt():
agent = create_chat_agent(Config)
# The agent should have at least one system prompt function registered
# (the add_background_context function)
assert len(agent._system_prompt_functions) >= 1
system_prompt_functions = getattr(agent, "_system_prompt_functions")
assert len(system_prompt_functions) >= 1
# Verify it's the add_background_context function
func_names = [r.function.__name__ for r in agent._system_prompt_functions]
func_names = [r.function.__name__ for r in system_prompt_functions]
assert "add_background_context" in func_names

View file

@ -2,7 +2,7 @@ import logging
import os
import tempfile
from pathlib import Path
from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING, Any, cast
# Prevent tests from loading user's local haiku.rag.yaml by setting env var
# to a test config file BEFORE any haiku.rag imports.
@ -26,7 +26,7 @@ from datasets import Dataset, load_dataset, load_from_disk # noqa: E402
if TYPE_CHECKING:
from vcr import VCR
pydantic_ai.models.ALLOW_MODEL_REQUESTS = False
setattr(pydantic_ai.models, "ALLOW_MODEL_REQUESTS", False)
logging.getLogger("vcr.cassette").setLevel(logging.WARNING)
@ -35,10 +35,9 @@ def qa_corpus() -> Dataset:
ds_path = Path(__file__).parent / "data" / "dataset"
ds_path.mkdir(parents=True, exist_ok=True)
try:
ds: Dataset = load_from_disk(ds_path) # type: ignore
return ds
return cast(Dataset, load_from_disk(ds_path))
except FileNotFoundError:
ds: Dataset = load_dataset("ServiceNow/repliqa")["repliqa_3"] # type: ignore
ds: Dataset = load_dataset("ServiceNow/repliqa")["repliqa_3"]
corpus = ds.filter(lambda doc: doc["document_topic"] == "News Stories")
corpus.save_to_disk(ds_path)
return corpus

View file

@ -58,7 +58,7 @@ async def test_client_document_crud(qa_corpus: Dataset, temp_db_path):
# Test update_document
updated_doc = await client.update_document(
document_id=retrieved_doc.id, # type: ignore[arg-type]
document_id=retrieved_doc.id,
content="Updated content",
)
assert updated_doc.content == "Updated content"

View file

@ -30,8 +30,7 @@ async def test_mcp_add_document_from_file():
t for t in tools.values() if t.name == "add_document_from_file"
)
result = await add_file_tool.fn(file_path="/test.txt") # type: ignore[attr-defined]
result = await add_file_tool.fn(file_path="/test.txt")
assert result == "doc123"
mock_rag.create_document_from_source.assert_called_once()
@ -52,9 +51,7 @@ async def test_mcp_ask_question():
tools = await mcp.get_tools()
ask_tool = next(t for t in tools.values() if t.name == "ask_question")
result = await ask_tool.fn( # type: ignore[attr-defined]
question="What is this?", cite=False, deep=False
)
result = await ask_tool.fn(question="What is this?", cite=False, deep=False)
assert result == "This is the answer"
mock_rag.ask.assert_called_once_with("What is this?")
@ -81,8 +78,7 @@ async def test_mcp_add_document_from_url():
t for t in tools.values() if t.name == "add_document_from_url"
)
result = await add_url_tool.fn(url="https://example.com") # type: ignore[attr-defined]
result = await add_url_tool.fn(url="https://example.com")
assert result == "doc456"
mock_rag.create_document_from_source.assert_called_once()
@ -108,9 +104,7 @@ async def test_mcp_add_document_from_text():
t for t in tools.values() if t.name == "add_document_from_text"
)
result = await add_text_tool.fn( # type: ignore[attr-defined]
content="test content", uri="text://test"
)
result = await add_text_tool.fn(content="test content", uri="text://test")
assert result == "doc789"
mock_rag.create_document.assert_called_once()
@ -141,8 +135,7 @@ async def test_mcp_search_documents():
t for t in tools.values() if t.name == "search_documents"
)
result = await search_tool.fn(query="test query", limit=5) # type: ignore[attr-defined]
result = await search_tool.fn(query="test query", limit=5)
assert len(result) == 2
assert result[0].document_id == "doc1"
assert result[0].content == "Result 1"
@ -174,8 +167,7 @@ async def test_mcp_get_document():
tools = await mcp.get_tools()
get_tool = next(t for t in tools.values() if t.name == "get_document")
result = await get_tool.fn(document_id="doc123") # type: ignore[attr-defined]
result = await get_tool.fn(document_id="doc123")
assert result is not None
assert result.id == "doc123"
assert result.content == "test"
@ -211,8 +203,7 @@ async def test_mcp_list_documents():
tools = await mcp.get_tools()
list_tool = next(t for t in tools.values() if t.name == "list_documents")
result = await list_tool.fn(limit=10, offset=0) # type: ignore[attr-defined]
result = await list_tool.fn(limit=10, offset=0)
assert len(result) == 2
assert result[0].id == "doc1"
assert result[1].id == "doc2"
@ -235,8 +226,7 @@ async def test_mcp_delete_document():
tools = await mcp.get_tools()
delete_tool = next(t for t in tools.values() if t.name == "delete_document")
result = await delete_tool.fn(document_id="doc123") # type: ignore[attr-defined]
result = await delete_tool.fn(document_id="doc123")
assert result is True
mock_rag.delete_document.assert_called_once_with("doc123")
@ -268,9 +258,7 @@ async def test_mcp_ask_question_deep():
ask_tool = next(t for t in tools.values() if t.name == "ask_question")
# cite=False to avoid citation formatting in output
result = await ask_tool.fn( # type: ignore[attr-defined]
question="Deep question?", cite=False, deep=True
)
result = await ask_tool.fn(question="Deep question?", cite=False, deep=True)
assert result == "Deep answer from research"
mock_graph.run.assert_called_once()
@ -311,7 +299,7 @@ async def test_mcp_research_question():
t for t in tools.values() if t.name == "research_question"
)
result = await research_tool.fn( # type: ignore[attr-defined]
result = await research_tool.fn(
question="Research question?",
)

View file

@ -1,9 +1,20 @@
from typing import TypedDict
import pytest
from datasets import Dataset
from haiku.rag.client import HaikuRAG, RebuildMode
class ChunkData(TypedDict):
id: str
document_id: str
content: str
content_fts: str
metadata: str
order: int
@pytest.mark.vcr()
async def test_rebuild_full(qa_corpus: Dataset, temp_db_path):
"""Test full rebuild: converts, chunks, and embeds all documents."""
@ -132,15 +143,15 @@ async def test_rebuild_embed_only_with_changed_vector_dim(
chunks_before = await client.chunk_repository.get_by_document_id(doc.id)
assert len(chunks_before) > 0
chunk_data = [
{
"id": c.id,
"document_id": c.document_id,
"content": c.content,
"content_fts": c.content,
"metadata": json.dumps(c.metadata),
"order": c.order,
}
chunk_data: list[ChunkData] = [
ChunkData(
id=c.id or "",
document_id=c.document_id or "",
content=c.content,
content_fts=c.content,
metadata=json.dumps(c.metadata),
order=c.order,
)
for c in chunks_before
]

View file

@ -19,8 +19,8 @@ async def test_search_qa_corpus(qa_corpus: Dataset, temp_db_path):
for doc_data in qa_corpus:
if len(seen_documents) >= 10:
break
document_text = doc_data["document_extracted"] # type: ignore
document_id = doc_data.get("document_id", "") # type: ignore
document_text = doc_data["document_extracted"]
document_id = doc_data.get("document_id", "")
if document_id in seen_documents:
continue

View file

@ -14,7 +14,7 @@ async def test_version_rollback_on_create_failure(temp_db_path):
await orig_create(chunks)
raise RuntimeError("boom")
client.chunk_repository.create = succeed_then_fail # type: ignore[method-assign]
client.chunk_repository.create = succeed_then_fail
# Attempt to create document; expect failure and rollback
content = "Hello, rollback!"
@ -43,20 +43,20 @@ async def test_version_rollback_on_update_failure(temp_db_path):
await orig_create(chunks)
raise RuntimeError("update fail")
client.chunk_repository.create = succeed_then_fail # type: ignore[method-assign]
client.chunk_repository.create = succeed_then_fail
# Attempt update
with pytest.raises(RuntimeError):
await client.update_document(
document_id=created.id, # type: ignore[arg-type]
document_id=created.id,
content="Updated content",
)
# Content and chunks should remain the original
persisted = await client.get_document_by_id(created.id) # type: ignore[arg-type]
persisted = await client.get_document_by_id(created.id)
assert persisted is not None
assert persisted.content == base_content
original_chunks = await client.chunk_repository.get_by_document_id(created.id) # type: ignore[arg-type]
original_chunks = await client.chunk_repository.get_by_document_id(created.id)
assert len(original_chunks) > 0

159
uv.lock
View file

@ -659,7 +659,7 @@ wheels = [
[[package]]
name = "datasets"
version = "4.4.2"
version = "4.5.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "dill" },
@ -677,9 +677,9 @@ dependencies = [
{ name = "tqdm" },
{ name = "xxhash" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c4/54/9359803da96bc65439a28fbb014dc2c90b7d4d8034a93b72362b0d40191f/datasets-4.4.2.tar.gz", hash = "sha256:9de16e415c4ba4713eac0493f7c7dc74f3aa21599297f00cc6ddab409cb7b24b", size = 586474, upload-time = "2025-12-19T15:03:09.129Z" }
sdist = { url = "https://files.pythonhosted.org/packages/55/bf/bb927bde63d649296c83e883171ae77074717c1b80fe2868b328bd0dbcbb/datasets-4.5.0.tar.gz", hash = "sha256:00c698ce1c2452e646cc5fad47fef39d3fe78dd650a8a6eb205bb45eb63cd500", size = 588384, upload-time = "2026-01-14T18:27:54.297Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/7b/b5/fefa518c809de7bced5cddb7c21c010da66fa2ae494bda96844a280cc6ce/datasets-4.4.2-py3-none-any.whl", hash = "sha256:6f5ef3417504d9cd663c71c1b90b9a494ff4c2076a2cd6a6e40ceee6ad95befc", size = 512268, upload-time = "2025-12-19T15:03:07.087Z" },
{ url = "https://files.pythonhosted.org/packages/fc/d5/0d563ea3c205eee226dc8053cf7682a8ac588db8acecd0eda2b587987a0b/datasets-4.5.0-py3-none-any.whl", hash = "sha256:b5d7e08096ffa407dd69e58b1c0271c9b2506140839b8d99af07375ad31b6726", size = 515196, upload-time = "2026-01-14T18:27:52.419Z" },
]
[[package]]
@ -741,7 +741,7 @@ wheels = [
[[package]]
name = "docling"
version = "2.67.0"
version = "2.68.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "accelerate" },
@ -773,9 +773,9 @@ dependencies = [
{ name = "tqdm" },
{ name = "typer" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a7/eb/1900eaf576ab935d5b630a5ba6eb0e7063a2e1d36542df2f9ba572505d57/docling-2.67.0.tar.gz", hash = "sha256:d8c1992bbc090cee8c3f602fa63ac0c3127a65e3cabdf509d23ebb4e14feaf38", size = 259923, upload-time = "2026-01-09T08:37:37.984Z" }
sdist = { url = "https://files.pythonhosted.org/packages/f4/cb/5dcda48a739e18c3d087de55be064d1fe9dfa802132aba274d55466ced01/docling-2.68.0.tar.gz", hash = "sha256:fabadc7aa807b96ac9bf85cc78f4fe343b5df658857386bc23541a9a6c116132", size = 265952, upload-time = "2026-01-13T10:47:35.925Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/8d/99/fa9ac2cffaa77cf46b6414d0a32490b2580c8f3753ab1c65d983ee27f3a0/docling-2.67.0-py3-none-any.whl", hash = "sha256:d3ea4c0d7a64fce4b8f8b38415e075f6637384eaadb27acbf5621673e0da7669", size = 277794, upload-time = "2026-01-09T08:37:36.52Z" },
{ url = "https://files.pythonhosted.org/packages/d5/a5/08716dcbf93e350f0595b58ece138b3b78606ef2f6a5a5058b1642cfe142/docling-2.68.0-py3-none-any.whl", hash = "sha256:97b2a4957e221973c69f1706da326fda8e973707d041778df12c01a5279e3e7e", size = 282854, upload-time = "2026-01-13T10:47:34.325Z" },
]
[[package]]
@ -1304,12 +1304,12 @@ dev = [
{ name = "mkdocs-material" },
{ name = "pre-commit" },
{ name = "pydantic-ai-slim", extra = ["anthropic", "bedrock", "google", "groq"] },
{ name = "pyright" },
{ name = "pytest" },
{ name = "pytest-asyncio" },
{ name = "pytest-cov" },
{ name = "pytest-recording" },
{ name = "ruff" },
{ name = "ty" },
]
[package.metadata]
@ -1321,7 +1321,7 @@ provides-extras = ["tui"]
[package.metadata.requires-dev]
dev = [
{ name = "datasets", specifier = ">=4.4.2" },
{ name = "datasets", specifier = ">=4.5.0" },
{ name = "haiku-rag-evals", editable = "evaluations" },
{ name = "mkdocs", specifier = ">=1.6.1" },
{ name = "mkdocs-material", specifier = ">=9.7.1" },
@ -1330,12 +1330,12 @@ dev = [
{ name = "pydantic-ai-slim", extras = ["bedrock"] },
{ name = "pydantic-ai-slim", extras = ["google"] },
{ name = "pydantic-ai-slim", extras = ["groq"] },
{ name = "pyright", specifier = ">=1.1.408" },
{ name = "pytest", specifier = ">=9.0.2" },
{ name = "pytest-asyncio", specifier = ">=1.3.0" },
{ name = "pytest-cov", specifier = ">=7.0.0" },
{ name = "pytest-recording", specifier = ">=0.13.4" },
{ name = "ruff", specifier = ">=0.14.11" },
{ name = "ruff", specifier = ">=0.14.13" },
{ name = "ty", specifier = ">=0.0.12" },
]
[[package]]
@ -1352,9 +1352,9 @@ dependencies = [
[package.metadata]
requires-dist = [
{ name = "datasets", specifier = ">=4.4.2" },
{ name = "datasets", specifier = ">=4.5.0" },
{ name = "haiku-rag-slim", editable = "haiku_rag_slim" },
{ name = "pydantic-ai-slim", extras = ["evals", "logfire"], specifier = ">=1.39.0" },
{ name = "pydantic-ai-slim", extras = ["evals", "logfire"], specifier = ">=1.44.0" },
{ name = "python-dotenv", specifier = ">=1.2.1" },
{ name = "typer", specifier = ">=0.19.2,<0.20.0" },
]
@ -1420,25 +1420,25 @@ zeroentropy = [
[package.metadata]
requires-dist = [
{ name = "cohere", marker = "extra == 'cohere'", specifier = ">=5.20.1" },
{ name = "docling", marker = "extra == 'docling'", specifier = "==2.67.0" },
{ name = "docling", marker = "extra == 'docling'", specifier = "==2.68.0" },
{ name = "docling-core", specifier = "==2.59.0" },
{ name = "httpx", specifier = ">=0.28.1" },
{ name = "lancedb", specifier = "==0.26.1" },
{ name = "mxbai-rerank", marker = "extra == 'mxbai'", specifier = ">=0.1.6" },
{ name = "opencv-python-headless", marker = "extra == 'docling'", specifier = ">=4.12.0.88" },
{ name = "pathspec", specifier = ">=0.12.1" },
{ name = "opencv-python-headless", marker = "extra == 'docling'", specifier = ">=4.13.0.90" },
{ name = "pathspec", specifier = ">=1.0.3" },
{ name = "pydantic", specifier = ">=2.12.5" },
{ name = "pydantic-ai-slim", extras = ["anthropic"], marker = "extra == 'anthropic'" },
{ name = "pydantic-ai-slim", extras = ["bedrock"], marker = "extra == 'bedrock'" },
{ name = "pydantic-ai-slim", extras = ["google"], marker = "extra == 'google'" },
{ name = "pydantic-ai-slim", extras = ["groq"], marker = "extra == 'groq'" },
{ name = "pydantic-ai-slim", extras = ["mistral"], marker = "extra == 'mistral'" },
{ name = "pydantic-ai-slim", extras = ["openai", "fastmcp", "logfire", "ag-ui"], specifier = ">=1.39.0" },
{ name = "pydantic-ai-slim", extras = ["openai", "fastmcp", "logfire", "ag-ui"], specifier = ">=1.44.0" },
{ name = "pydantic-ai-slim", extras = ["vertexai"], marker = "extra == 'vertexai'" },
{ name = "python-dotenv", specifier = ">=1.2.1" },
{ name = "pyyaml", specifier = ">=6.0.3" },
{ name = "rich", specifier = ">=14.2.0" },
{ name = "textual", marker = "extra == 'tui'", specifier = ">=7.0.0" },
{ name = "textual", marker = "extra == 'tui'", specifier = ">=7.3.0" },
{ name = "textual-image", marker = "extra == 'tui'", specifier = ">=0.8.5" },
{ name = "typer", specifier = ">=0.19.2,<0.20.0" },
{ name = "voyageai", marker = "extra == 'voyageai'", specifier = ">=0.3.7" },
@ -2773,19 +2773,20 @@ wheels = [
[[package]]
name = "opencv-python-headless"
version = "4.12.0.88"
version = "4.13.0.90"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "numpy" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a4/63/6861102ec149c3cd298f4d1ea7ce9d6adbc7529221606ff1dab991a19adb/opencv-python-headless-4.12.0.88.tar.gz", hash = "sha256:cfdc017ddf2e59b6c2f53bc12d74b6b0be7ded4ec59083ea70763921af2b6c09", size = 95379675, upload-time = "2025-07-07T09:21:06.815Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f7/7d/414e243c5c8216a5277afd104a319cc1291c5e23f5eeef512db5629ee7f4/opencv_python_headless-4.12.0.88-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:1e58d664809b3350c1123484dd441e1667cd7bed3086db1b9ea1b6f6cb20b50e", size = 37877864, upload-time = "2025-07-07T09:14:41.693Z" },
{ url = "https://files.pythonhosted.org/packages/05/14/7e162714beed1cd5e7b5eb66fcbcba2f065c51b1d9da2463024c84d2f7c0/opencv_python_headless-4.12.0.88-cp37-abi3-macosx_13_0_x86_64.whl", hash = "sha256:365bb2e486b50feffc2d07a405b953a8f3e8eaa63865bc650034e5c71e7a5154", size = 57326608, upload-time = "2025-07-07T09:14:51.885Z" },
{ url = "https://files.pythonhosted.org/packages/69/4e/116720df7f1f7f3b59abc608ca30fbec9d2b3ae810afe4e4d26483d9dfa0/opencv_python_headless-4.12.0.88-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:aeb4b13ecb8b4a0beb2668ea07928160ea7c2cd2d9b5ef571bbee6bafe9cc8d0", size = 33145800, upload-time = "2025-07-07T09:15:00.367Z" },
{ url = "https://files.pythonhosted.org/packages/89/53/e19c21e0c4eb1275c3e2c97b081103b6dfb3938172264d283a519bf728b9/opencv_python_headless-4.12.0.88-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:236c8df54a90f4d02076e6f9c1cc763d794542e886c576a6fee46ec8ff75a7a9", size = 54023419, upload-time = "2025-07-07T09:15:10.164Z" },
{ url = "https://files.pythonhosted.org/packages/bf/9c/a76fd5414de6ec9f21f763a600058a0c3e290053cea87e0275692b1375c0/opencv_python_headless-4.12.0.88-cp37-abi3-win32.whl", hash = "sha256:fde2cf5c51e4def5f2132d78e0c08f9c14783cd67356922182c6845b9af87dbd", size = 30225230, upload-time = "2025-07-07T09:15:17.045Z" },
{ url = "https://files.pythonhosted.org/packages/f2/35/0858e9e71b36948eafbc5e835874b63e515179dc3b742cbe3d76bc683439/opencv_python_headless-4.12.0.88-cp37-abi3-win_amd64.whl", hash = "sha256:86b413bdd6c6bf497832e346cd5371995de148e579b9774f8eba686dee3f5528", size = 38923559, upload-time = "2025-07-07T09:15:25.229Z" },
{ url = "https://files.pythonhosted.org/packages/ed/76/38c4cbb5ccfce7aaf36fd9be9fc74a15c85a48ef90bfaca2049b486e10c5/opencv_python_headless-4.13.0.90-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:12a28674f215542c9bf93338de1b5bffd76996d32da9acb9e739fdb9c8bbd738", size = 46020414, upload-time = "2026-01-18T09:07:10.801Z" },
{ url = "https://files.pythonhosted.org/packages/93/c5/4b40daa5003b45aa8397f160324a091ed323733e2446dc0bdf3655e77b84/opencv_python_headless-4.13.0.90-cp37-abi3-macosx_14_0_x86_64.whl", hash = "sha256:32255203040dc98803be96362e13f9e4bce20146898222d2e5c242f80de50da5", size = 32568519, upload-time = "2026-01-18T09:07:52.368Z" },
{ url = "https://files.pythonhosted.org/packages/da/65/920e64a7f03cf5917cd2c6a3046293843c1a16ad89f0ed0f1c683979c9de/opencv_python_headless-4.13.0.90-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e13790342591557050157713af17a7435ac1b50c65282715093c9297fa045d8f", size = 35191272, upload-time = "2026-01-18T09:08:49.235Z" },
{ url = "https://files.pythonhosted.org/packages/fc/13/af150685be342dc09bfb0824e2a280020ccf1c7fc64e15a31d9209016aa9/opencv_python_headless-4.13.0.90-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dbc1f4625e5af3a80ebdbd84380227c0f445228588f2521b11af47710caca1ba", size = 57683677, upload-time = "2026-01-18T09:10:23.588Z" },
{ url = "https://files.pythonhosted.org/packages/cd/47/baab2a3b6d8da8c52e73d00207d1ed3155601c2c332ea855455b3fbc8ff4/opencv_python_headless-4.13.0.90-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:eba38bc255d0b7d1969c5bcc90a060ca2b61a3403b613872c750bfa5dfe9e03b", size = 36590019, upload-time = "2026-01-18T09:10:49.053Z" },
{ url = "https://files.pythonhosted.org/packages/81/a1/facfe2801a861b424c4221d66e1281cf19735c00e07f063a337a208c11b5/opencv_python_headless-4.13.0.90-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f46b17ea0aa7e4124ca6ad71143f89233ae9557f61d2326bcdb34329a1ddf9bd", size = 62535926, upload-time = "2026-01-18T09:12:47.229Z" },
{ url = "https://files.pythonhosted.org/packages/06/d2/5e9ee7512306c1caa518be929d1f44bb1c189f342f538f73bea6fb94919f/opencv_python_headless-4.13.0.90-cp37-abi3-win32.whl", hash = "sha256:96060fc57a1abb1144b0b8129e2ff3bfcdd0ccd8e8bd05bd85256ff4ed587d3b", size = 30811665, upload-time = "2026-01-18T09:13:44.517Z" },
{ url = "https://files.pythonhosted.org/packages/a0/09/0a4d832448dccd03b2b1bdee70b9fc2e02c147cc7e06975e9cd729569d90/opencv_python_headless-4.13.0.90-cp37-abi3-win_amd64.whl", hash = "sha256:0e0c8c9f620802fddc4fa7f471a1d263c7b0dca16cd9e7e2f996bb8bd2128c0c", size = 40070035, upload-time = "2026-01-18T09:15:14.652Z" },
]
[[package]]
@ -3065,11 +3066,11 @@ wheels = [
[[package]]
name = "pathspec"
version = "0.12.1"
version = "1.0.3"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" }
sdist = { url = "https://files.pythonhosted.org/packages/4c/b2/bb8e495d5262bfec41ab5cb18f522f1012933347fb5d9e62452d446baca2/pathspec-1.0.3.tar.gz", hash = "sha256:bac5cf97ae2c2876e2d25ebb15078eb04d76e4b98921ee31c6f85ade8b59444d", size = 130841, upload-time = "2026-01-09T15:46:46.009Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" },
{ url = "https://files.pythonhosted.org/packages/32/2b/121e912bd60eebd623f873fd090de0e84f322972ab25a7f9044c056804ed/pathspec-1.0.3-py3-none-any.whl", hash = "sha256:e80767021c1cc524aa3fb14bedda9c34406591343cc42797b386ce7b9354fb6c", size = 55021, upload-time = "2026-01-09T15:46:44.652Z" },
]
[[package]]
@ -3496,7 +3497,7 @@ email = [
[[package]]
name = "pydantic-ai-slim"
version = "1.39.0"
version = "1.44.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "genai-prices" },
@ -3507,9 +3508,9 @@ dependencies = [
{ name = "pydantic-graph" },
{ name = "typing-inspection" },
]
sdist = { url = "https://files.pythonhosted.org/packages/91/cb/542ad43e06da09104ef3443556e629d9aa260f9d584da8f7a410fb3a07e5/pydantic_ai_slim-1.39.0.tar.gz", hash = "sha256:e8cea9fc8f6149347c3e1d489b0ed2d541b4789e0583819f116284145d22fa69", size = 368962, upload-time = "2025-12-24T03:34:11.306Z" }
sdist = { url = "https://files.pythonhosted.org/packages/24/73/122aafb9bcad78042e2799649db745c357fc594e112c0ad0d8d183fdc447/pydantic_ai_slim-1.44.0.tar.gz", hash = "sha256:1bda6dbec4b94d8e52e32eb1e4c1da14f4f0202414306c65e2c3b43bebd82407", size = 378362, upload-time = "2026-01-17T01:26:09.64Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2a/df/86381632be07b7df2e8e5880a1f18c6ee98122adf5848d329fee239a03b2/pydantic_ai_slim-1.39.0-py3-none-any.whl", hash = "sha256:8669d1781eba7713870bf76783e1e853577d5e55eb2986a27d49bc600889aaaf", size = 484906, upload-time = "2025-12-24T03:34:03.179Z" },
{ url = "https://files.pythonhosted.org/packages/1a/18/2f68a9718843a95c0b4724ab3821ef8f60f7b8ef50e70b3769db3259da81/pydantic_ai_slim-1.44.0-py3-none-any.whl", hash = "sha256:3bf412f43d3ae787350d671f873706ad74603777e04f42411c8fbdf7dced8031", size = 496441, upload-time = "2026-01-17T01:26:00.184Z" },
]
[package.optional-dependencies]
@ -3623,7 +3624,7 @@ wheels = [
[[package]]
name = "pydantic-evals"
version = "1.39.0"
version = "1.44.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
@ -3633,14 +3634,14 @@ dependencies = [
{ name = "pyyaml" },
{ name = "rich" },
]
sdist = { url = "https://files.pythonhosted.org/packages/20/20/ec455c7d32fde2022805870daf78581c9c493a4fcae6f32204fae5025658/pydantic_evals-1.39.0.tar.gz", hash = "sha256:6f8a754ca84afff3f2b2de9802fb0e12f69d9fc0a0411e2f7c9709fc09fb43b3", size = 47179, upload-time = "2025-12-24T03:34:12.477Z" }
sdist = { url = "https://files.pythonhosted.org/packages/10/0c/3a11101799972833585458caa5c0aa1b1cc8045acaaaec70846cb5dfdb3a/pydantic_evals-1.44.0.tar.gz", hash = "sha256:d93733e1d042c8f312645a969d7496b97d18d0030cb47174e57047ac56a2fc81", size = 47174, upload-time = "2026-01-17T01:26:10.745Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f6/c1/6d43ecd3f7acb78a3f683178d40008d486c08583ca848891f000d62c142e/pydantic_evals-1.39.0-py3-none-any.whl", hash = "sha256:18470ade5fea15d17911a517e37ea98700702d9ba011ef2facb707e87eae0564", size = 56347, upload-time = "2025-12-24T03:34:05.111Z" },
{ url = "https://files.pythonhosted.org/packages/20/4a/0bb5c78a0c82eaa2fe4b4caf15afa676aa37cad8b3dfeabb7766f7f651df/pydantic_evals-1.44.0-py3-none-any.whl", hash = "sha256:6eed03e42cc0e6f9fd022345dce3db0113614052321037efeb47a408a95f460c", size = 56346, upload-time = "2026-01-17T01:26:02.053Z" },
]
[[package]]
name = "pydantic-graph"
version = "1.39.0"
version = "1.44.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "httpx" },
@ -3648,9 +3649,9 @@ dependencies = [
{ name = "pydantic" },
{ name = "typing-inspection" },
]
sdist = { url = "https://files.pythonhosted.org/packages/09/d5/2f45d1fd2ae0ba89b5a70b3bec8c2e910c4891fe0ed7e4fc896ca7e126a0/pydantic_graph-1.39.0.tar.gz", hash = "sha256:08c6f349dbbade6f4cdaaed02de4e8d75b9a37d44f8238e40a14f94f6a31761f", size = 58453, upload-time = "2025-12-24T03:34:13.766Z" }
sdist = { url = "https://files.pythonhosted.org/packages/aa/d9/83f1921633634cb1fd5947ebdc48a992cd1e660d9d0ba10f23450af654b8/pydantic_graph-1.44.0.tar.gz", hash = "sha256:81bb14bb47d3313fd7114f3ae9650dab77729451659e0247d298e1800f997c23", size = 58454, upload-time = "2026-01-17T01:26:12.113Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/65/e2/719de1af767863359278e8b69c538dba9a7dbd19bb94111206e57ca34648/pydantic_graph-1.39.0-py3-none-any.whl", hash = "sha256:e0f89fc2c7ab111ae5f38dd2d88c5d26a0784eaabe95735c2b4087b0b512cc2d", size = 72327, upload-time = "2025-12-24T03:34:06.476Z" },
{ url = "https://files.pythonhosted.org/packages/6f/e6/f9ed700171435309e214cf19012cf3b391d10ec28786d4a567ee315b1acd/pydantic_graph-1.44.0-py3-none-any.whl", hash = "sha256:5affbfe5779f79946de2c6a6524b98e2344982a129b2a1e19d031e76a5bc1e51", size = 72324, upload-time = "2026-01-17T01:26:04.119Z" },
]
[[package]]
@ -3843,19 +3844,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/df/80/fc9d01d5ed37ba4c42ca2b55b4339ae6e200b456be3a1aaddf4a9fa99b8c/pyperclip-1.11.0-py3-none-any.whl", hash = "sha256:299403e9ff44581cb9ba2ffeed69c7aa96a008622ad0c46cb575ca75b5b84273", size = 11063, upload-time = "2025-09-26T14:40:36.069Z" },
]
[[package]]
name = "pyright"
version = "1.1.408"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "nodeenv" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/74/b2/5db700e52554b8f025faa9c3c624c59f1f6c8841ba81ab97641b54322f16/pyright-1.1.408.tar.gz", hash = "sha256:f28f2321f96852fa50b5829ea492f6adb0e6954568d1caa3f3af3a5f555eb684", size = 4400578, upload-time = "2026-01-08T08:07:38.795Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/0c/82/a2c93e32800940d9573fb28c346772a14778b84ba7524e691b324620ab89/pyright-1.1.408-py3-none-any.whl", hash = "sha256:090b32865f4fdb1e0e6cd82bf5618480d48eecd2eb2e70f960982a3d9a4c17c1", size = 6399144, upload-time = "2026-01-08T08:07:37.082Z" },
]
[[package]]
name = "pytest"
version = "9.0.2"
@ -4357,28 +4345,28 @@ wheels = [
[[package]]
name = "ruff"
version = "0.14.11"
version = "0.14.13"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d4/77/9a7fe084d268f8855d493e5031ea03fa0af8cc05887f638bf1c4e3363eb8/ruff-0.14.11.tar.gz", hash = "sha256:f6dc463bfa5c07a59b1ff2c3b9767373e541346ea105503b4c0369c520a66958", size = 5993417, upload-time = "2026-01-08T19:11:58.322Z" }
sdist = { url = "https://files.pythonhosted.org/packages/50/0a/1914efb7903174b381ee2ffeebb4253e729de57f114e63595114c8ca451f/ruff-0.14.13.tar.gz", hash = "sha256:83cd6c0763190784b99650a20fec7633c59f6ebe41c5cc9d45ee42749563ad47", size = 6059504, upload-time = "2026-01-15T20:15:16.918Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f0/a6/a4c40a5aaa7e331f245d2dc1ac8ece306681f52b636b40ef87c88b9f7afd/ruff-0.14.11-py3-none-linux_armv6l.whl", hash = "sha256:f6ff2d95cbd335841a7217bdfd9c1d2e44eac2c584197ab1385579d55ff8830e", size = 12951208, upload-time = "2026-01-08T19:12:09.218Z" },
{ url = "https://files.pythonhosted.org/packages/5c/5c/360a35cb7204b328b685d3129c08aca24765ff92b5a7efedbdd6c150d555/ruff-0.14.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6f6eb5c1c8033680f4172ea9c8d3706c156223010b8b97b05e82c59bdc774ee6", size = 13330075, upload-time = "2026-01-08T19:12:02.549Z" },
{ url = "https://files.pythonhosted.org/packages/1b/9e/0cc2f1be7a7d33cae541824cf3f95b4ff40d03557b575912b5b70273c9ec/ruff-0.14.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f2fc34cc896f90080fca01259f96c566f74069a04b25b6205d55379d12a6855e", size = 12257809, upload-time = "2026-01-08T19:12:00.366Z" },
{ url = "https://files.pythonhosted.org/packages/a7/e5/5faab97c15bb75228d9f74637e775d26ac703cc2b4898564c01ab3637c02/ruff-0.14.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53386375001773ae812b43205d6064dae49ff0968774e6befe16a994fc233caa", size = 12678447, upload-time = "2026-01-08T19:12:13.899Z" },
{ url = "https://files.pythonhosted.org/packages/1b/33/e9767f60a2bef779fb5855cab0af76c488e0ce90f7bb7b8a45c8a2ba4178/ruff-0.14.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a697737dce1ca97a0a55b5ff0434ee7205943d4874d638fe3ae66166ff46edbe", size = 12758560, upload-time = "2026-01-08T19:11:42.55Z" },
{ url = "https://files.pythonhosted.org/packages/eb/84/4c6cf627a21462bb5102f7be2a320b084228ff26e105510cd2255ea868e5/ruff-0.14.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6845ca1da8ab81ab1dce755a32ad13f1db72e7fba27c486d5d90d65e04d17b8f", size = 13599296, upload-time = "2026-01-08T19:11:30.371Z" },
{ url = "https://files.pythonhosted.org/packages/88/e1/92b5ed7ea66d849f6157e695dc23d5d6d982bd6aa8d077895652c38a7cae/ruff-0.14.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e36ce2fd31b54065ec6f76cb08d60159e1b32bdf08507862e32f47e6dde8bcbf", size = 15048981, upload-time = "2026-01-08T19:12:04.742Z" },
{ url = "https://files.pythonhosted.org/packages/61/df/c1bd30992615ac17c2fb64b8a7376ca22c04a70555b5d05b8f717163cf9f/ruff-0.14.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:590bcc0e2097ecf74e62a5c10a6b71f008ad82eb97b0a0079e85defe19fe74d9", size = 14633183, upload-time = "2026-01-08T19:11:40.069Z" },
{ url = "https://files.pythonhosted.org/packages/04/e9/fe552902f25013dd28a5428a42347d9ad20c4b534834a325a28305747d64/ruff-0.14.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:53fe71125fc158210d57fe4da26e622c9c294022988d08d9347ec1cf782adafe", size = 14050453, upload-time = "2026-01-08T19:11:37.555Z" },
{ url = "https://files.pythonhosted.org/packages/ae/93/f36d89fa021543187f98991609ce6e47e24f35f008dfe1af01379d248a41/ruff-0.14.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a35c9da08562f1598ded8470fcfef2afb5cf881996e6c0a502ceb61f4bc9c8a3", size = 13757889, upload-time = "2026-01-08T19:12:07.094Z" },
{ url = "https://files.pythonhosted.org/packages/b7/9f/c7fb6ecf554f28709a6a1f2a7f74750d400979e8cd47ed29feeaa1bd4db8/ruff-0.14.11-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:0f3727189a52179393ecf92ec7057c2210203e6af2676f08d92140d3e1ee72c1", size = 13955832, upload-time = "2026-01-08T19:11:55.064Z" },
{ url = "https://files.pythonhosted.org/packages/db/a0/153315310f250f76900a98278cf878c64dfb6d044e184491dd3289796734/ruff-0.14.11-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:eb09f849bd37147a789b85995ff734a6c4a095bed5fd1608c4f56afc3634cde2", size = 12586522, upload-time = "2026-01-08T19:11:35.356Z" },
{ url = "https://files.pythonhosted.org/packages/2f/2b/a73a2b6e6d2df1d74bf2b78098be1572191e54bec0e59e29382d13c3adc5/ruff-0.14.11-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:c61782543c1231bf71041461c1f28c64b961d457d0f238ac388e2ab173d7ecb7", size = 12724637, upload-time = "2026-01-08T19:11:47.796Z" },
{ url = "https://files.pythonhosted.org/packages/f0/41/09100590320394401cd3c48fc718a8ba71c7ddb1ffd07e0ad6576b3a3df2/ruff-0.14.11-py3-none-musllinux_1_2_i686.whl", hash = "sha256:82ff352ea68fb6766140381748e1f67f83c39860b6446966cff48a315c3e2491", size = 13145837, upload-time = "2026-01-08T19:11:32.87Z" },
{ url = "https://files.pythonhosted.org/packages/3b/d8/e035db859d1d3edf909381eb8ff3e89a672d6572e9454093538fe6f164b0/ruff-0.14.11-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:728e56879df4ca5b62a9dde2dd0eb0edda2a55160c0ea28c4025f18c03f86984", size = 13850469, upload-time = "2026-01-08T19:12:11.694Z" },
{ url = "https://files.pythonhosted.org/packages/4e/02/bb3ff8b6e6d02ce9e3740f4c17dfbbfb55f34c789c139e9cd91985f356c7/ruff-0.14.11-py3-none-win32.whl", hash = "sha256:337c5dd11f16ee52ae217757d9b82a26400be7efac883e9e852646f1557ed841", size = 12851094, upload-time = "2026-01-08T19:11:45.163Z" },
{ url = "https://files.pythonhosted.org/packages/58/f1/90ddc533918d3a2ad628bc3044cdfc094949e6d4b929220c3f0eb8a1c998/ruff-0.14.11-py3-none-win_amd64.whl", hash = "sha256:f981cea63d08456b2c070e64b79cb62f951aa1305282974d4d5216e6e0178ae6", size = 14001379, upload-time = "2026-01-08T19:11:52.591Z" },
{ url = "https://files.pythonhosted.org/packages/c4/1c/1dbe51782c0e1e9cfce1d1004752672d2d4629ea46945d19d731ad772b3b/ruff-0.14.11-py3-none-win_arm64.whl", hash = "sha256:649fb6c9edd7f751db276ef42df1f3df41c38d67d199570ae2a7bd6cbc3590f0", size = 12938644, upload-time = "2026-01-08T19:11:50.027Z" },
{ url = "https://files.pythonhosted.org/packages/c3/ae/0deefbc65ca74b0ab1fd3917f94dc3b398233346a74b8bbb0a916a1a6bf6/ruff-0.14.13-py3-none-linux_armv6l.whl", hash = "sha256:76f62c62cd37c276cb03a275b198c7c15bd1d60c989f944db08a8c1c2dbec18b", size = 13062418, upload-time = "2026-01-15T20:14:50.779Z" },
{ url = "https://files.pythonhosted.org/packages/47/df/5916604faa530a97a3c154c62a81cb6b735c0cb05d1e26d5ad0f0c8ac48a/ruff-0.14.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:914a8023ece0528d5cc33f5a684f5f38199bbb566a04815c2c211d8f40b5d0ed", size = 13442344, upload-time = "2026-01-15T20:15:07.94Z" },
{ url = "https://files.pythonhosted.org/packages/4c/f3/e0e694dd69163c3a1671e102aa574a50357536f18a33375050334d5cd517/ruff-0.14.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d24899478c35ebfa730597a4a775d430ad0d5631b8647a3ab368c29b7e7bd063", size = 12354720, upload-time = "2026-01-15T20:15:09.854Z" },
{ url = "https://files.pythonhosted.org/packages/c3/e8/67f5fcbbaee25e8fc3b56cc33e9892eca7ffe09f773c8e5907757a7e3bdb/ruff-0.14.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9aaf3870f14d925bbaf18b8a2347ee0ae7d95a2e490e4d4aea6813ed15ebc80e", size = 12774493, upload-time = "2026-01-15T20:15:20.908Z" },
{ url = "https://files.pythonhosted.org/packages/6b/ce/d2e9cb510870b52a9565d885c0d7668cc050e30fa2c8ac3fb1fda15c083d/ruff-0.14.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac5b7f63dd3b27cc811850f5ffd8fff845b00ad70e60b043aabf8d6ecc304e09", size = 12815174, upload-time = "2026-01-15T20:15:05.74Z" },
{ url = "https://files.pythonhosted.org/packages/88/00/c38e5da58beebcf4fa32d0ddd993b63dfacefd02ab7922614231330845bf/ruff-0.14.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78d2b1097750d90ba82ce4ba676e85230a0ed694178ca5e61aa9b459970b3eb9", size = 13680909, upload-time = "2026-01-15T20:15:14.537Z" },
{ url = "https://files.pythonhosted.org/packages/61/61/cd37c9dd5bd0a3099ba79b2a5899ad417d8f3b04038810b0501a80814fd7/ruff-0.14.13-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7d0bf87705acbbcb8d4c24b2d77fbb73d40210a95c3903b443cd9e30824a5032", size = 15144215, upload-time = "2026-01-15T20:15:22.886Z" },
{ url = "https://files.pythonhosted.org/packages/56/8a/85502d7edbf98c2df7b8876f316c0157359165e16cdf98507c65c8d07d3d/ruff-0.14.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3eb5da8e2c9e9f13431032fdcbe7681de9ceda5835efee3269417c13f1fed5c", size = 14706067, upload-time = "2026-01-15T20:14:48.271Z" },
{ url = "https://files.pythonhosted.org/packages/7e/2f/de0df127feb2ee8c1e54354dc1179b4a23798f0866019528c938ba439aca/ruff-0.14.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:642442b42957093811cd8d2140dfadd19c7417030a7a68cf8d51fcdd5f217427", size = 14133916, upload-time = "2026-01-15T20:14:57.357Z" },
{ url = "https://files.pythonhosted.org/packages/0d/77/9b99686bb9fe07a757c82f6f95e555c7a47801a9305576a9c67e0a31d280/ruff-0.14.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4acdf009f32b46f6e8864af19cbf6841eaaed8638e65c8dac845aea0d703c841", size = 13859207, upload-time = "2026-01-15T20:14:55.111Z" },
{ url = "https://files.pythonhosted.org/packages/7d/46/2bdcb34a87a179a4d23022d818c1c236cb40e477faf0d7c9afb6813e5876/ruff-0.14.13-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:591a7f68860ea4e003917d19b5c4f5ac39ff558f162dc753a2c5de897fd5502c", size = 14043686, upload-time = "2026-01-15T20:14:52.841Z" },
{ url = "https://files.pythonhosted.org/packages/1a/a9/5c6a4f56a0512c691cf143371bcf60505ed0f0860f24a85da8bd123b2bf1/ruff-0.14.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:774c77e841cc6e046fc3e91623ce0903d1cd07e3a36b1a9fe79b81dab3de506b", size = 12663837, upload-time = "2026-01-15T20:15:18.921Z" },
{ url = "https://files.pythonhosted.org/packages/fe/bb/b920016ece7651fa7fcd335d9d199306665486694d4361547ccb19394c44/ruff-0.14.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:61f4e40077a1248436772bb6512db5fc4457fe4c49e7a94ea7c5088655dd21ae", size = 12805867, upload-time = "2026-01-15T20:14:59.272Z" },
{ url = "https://files.pythonhosted.org/packages/7d/b3/0bd909851e5696cd21e32a8fc25727e5f58f1934b3596975503e6e85415c/ruff-0.14.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6d02f1428357fae9e98ac7aa94b7e966fd24151088510d32cf6f902d6c09235e", size = 13208528, upload-time = "2026-01-15T20:15:03.732Z" },
{ url = "https://files.pythonhosted.org/packages/3b/3b/e2d94cb613f6bbd5155a75cbe072813756363eba46a3f2177a1fcd0cd670/ruff-0.14.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e399341472ce15237be0c0ae5fbceca4b04cd9bebab1a2b2c979e015455d8f0c", size = 13929242, upload-time = "2026-01-15T20:15:11.918Z" },
{ url = "https://files.pythonhosted.org/packages/6a/c5/abd840d4132fd51a12f594934af5eba1d5d27298a6f5b5d6c3be45301caf/ruff-0.14.13-py3-none-win32.whl", hash = "sha256:ef720f529aec113968b45dfdb838ac8934e519711da53a0456038a0efecbd680", size = 12919024, upload-time = "2026-01-15T20:14:43.647Z" },
{ url = "https://files.pythonhosted.org/packages/c2/55/6384b0b8ce731b6e2ade2b5449bf07c0e4c31e8a2e68ea65b3bafadcecc5/ruff-0.14.13-py3-none-win_amd64.whl", hash = "sha256:6070bd026e409734b9257e03e3ef18c6e1a216f0435c6751d7a8ec69cb59abef", size = 14097887, upload-time = "2026-01-15T20:15:01.48Z" },
{ url = "https://files.pythonhosted.org/packages/4d/e1/7348090988095e4e39560cfc2f7555b1b2a7357deba19167b600fdf5215d/ruff-0.14.13-py3-none-win_arm64.whl", hash = "sha256:7ab819e14f1ad9fe39f246cfcc435880ef7a9390d81a2b6ac7e01039083dd247", size = 13080224, upload-time = "2026-01-15T20:14:45.853Z" },
]
[[package]]
@ -4672,7 +4660,7 @@ wheels = [
[[package]]
name = "textual"
version = "7.0.0"
version = "7.3.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "markdown-it-py", extra = ["linkify"] },
@ -4682,9 +4670,9 @@ dependencies = [
{ name = "rich" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/d4/9c/ebc9ca1f95366bef4c0e8360f4a77400d47a79aeecc08747de1990ef8bdc/textual-7.0.0.tar.gz", hash = "sha256:617638a2be74fb7507aff3ea6ec9374148be02e5a7bb1d02396d1d557b66c0a9", size = 1582005, upload-time = "2026-01-03T11:48:10.909Z" }
sdist = { url = "https://files.pythonhosted.org/packages/6f/ee/620c887bfad9d6eba062dfa3b6b0e735e0259102e2667b19f21625ef598d/textual-7.3.0.tar.gz", hash = "sha256:3169e8ba5518a979b0771e60be380ab1a6c344f30a2126e360e6f38d009a3de4", size = 1590692, upload-time = "2026-01-15T16:32:02.342Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/63/f8/a1ef9034b2a7f334f91b2f673f2ec03020a2529bb30a9437a6beb855beee/textual-7.0.0-py3-none-any.whl", hash = "sha256:190de0f65e5f4bc820fae46f32f591e509621d76688b36400ce01fa63dc6b623", size = 715156, upload-time = "2026-01-03T11:48:09.067Z" },
{ url = "https://files.pythonhosted.org/packages/c3/1f/abeb4e5cb36b99dd37db72beb2a74d58598ccb35aaadf14624ee967d4a6b/textual-7.3.0-py3-none-any.whl", hash = "sha256:db235cecf969c87fe5a9c04d83595f506affc9db81f3a53ab849534d726d330a", size = 716374, upload-time = "2026-01-15T16:31:58.233Z" },
]
[[package]]
@ -4992,6 +4980,31 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/16/b5/b0d3d8b901b6a04ca38df5e24c27e53afb15b93624d7fd7d658c7cd9352a/triton-3.5.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bac7f7d959ad0f48c0e97d6643a1cc0fd5786fe61cb1f83b537c6b2d54776478", size = 170582192, upload-time = "2025-11-11T17:41:23.963Z" },
]
[[package]]
name = "ty"
version = "0.0.12"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/b5/78/ba1a4ad403c748fbba8be63b7e774a90e80b67192f6443d624c64fe4aaab/ty-0.0.12.tar.gz", hash = "sha256:cd01810e106c3b652a01b8f784dd21741de9fdc47bd595d02c122a7d5cefeee7", size = 4981303, upload-time = "2026-01-14T22:30:48.537Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/7d/8f/c21314d074dda5fb13d3300fa6733fd0d8ff23ea83a721818740665b6314/ty-0.0.12-py3-none-linux_armv6l.whl", hash = "sha256:eb9da1e2c68bd754e090eab39ed65edf95168d36cbeb43ff2bd9f86b4edd56d1", size = 9614164, upload-time = "2026-01-14T22:30:44.016Z" },
{ url = "https://files.pythonhosted.org/packages/09/28/f8a4d944d13519d70c486e8f96d6fa95647ac2aa94432e97d5cfec1f42f6/ty-0.0.12-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:c181f42aa19b0ed7f1b0c2d559980b1f1d77cc09419f51c8321c7ddf67758853", size = 9542337, upload-time = "2026-01-14T22:30:05.687Z" },
{ url = "https://files.pythonhosted.org/packages/e1/9c/f576e360441de7a8201daa6dc4ebc362853bc5305e059cceeb02ebdd9a48/ty-0.0.12-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1f829e1eecd39c3e1b032149db7ae6a3284f72fc36b42436e65243a9ed1173db", size = 8909582, upload-time = "2026-01-14T22:30:46.089Z" },
{ url = "https://files.pythonhosted.org/packages/d6/13/0898e494032a5d8af3060733d12929e3e7716db6c75eac63fa125730a3e7/ty-0.0.12-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45162e7826e1789cf3374627883cdeb0d56b82473a0771923e4572928e90be3", size = 9384932, upload-time = "2026-01-14T22:30:13.769Z" },
{ url = "https://files.pythonhosted.org/packages/e4/1a/b35b6c697008a11d4cedfd34d9672db2f0a0621ec80ece109e13fca4dfef/ty-0.0.12-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d11fec40b269bec01e751b2337d1c7ffa959a2c2090a950d7e21c2792442cccd", size = 9453140, upload-time = "2026-01-14T22:30:11.131Z" },
{ url = "https://files.pythonhosted.org/packages/dd/1e/71c9edbc79a3c88a0711324458f29c7dbf6c23452c6e760dc25725483064/ty-0.0.12-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09d99e37e761a4d2651ad9d5a610d11235fbcbf35dc6d4bc04abf54e7cf894f1", size = 9960680, upload-time = "2026-01-14T22:30:33.621Z" },
{ url = "https://files.pythonhosted.org/packages/0e/75/39375129f62dd22f6ad5a99cd2a42fd27d8b91b235ce2db86875cdad397d/ty-0.0.12-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d9ca0cdb17bd37397da7b16a7cd23423fc65c3f9691e453ad46c723d121225a1", size = 10904518, upload-time = "2026-01-14T22:30:08.464Z" },
{ url = "https://files.pythonhosted.org/packages/32/5e/26c6d88fafa11a9d31ca9f4d12989f57782ec61e7291d4802d685b5be118/ty-0.0.12-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcf2757b905e7eddb7e456140066335b18eb68b634a9f72d6f54a427ab042c64", size = 10525001, upload-time = "2026-01-14T22:30:16.454Z" },
{ url = "https://files.pythonhosted.org/packages/c2/a5/2f0b91894af13187110f9ad7ee926d86e4e6efa755c9c88a820ed7f84c85/ty-0.0.12-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:00cf34c1ebe1147efeda3021a1064baa222c18cdac114b7b050bbe42deb4ca80", size = 10307103, upload-time = "2026-01-14T22:30:41.221Z" },
{ url = "https://files.pythonhosted.org/packages/4b/77/13d0410827e4bc713ebb7fdaf6b3590b37dcb1b82e0a81717b65548f2442/ty-0.0.12-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb3a655bd869352e9a22938d707631ac9fbca1016242b1f6d132d78f347c851", size = 10072737, upload-time = "2026-01-14T22:30:51.783Z" },
{ url = "https://files.pythonhosted.org/packages/e1/dd/fc36d8bac806c74cf04b4ca735bca14d19967ca84d88f31e121767880df1/ty-0.0.12-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4658e282c7cb82be304052f8f64f9925f23c3c4f90eeeb32663c74c4b095d7ba", size = 9368726, upload-time = "2026-01-14T22:30:18.683Z" },
{ url = "https://files.pythonhosted.org/packages/54/70/9e8e461647550f83e2fe54bc632ccbdc17a4909644783cdbdd17f7296059/ty-0.0.12-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:c167d838eaaa06e03bb66a517f75296b643d950fbd93c1d1686a187e5a8dbd1f", size = 9454704, upload-time = "2026-01-14T22:30:22.759Z" },
{ url = "https://files.pythonhosted.org/packages/04/9b/6292cf7c14a0efeca0539cf7d78f453beff0475cb039fbea0eb5d07d343d/ty-0.0.12-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2956e0c9ab7023533b461d8a0e6b2ea7b78e01a8dde0688e8234d0fce10c4c1c", size = 9649829, upload-time = "2026-01-14T22:30:31.234Z" },
{ url = "https://files.pythonhosted.org/packages/49/bd/472a5d2013371e4870886cff791c94abdf0b92d43d305dd0f8e06b6ff719/ty-0.0.12-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5c6a3fd7479580009f21002f3828320621d8a82d53b7ba36993234e3ccad58c8", size = 10162814, upload-time = "2026-01-14T22:30:36.174Z" },
{ url = "https://files.pythonhosted.org/packages/31/e9/2ecbe56826759845a7c21d80aa28187865ea62bc9757b056f6cbc06f78ed/ty-0.0.12-py3-none-win32.whl", hash = "sha256:a91c24fd75c0f1796d8ede9083e2c0ec96f106dbda73a09fe3135e075d31f742", size = 9140115, upload-time = "2026-01-14T22:30:38.903Z" },
{ url = "https://files.pythonhosted.org/packages/5d/6d/d9531eff35a5c0ec9dbc10231fac21f9dd6504814048e81d6ce1c84dc566/ty-0.0.12-py3-none-win_amd64.whl", hash = "sha256:df151894be55c22d47068b0f3b484aff9e638761e2267e115d515fcc9c5b4a4b", size = 9884532, upload-time = "2026-01-14T22:30:25.112Z" },
{ url = "https://files.pythonhosted.org/packages/e9/f3/20b49e75967023b123a221134548ad7000f9429f13fdcdda115b4c26305f/ty-0.0.12-py3-none-win_arm64.whl", hash = "sha256:cea99d334b05629de937ce52f43278acf155d3a316ad6a35356635f886be20ea", size = 9313974, upload-time = "2026-01-14T22:30:27.44Z" },
]
[[package]]
name = "typer"
version = "0.19.2"