Skip to content
This repository was archived by the owner on Jun 16, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions REUSE.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@

version = 1

# =============================================================================
# Python bytecode cache files - generated automatically by the Python interpreter
# =============================================================================
# These .pyc files in __pycache__ directories are auto-generated by Python
# and are excluded from version control via .gitignore. They are covered here
# to prevent reuse lint failures when they exist transiently (e.g. during CI).
[[annotations]]
path = ["**/__pycache__/**", "**/*.pyc", "**/*.pyo"]
precedence = "override"
SPDX-FileCopyrightText = "2025 Knitli Inc."
SPDX-License-Identifier = "MIT OR Apache-2.0"

# =============================================================================
# typings/uuid_extensions - Type stubs generated by pyright from uuid7 package
# =============================================================================
Expand Down
67 changes: 56 additions & 11 deletions mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ MISE_EXPERIMENTAL = "1"
GH_REPO = "knitli/codeweaver"
REMOTE_ORIGIN_URL = '''http://github.com/knitli/codeweaver.git'''
PROJECT_NAME = "codeweaver"
# defaults to false -- override in a local mise.local.toml if you want to use GPU dependencies (recommended if hardware supports it)
CODEWEAVER__DEV__USE_GPU = '''{{ get_env(name="CODEWEAVER__DEV__USE_GPU", default="false") }}'''
# According to the mise docs, config_root should always be the project root. Even if the mise.toml is in a subdirectory.
# But that didn't seem to be the case, so we manually trim known suffixes.
CODEWEAVER_PROJECT_PATH = '''{{ config_root | trim | trim_end_matches(pat="/") | trim_end_matches(pat="/mise") | trim_end_matches(pat="/.config") }}'''
Expand All @@ -30,18 +32,19 @@ _.path = [
"scripts/testing",
"scripts/utils",
".venv/bin",
"tools/exportify/",
]
MISE_ENV = '''{% if get_env(name="CI", default="") == "true" %}""{% else %}dev{% endif %}'''
CW_PREFIX = '''{% if get_env(name="CI", default="") == "true" %}[codeweaver]{% elif get_env(name="TERM", default="xterm-256color") == "*truecolor*" %}\033[38;2;181;108;48;m[codeweaver]\033[0m{% else %}\033[38;5;131m[codeweaver]\033[0m{% endif %}'''
# this is a bit redundant but it makes it easier to override in CI environments
MISE_PYTHON_VERSION = '''{{ get_env(name="MISE_PYTHON_VERSION", default="3.13") }}'''
# For the life of me, I can't get mise to use free-threaded python, so we strip the 't' and in CI use 'uv' directly based on `PYTHON_VERSION`
MISE_PYTHON_VERSION = '''{{ get_env(name="MISE_PYTHON_VERSION", default="3.13") | lower | trim_end_matches(pat="t") }}'''
PYTHON_VERSION = '''{{ get_env(name="MISE_PYTHON_VERSION", default="3.13") }}'''
HK_MISE = "1"

[shell_alias]
mx = "mise x"
mr = "mise r"
start-serena = '''uvx -p 3.13.11 --from git+https://github.com/oraios/serena serena start-mcp-server --project {{ get_env(name="CODEWEAVER_PROJECT_PATH", default=exec(command="pwd")) }} --transport streamable-http --port 9121 --host 127.0.0.1'''
start-serena = '''uvx -p 3.13 --from git+https://github.com/oraios/serena serena start-mcp-server --project {{ get_env(name="CODEWEAVER_PROJECT_PATH", default=exec(command="pwd")) }} --transport streamable-http --port 9121 --host 127.0.0.1'''

