Repository navigation
Expand file tree
/
Copy pathpyproject.toml
More file actions
103 lines (98 loc) · 4.96 KB
/
Copy pathpyproject.toml
File metadata and controls
103 lines (98 loc) · 4.96 KB
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
[project]
name = "nerve"
version = "0.1.0"
description = "Personal AI assistant — lightweight, single-process, purpose-built"
readme = "README.md"
# 3.13, not 3.12: the pinned memu-py==1.4.0 requires >=3.13, so a 3.12 install
# has never actually been resolvable — `uv pip install -e .` on 3.12 fails
# outright. This says what was already true, and gives 3.12 users a clear error
# instead of a confusing transitive dependency conflict.
requires-python = ">=3.13"
license = { text = "Apache-2.0" }
dependencies = [
"fastapi>=0.115.0",
"uvicorn[standard]>=0.34.0",
"aiosqlite>=0.21.0",
"pyyaml>=6.0",
"python-telegram-bot>=21.0",
"slack-sdk>=3.33.0",
# Socket Mode's asyncio client is the aiohttp one; slack-sdk leaves the
# transport dependency to the caller.
"aiohttp>=3.10",
# Floor raised from 0.2.82 for mcp 2.x: 0.2.140 is the first release whose
# own constraint is `mcp<3.0.0` (0.2.100 through 0.2.139 all declare
# `mcp<2.0.0`). It matters because the SDK builds the in-process MCP server
# that serves EVERY agent tool, so an SDK without 2.x support breaks the
# whole Claude backend, not just /mcp/v1. 0.2.82 is the dangerous case: it
# declares `mcp>=1.23.0` with no upper bound, so `0.2.82 + mcp 2.x` is a
# resolvable combination that cannot work.
# Floor raised again to 0.2.150 for the bundled CLI. The SDK spawns its own
# `_bundled/claude` in preference to anything on PATH, so the CLI it ships
# is the one every session actually runs: 0.2.140 bundles 2.1.235, which
# rejects models released after it with "does not support this model;
# version 2.1.251 or newer is required". 0.2.150 bundles 2.1.257. Every
# release in 0.2.141..0.2.150 is a CLI-bundle bump only — no API change.
"claude-agent-sdk>=0.2.158",
# Declared explicitly because nerve/mcp_server/ imports `mcp` directly
# rather than only through claude-agent-sdk. Both bounds are load-bearing:
# nerve/mcp_server/ is written against the 2.x lowlevel API (constructor
# callbacks, request context as a handler argument), which does not exist
# in 1.x, and 3.x has not been vetted.
"mcp>=2,<3",
# Used directly by nerve/mcp_server/server.py to validate tool arguments
# against each tool's inputSchema. mcp 1.x's call_tool decorator did this
# for us; the 2.x callback does not, so the check is ours now and the
# dependency is declared rather than borrowed from claude-agent-sdk.
"jsonschema>=4.20",
"apscheduler>=3.11.0",
# The crypto extra brings `cryptography`, which ES256 needs: hosted
# channel streams are authenticated with control plane workload identity
# tokens signed with P-256 keys.
"pyjwt[crypto]>=2.10.1",
"bcrypt>=4.2.0",
"httpx>=0.28.0",
"websockets>=14.0",
"click>=8.1.0",
"telethon>=1.38.0",
# [bedrock] pulls boto3/botocore, required by AnthropicBedrock for AWS SigV4
# request signing (session title generation and other direct-SDK fast-model calls).
"anthropic[bedrock]>=0.45.0", # used by memu_bridge for event date resolution
"memu-py==1.4.0", # pinned — nerve monkey-patches memU internals (see memu_bridge._patch_sqlite_bugs)
"watchfiles>=1.0.0",
"html2text>=2024.2.26",
# Optional xmemory.ai structured-memory layer — only active when an
# xmemory api_key + instance_id are configured (see XmemoryConfig).
"xmemory-ai>=0.10.0",
# Optional observability stack — only active when langfuse keys are
# configured. All three are pure-Python wheels.
"langfuse>=3.0.0",
"langsmith[claude-agent-sdk]>=0.4.0",
"opentelemetry-instrumentation-anthropic>=0.40.0",
]
[project.optional-dependencies]
# Test/dev dependencies. Install with: uv sync --extra test
# Upper bounds guard CI against surprise major-version breaks (notably the
# pytest-asyncio 1.x event_loop changes the suite's conftest relies on).
test = [
"pytest>=8,<10",
"pytest-asyncio>=0.24,<2",
]
[project.scripts]
nerve = "nerve.cli:main"
[build-system]
# Bounded, not bare: uv.lock pins runtime dependencies but build backends are
# resolved fresh in an isolated build environment on every install, so an
# unpinned backend is a hole in "reproducible install". A major bound stops the
# breaking-change class; exact pinning would need --build-constraint, which the
# plain-pip path wouldn't honour anyway.
requires = ["hatchling>=1.27,<2"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
# `packages` already takes everything under nerve/, nerve/templates/ included,
# so there is no force-include here: adding that subtree a second time is what
# hatchling rejects with "A second file is being added to the wheel archive at
# the same path", which made the wheel unbuildable and `pip install` from git
# impossible. Nothing caught it because every documented install is `pip install
# -e .` from a clone and CI installs the same way, so no wheel was ever built
# until the config-repo validation workflow needed one.
packages = ["nerve"]