[settings]
idiomatic_version_file_enable_tools = []
Expand Down Expand Up @@ -84,18 +87,50 @@ echo [codeweaver] CodeWeaver Version: %CODEWEAVER_VERSION%
echo [codeweaver] Project Path: %CODEWEAVER_PROJECT_PATH%
'''

[tasks._special-dependencies]
hide = true
tools.uv = "latest"
run = '''
if [ "$MISE_PYTHON_VERSION" = "3.13" ] || [ "$MISE_PYTHON_VERSION" = "3.14" ]; then
GIL_STATUS="$(uv run python -c 'import sys; print(sys._is_gil_enabled())')"
# If the gil is enabled we can install a couple extras
if [ "$GIL_STATUS" = "True" ]; then
case "$MISE_PYTHON_VERSION" in
3.13)
uv pip install 'pydantic-settings[yaml,toml,aws-secrets-manager,gcp-secret-manager,azure-key-vault]'
;;
3.14)
uv pip install ddgs
;;
esac
fi
fi
'''

[tasks.sync]
depends = ["source"]
tools.uv = "latest"
run = '''
echo "running sync task"
echo "${CW_PREFIX} Syncing dependencies..."
uv sync --extra full --group dev --group docs --group build --group test
if [ "$CODEWEAVER__DEV__USE_GPU" = "true" ]; then
echo "${CW_PREFIX} GPU support enabled. Syncing GPU dependencies..."
mise //:sync-gpu
else
echo "${CW_PREFIX} Syncing CPU dependencies..."
uv sync --python {{ get_env(name='PYTHON_VERSION', default='3.13') }} --extra full --group dev --group docs --group build --group test
fi
mise //:_special-dependencies
'''
run_windows = '''
echo "running sync task"
echo [codeweaver] Syncing dependencies...
uv sync --extra full --group dev --group docs --group build --group test
if "%CODEWEAVER__DEV__USE_GPU%"=="true" (
echo [codeweaver] GPU support enabled. Syncing GPU dependencies...
mise //:sync-gpu
) else (
echo [codeweaver] Syncing dependencies...
uv sync --python {{ get_env(name='PYTHON_VERSION', default='3.13') }} --extra full --group dev --group docs --group build --group test
)
mise //:_special-dependencies
'''

[tasks.sync-gpu]
Expand All @@ -104,8 +139,19 @@ tools.uv = "latest"
run = '''
echo "running sync-gpu task"
echo "${CW_PREFIX} Syncing GPU dependencies..."
uv sync --extra full-gpu --group dev --group docs --group build --group test
uv sync --python {{ get_env(name='PYTHON_VERSION', default='3.13') }} --extra full-gpu --group dev --group docs --group build --group test
mise //:_special-dependencies
'''
run_windows = '''
echo "running sync-gpu task"
echo [codeweaver] Syncing GPU dependencies...
uv sync --python {{ get_env(name='PYTHON_VERSION', default='3.13') }} --extra full-gpu --group dev --group docs --group build --group test
mise //:_special-dependencies
'''

[tasks.sync-gpu.env]
# if you explicitly run the sync-gpu task, we assume you want GPU dependencies regardless of the CODEWEAVER__DEV__USE_GPU setting
CODEWEAVER__DEV__USE_GPU = "true"

[tasks.source]
run = '''
Expand All @@ -116,7 +162,7 @@ echo "${CW_PREFIX} Sourcing virtual environment..."
git rev-parse --show-toplevel || true
if [ ! -d ".venv" ]; then
echo "${CW_PREFIX} ⚠️ \033[0;31mVirtual environment not found. We'll try to proceed, but things may break!\033[0m"
uv venv --seed --keyring-provider subprocess --python {{ get_env(name='MISE_PYTHON_VERSION', default='3.13') }} .venv
uv venv --seed --keyring-provider subprocess --python {{ get_env(name='PYTHON_VERSION', default='3.13') }} .venv
fi
. .venv/bin/activate || echo "${CW_PREFIX} ⚠️ \033[0;31mFailed to source virtual environment.\033[0m"
'''
Expand Down Expand Up @@ -512,16 +558,15 @@ PYTHONPATH = "src"
env.PYTHONPATH = "src"
tools.uv = "latest"
tools.python = '''{{ get_env(name="MISE_PYTHON_VERSION", default="3.13") }}'''
depends = ["sync"] # ensure test dependencies are installed
run = '''
echo "running test-cov task"
echo "${CW_PREFIX} Running tests with coverage..."
uv sync --group test --inexact
uv run pytest tests/ --cov=codeweaver --cov-report=xml --cov-report=term-missing --junit-xml=test-results.xml -v "$@"
'''
run_windows = '''
echo "running test-cov task"
echo [codeweaver] Running tests with coverage...
uv sync --group test --inexact
uv run pytest tests/ --cov=codeweaver --cov-report=xml --cov-report=term-missing --junit-xml=test-results.xml -v %*
'''

Expand Down
63 changes: 34 additions & 29 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ dependencies = [
# lazy import handling; spun off from core/utils/lazy_importer into its own package
"lateimport>=0.1.0",
# retries
"tenacity>=9.1.2",
"tenacity>=9.1.4",
# for local providers (sentence-transformers, fastembed) to detect CPU/GPU features
"py-cpuinfo>=9.0.0",
# * ================ CLI Dependencies ==================*
Expand All @@ -149,7 +149,7 @@ dependencies = [
"fastembed==0.7.4; python_version < '3.14'",
"google-genai==1.56.0",
# NOTE: We're waiting on pydantic-ai to update to 1.0+ before we can upgrade too
"huggingface-hub>=1.7.1",
"huggingface-hub>=1.0.0",
"mistralai==1.10.0",
"openai==2.28.0",
"qdrant-client==1.17.1",
Expand All @@ -169,7 +169,7 @@ dependencies = [
"ast-grep-py>=0.40.3",
# * ================ Server and MCP Server Framework ==================*
# fastmcp is the core MCP server framework
"fastmcp>=2.14.5",
"fastmcp>=2.14.0",
# just used for types but we need them at runtime for Pydantic models
"mcp>=1.23.3",
# Runs the core admin/management server
Expand All @@ -181,7 +181,7 @@ dependencies = [
"tomli-w>=1.2.0",
# * ================ Telemetry and Observability ==================*
# It's telemetry. Our implementation is lightweight and privacy-focused.
"posthog>=7.8.2",
"posthog>=7.9.12",

#! Not yet used, but planned for future releases
# * ================ Future Dependencies ==================*
Expand Down Expand Up @@ -216,38 +216,36 @@ auth-permitio = ["permit-fastmcp"]
# ==== Authentication and Authorization Middleware/Addons ====
# Settings/Config Secrets
aws-secrets-manager = ["pydantic-settings[yaml,toml,aws-secrets-manager]"]
# does NOT support free-threaded python 3.13 (3.14 is OK) due to cffi dependency in azure-identity
azure-key-vault = ["pydantic-settings[yaml,toml,azure-key-vault]"]
bedrock = ["pydantic-ai-slim[bedrock]"]
cohere = ["pydantic-ai-slim[cohere]"]
# ==== Data Sources ====
duckduckgo = ["pydantic-ai-slim[duckduckgo]"]
# duckduckgo relies on primp, which needs maturin. Maturin does not yet support python 3.14 free-threaded builds, so we exclude it from python 3.14 installs for now. If you need duckduckgo support on python 3.14, you can install the ddgs package manually in your environment.
duckduckgo = ["ddgs; python_version < '3.14'"]
exa = ["exa-py"]
fastembed = ["fastembed; python_version < '3.14'", "py-cpuinfo"]
# Requires additional setup, see https://qdrant.github.io/fastembed/examples/FastEmbed_GPU/
fastembed-gpu = ["fastembed-gpu; python_version < '3.14'", "py-cpuinfo"]
# workos AuthKit middleware - see https://gofastmcp.com/integrations/authkit
# No additional dependencies required, it's purely REST-based.
# Enable with environment variables:
# ## Instruct FastMCP to use the AuthKit provider:
# FASTMCP_SERVER_AUTH=AUTHKIT
# configure the AuthKit provider
# FASTMCP_SERVER_AUTH_AUTHKITPROVIDER_AUTHKIT_DOMAIN="https://your-project-12345.authkit.app"
# FASTMCP_SERVER_AUTH_AUTHKITPROVIDER_BASE_URL="http://localhost:8000"
# All groups for users - full featured with all middleware

full = [
"permit-fastmcp",
"ddgs",
"ddgs; python_version < '3.14'",
"eunomia-mcp",
"exa-py",
"pydantic-ai-slim[openai,cohere,google,anthropic,groq,mistral,bedrock,huggingface,retries,xai]",
"pydantic-settings[yaml,toml,aws-secrets-manager,azure-key-vault,gcp-secret-manager]",
# azure-key-vault requires azure-identity, which requires cffi. cffi *does* work on python 3.13, but NOT 3.13 freethreaded
# since we have no way to test for freethreaded builds in pyproject.toml and the build breaks with it, we leave it out.
# If you need azure-key-vault support on python 3.13, you can install the full group and then manually install azure-identity in your environment to get the missing dependency (with vanilla python).
"pydantic-settings[yaml,toml,aws-secrets-manager,gcp-secret-manager]; python_version == '3.13'",
"pydantic-settings[yaml,toml,aws-secrets-manager,gcp-secret-manager,azure-key-vault]; python_version != '3.13'",
"permit-fastmcp",
"sentence-transformers",
"tavily-python",
]
full-gpu = [
"permit-fastmcp",
"ddgs",
"ddgs; python_version < '3.14'",
"eunomia-mcp",
"fastembed-gpu; python_version < '3.14'",
"permit-fastmcp",
Expand Down Expand Up @@ -284,15 +282,15 @@ recommended = [
"tokenizers",
"py-cpuinfo",
"voyageai",
"ddgs",
"ddgs; python_version < '3.14'",
"pydantic-ai-slim[openai,anthropic,retries]",
"tavily",
]
recommended-local-only = [
"fastembed; python_version < '3.14'",
"sentence-transformers",
"tokenizers",
"ddgs",
"ddgs; python_version < '3.14'",
"py-cpuinfo",
# openai for ollama local models
"pydantic-ai-slim[openai,retries]",
Expand Down Expand Up @@ -321,33 +319,33 @@ xai = ["pydantic-ai-slim[xai]"]
[dependency-groups]
dev = [
# black is used to format generated code
"black>=26.1.0",
"ruff>=0.15.2",
"black>=26.3.1",
"ruff>=0.15.6",
"serena>=0.9.1",
"ty>=0.0.18",
"uv>=0.10.5",
"ty>=0.0.23",
"uv>=0.10.11",
]
build = ["hatchling>=1.28.0", "twine>=6.2.0", "uv-dynamic-versioning>=0.12.0"]
dev-helpers = [
"ipython>=9.10.0",
"ipython>=9.11.0",
"jsonlines>=4.0.0",
"memory-profiler>=0.61.0",
"pdbpp>=0.12.1",
"pyperclip>=1.11.0",
"superclaude>=4.2.0",
]
docs = [
"griffe==1.15.0",
"griffe>=2.0.0",
"griffe-pydantic>=1.1.0",
"griffe2md>=0.1.0",
"griffe2md>=1.5.0",
]
test = [
"dirty-equals>=0.11.0",
"hypothesis>=6.151.9",
"pytest>=9.0.2",
"pytest-asyncio>=1.3.0",
"pytest-cov>=7.0.0",
"pytest-env>=1.5.0",
"pytest-env>=1.6.0",
"pytest-examples>=0.0.18",
"pytest-flakefinder>=1.1.0",
"pytest-mock>=3.15.1",
Expand All @@ -357,7 +355,7 @@ test = [

[build-system]
requires = [
"hatchling>=1.28.0",
"hatchling>=1.29.0",
"twine>=6.2.0",
"uv-dynamic-versioning>=0.13.0",
]
Expand Down Expand Up @@ -518,13 +516,17 @@ markers = [
# External dependencies
"real_providers: Tests using actual embedding/vector store providers (not mocks)",
"requires_api_keys: Tests requiring external API credentials and authentication",
"requires_fastembed: Tests requiring fastembed package (not available on Python 3.14+)",
"requires_gpu: Tests requiring GPU hardware for execution",
"requires_models: Tests requiring ML model downloads and local model files",
"requires_voyageai: Tests requiring voyageai package (has pydantic v1 issues on Python 3.14+)",
"retry: Tests that may need retries",
"search: Tests related to search functionality",
"server: Tests related to server functionality",
"services: Tests related to services layer",
"skip_ci: Tests to skip in CI/CD environments",
"skip_on_free_threaded: Tests that should be skipped on free-threaded Python builds",
"skip_on_python_314: Tests that should be skipped on Python 3.14+ due to dependency incompatibilities",
"slow: Tests that take a significant amount of time to run",
"telemetry: Tests related to telemetry and metrics",
"timeout: Tests with specific timeout requirements",
Expand Down Expand Up @@ -752,7 +754,10 @@ unsupported-operator = "ignore"
no-matching-overload = "ignore"

[[tool.ty.overrides]]
include = ["src/codeweaver/__init__.py"]
include = [
"src/codeweaver/__init__.py",
"src/codeweaver/semantic/classifications.py"
]

[tool.ty.overrides.rules]
invalid-assignment = "ignore"
Expand Down
2 changes: 1 addition & 1 deletion scripts/convert_voyage_nano_to_onnx.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def validate_conversion(
print(f" Config: {cast(torch.nn.Model, module).get_config_dict()}")
inputs = tokenizer(
text, padding=True, truncation=True, return_tensors="pt", max_length=32768
)
) # ty:ignore[call-non-callable]
print(f" Tokenizer outputs: {list(inputs.keys())}")
print(f" Tokenized input_ids shape: {inputs['input_ids'].shape}")
for input_name in onnx_model.input_names:
Expand Down
Empty file modified scripts/model_data/hf-models.json
100644 → 100755
Empty file.
Empty file modified scripts/model_data/hf-models.json.license
100644 → 100755
Empty file.
Empty file modified scripts/model_data/mteb_to_codeweaver.py
100644 → 100755
Empty file.
Empty file modified scripts/model_data/secondary_providers.json
100644 → 100755
Empty file.
Empty file modified scripts/model_data/secondary_providers.json.license
100644 → 100755
Empty file.
2 changes: 1 addition & 1 deletion src/codeweaver/core/chunks.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ def serialize_for_embedding(self) -> str:
k: v for k, v in self.metadata.items() if k in ("name", "tags", "semantic_meta")
}
):
data["metadata"] = metadata
data["metadata"] = metadata # ty:ignore[invalid-assignment]

# Use pydantic_core.to_json for fast, reliable serialization
return to_json({k: v for k, v in data.items() if v is not None}).decode("utf-8")
Expand Down
2 changes: 1 addition & 1 deletion src/codeweaver/core/di/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ async def resolve(
if self._is_union_type(interface):
instance = await self._resolve_union_interface(interface, cache_key, _resolution_stack)
return cast(T, instance)
elif interface is type(None):
if interface is type(None):
return cast(T, None)

# 1. Check overrides first
Expand Down
2 changes: 1 addition & 1 deletion src/codeweaver/core/types/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class EnvVarInfo(NamedTuple):
choices: set[str] | None = None
variable_name: str | None = None
"""The name of the variable as used by the provider's **client**, if different from `env`."""
variables: NotRequired[tuple[VariableInfo, ...]] = ()
variables: tuple[VariableInfo, ...] = ()
"""The variables that this environment variable can configure. Use for situations where an env var does not map to the client directly or configures multiple variables."""
resolver_key: str | None = None
"""Optional key for the resolver to deconflict multiple config sources."""
Expand Down
8 changes: 4 additions & 4 deletions src/codeweaver/core/types/service_cards.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,8 @@ class ServiceMetadata(NamedTuple):
"""

client_handler: (
Callable[[Any, ServiceCard, ...], Any]
| Callable[[Any, ServiceCard, ...], Coroutine[Any, Any, Any]]
Callable[..., Any]
| Callable[..., Coroutine[Any, Any, Any]]
| None
) = None
"""Custom instantiation handler for the SDK client.
Expand All @@ -363,8 +363,8 @@ class ServiceMetadata(NamedTuple):
"""

provider_handler: (
Callable[[Any, ServiceCard, ...], Any]
| Callable[[Any, ServiceCard, ...], Coroutine[Any, Any, Any]]
Callable[..., Any]
| Callable[..., Coroutine[Any, Any, Any]]
| None
) = None
Comment thread
bashandbone marked this conversation as resolved.
"""Custom instantiation handler for the provider wrapper.
Expand Down
Loading
Loading