agentic-data-contracts 0.2.1__tar.gz → 0.2.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.
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/CHANGELOG.md +17 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/PKG-INFO +8 -7
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/README.md +5 -4
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/docs/architecture.md +1 -1
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/pyproject.toml +2 -2
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/__init__.py +7 -1
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/core/contract.py +15 -0
- agentic_data_contracts-0.2.3/src/agentic_data_contracts/tools/sdk.py +71 -0
- agentic_data_contracts-0.2.3/tests/test_core/test_sdk_config.py +36 -0
- agentic_data_contracts-0.2.3/tests/test_tools/test_sdk.py +116 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/uv.lock +9 -9
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/.github/dependabot.yml +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/.github/workflows/ci.yml +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/.gitignore +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/.pre-commit-config.yaml +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/.python-version +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/CLAUDE.md +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/LICENSE +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/examples/revenue_agent/agent.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/examples/revenue_agent/contract.yml +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/examples/revenue_agent/semantic.yml +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/examples/revenue_agent/setup_db.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/adapters/__init__.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/adapters/base.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/adapters/duckdb.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/bridge/__init__.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/bridge/compiler.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/core/__init__.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/core/schema.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/core/session.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/py.typed +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/semantic/__init__.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/semantic/base.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/semantic/cube.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/semantic/dbt.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/semantic/yaml_source.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/tools/__init__.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/tools/factory.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/tools/middleware.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/validation/__init__.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/validation/checkers.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/validation/explain.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/validation/validator.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/__init__.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/conftest.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/fixtures/minimal_contract.yml +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/fixtures/sample_cube_schema.yml +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/fixtures/sample_dbt_manifest.json +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/fixtures/semantic_source.yml +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/fixtures/valid_contract.yml +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_adapters/__init__.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_adapters/test_duckdb.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_bridge/__init__.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_bridge/test_compiler.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_core/__init__.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_core/test_contract.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_core/test_load_semantic_source.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_core/test_schema.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_core/test_session.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_core/test_system_prompt_metrics.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_public_api.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_semantic/__init__.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_semantic/test_cube.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_semantic/test_dbt.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_semantic/test_search.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_semantic/test_yaml_source.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_tools/__init__.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_tools/test_auto_load.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_tools/test_factory.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_tools/test_middleware.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_tools/test_semantic_tools.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_validation/__init__.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_validation/test_checkers.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_validation/test_explain.py +0 -0
- {agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_validation/test_validator.py +0 -0
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.2.3] - 2026-03-29
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **SDK MCP server convenience method**: `create_sdk_mcp_server(contract, adapter=...)` wraps all 10 tools with the SDK's `@tool` decorator and bundles them into a ready-to-use MCP server for `ClaudeAgentOptions.mcp_servers`
|
|
10
|
+
- **Top-level export**: `from agentic_data_contracts import create_sdk_mcp_server`
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **SDK dependency**: Bumped `claude-agent-sdk` minimum to `>=0.1.52`
|
|
15
|
+
|
|
16
|
+
## [0.2.2] - 2026-03-28
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- **SDK config generation**: `DataContract.to_sdk_config()` maps contract limits to Claude Agent SDK options (`token_budget` → `task_budget`, `max_retries` → `max_turns`)
|
|
21
|
+
|
|
5
22
|
## [0.2.1] - 2026-03-28
|
|
6
23
|
|
|
7
24
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentic-data-contracts
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: YAML-first data contract governance for AI agents
|
|
5
5
|
Project-URL: Homepage, https://github.com/flyersworder/agentic-data-contracts
|
|
6
6
|
Project-URL: Repository, https://github.com/flyersworder/agentic-data-contracts
|
|
@@ -27,10 +27,10 @@ Requires-Dist: thefuzz>=0.22.1
|
|
|
27
27
|
Provides-Extra: agent-contracts
|
|
28
28
|
Requires-Dist: ai-agent-contracts>=0.2.0; extra == 'agent-contracts'
|
|
29
29
|
Provides-Extra: agent-sdk
|
|
30
|
-
Requires-Dist: claude-agent-sdk; extra == 'agent-sdk'
|
|
30
|
+
Requires-Dist: claude-agent-sdk>=0.1.52; extra == 'agent-sdk'
|
|
31
31
|
Provides-Extra: all
|
|
32
32
|
Requires-Dist: ai-agent-contracts>=0.2.0; extra == 'all'
|
|
33
|
-
Requires-Dist: claude-agent-sdk; extra == 'all'
|
|
33
|
+
Requires-Dist: claude-agent-sdk>=0.1.52; extra == 'all'
|
|
34
34
|
Requires-Dist: duckdb; extra == 'all'
|
|
35
35
|
Requires-Dist: google-cloud-bigquery; extra == 'all'
|
|
36
36
|
Requires-Dist: psycopg2-binary; extra == 'all'
|
|
@@ -150,25 +150,26 @@ adapter = DuckDBAdapter("analytics.duckdb")
|
|
|
150
150
|
tools = create_tools(dc, adapter=adapter)
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
-
### 3. Use with the Claude Agent SDK
|
|
153
|
+
### 3. Use with the Claude Agent SDK (requires `claude-agent-sdk>=0.1.52`)
|
|
154
154
|
|
|
155
155
|
```python
|
|
156
156
|
import asyncio
|
|
157
|
+
from agentic_data_contracts import create_sdk_mcp_server
|
|
157
158
|
from claude_agent_sdk import (
|
|
158
159
|
ClaudeAgentOptions,
|
|
159
160
|
AssistantMessage,
|
|
160
161
|
TextBlock,
|
|
161
|
-
create_sdk_mcp_server,
|
|
162
162
|
query,
|
|
163
163
|
)
|
|
164
164
|
|
|
165
|
-
|
|
165
|
+
# One-liner: wraps all 10 tools and bundles into an SDK MCP server
|
|
166
|
+
server = create_sdk_mcp_server(dc, adapter=adapter)
|
|
166
167
|
|
|
167
168
|
options = ClaudeAgentOptions(
|
|
168
169
|
model="claude-sonnet-4-6",
|
|
169
170
|
system_prompt=f"You are a revenue analytics assistant.\n\n{dc.to_system_prompt()}",
|
|
170
171
|
mcp_servers={"dc": server},
|
|
171
|
-
|
|
172
|
+
**dc.to_sdk_config(), # token_budget → task_budget, max_retries → max_turns
|
|
172
173
|
)
|
|
173
174
|
|
|
174
175
|
async def run(prompt: str) -> None:
|
|
@@ -97,25 +97,26 @@ adapter = DuckDBAdapter("analytics.duckdb")
|
|
|
97
97
|
tools = create_tools(dc, adapter=adapter)
|
|
98
98
|
```
|
|
99
99
|
|
|
100
|
-
### 3. Use with the Claude Agent SDK
|
|
100
|
+
### 3. Use with the Claude Agent SDK (requires `claude-agent-sdk>=0.1.52`)
|
|
101
101
|
|
|
102
102
|
```python
|
|
103
103
|
import asyncio
|
|
104
|
+
from agentic_data_contracts import create_sdk_mcp_server
|
|
104
105
|
from claude_agent_sdk import (
|
|
105
106
|
ClaudeAgentOptions,
|
|
106
107
|
AssistantMessage,
|
|
107
108
|
TextBlock,
|
|
108
|
-
create_sdk_mcp_server,
|
|
109
109
|
query,
|
|
110
110
|
)
|
|
111
111
|
|
|
112
|
-
|
|
112
|
+
# One-liner: wraps all 10 tools and bundles into an SDK MCP server
|
|
113
|
+
server = create_sdk_mcp_server(dc, adapter=adapter)
|
|
113
114
|
|
|
114
115
|
options = ClaudeAgentOptions(
|
|
115
116
|
model="claude-sonnet-4-6",
|
|
116
117
|
system_prompt=f"You are a revenue analytics assistant.\n\n{dc.to_system_prompt()}",
|
|
117
118
|
mcp_servers={"dc": server},
|
|
118
|
-
|
|
119
|
+
**dc.to_sdk_config(), # token_budget → task_budget, max_retries → max_turns
|
|
119
120
|
)
|
|
120
121
|
|
|
121
122
|
async def run(prompt: str) -> None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "agentic-data-contracts"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.3"
|
|
4
4
|
description = "YAML-first data contract governance for AI agents"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -41,7 +41,7 @@ Issues = "https://github.com/flyersworder/agentic-data-contracts/issues"
|
|
|
41
41
|
Documentation = "https://github.com/flyersworder/agentic-data-contracts/blob/main/docs/architecture.md"
|
|
42
42
|
|
|
43
43
|
[project.optional-dependencies]
|
|
44
|
-
agent-sdk = ["claude-agent-sdk"]
|
|
44
|
+
agent-sdk = ["claude-agent-sdk>=0.1.52"]
|
|
45
45
|
agent-contracts = ["ai-agent-contracts>=0.2.0"]
|
|
46
46
|
bigquery = ["google-cloud-bigquery"]
|
|
47
47
|
snowflake = ["snowflake-connector-python"]
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/__init__.py
RENAMED
|
@@ -3,5 +3,11 @@
|
|
|
3
3
|
from agentic_data_contracts.core.contract import DataContract
|
|
4
4
|
from agentic_data_contracts.tools.factory import create_tools
|
|
5
5
|
from agentic_data_contracts.tools.middleware import contract_middleware
|
|
6
|
+
from agentic_data_contracts.tools.sdk import create_sdk_mcp_server
|
|
6
7
|
|
|
7
|
-
__all__ = [
|
|
8
|
+
__all__ = [
|
|
9
|
+
"DataContract",
|
|
10
|
+
"create_tools",
|
|
11
|
+
"contract_middleware",
|
|
12
|
+
"create_sdk_mcp_server",
|
|
13
|
+
]
|
|
@@ -60,6 +60,21 @@ class DataContract:
|
|
|
60
60
|
r for r in self.schema.semantic.rules if r.enforcement == Enforcement.LOG
|
|
61
61
|
]
|
|
62
62
|
|
|
63
|
+
def to_sdk_config(self) -> dict[str, object]:
|
|
64
|
+
"""Generate Claude Agent SDK configuration from contract limits.
|
|
65
|
+
|
|
66
|
+
Returns a dict of SDK options derived from contract resource/temporal
|
|
67
|
+
constraints, suitable for passing to ClaudeAgentOptions.
|
|
68
|
+
"""
|
|
69
|
+
config: dict[str, object] = {}
|
|
70
|
+
res = self.schema.resources
|
|
71
|
+
if res:
|
|
72
|
+
if res.token_budget is not None:
|
|
73
|
+
config["task_budget"] = res.token_budget
|
|
74
|
+
if res.max_retries is not None:
|
|
75
|
+
config["max_turns"] = res.max_retries
|
|
76
|
+
return config
|
|
77
|
+
|
|
63
78
|
def load_semantic_source(self) -> SemanticSource | None:
|
|
64
79
|
"""Auto-load the semantic source from the contract's source config.
|
|
65
80
|
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""Claude Agent SDK integration — wraps ToolDefs into an SDK MCP server."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from agentic_data_contracts.adapters.base import DatabaseAdapter
|
|
8
|
+
from agentic_data_contracts.core.contract import DataContract
|
|
9
|
+
from agentic_data_contracts.core.session import ContractSession
|
|
10
|
+
from agentic_data_contracts.semantic.base import SemanticSource
|
|
11
|
+
from agentic_data_contracts.tools.factory import ToolDef, create_tools
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def create_sdk_mcp_server(
|
|
15
|
+
contract: DataContract,
|
|
16
|
+
*,
|
|
17
|
+
adapter: DatabaseAdapter | None = None,
|
|
18
|
+
semantic_source: SemanticSource | None = None,
|
|
19
|
+
session: ContractSession | None = None,
|
|
20
|
+
tools: list[ToolDef] | None = None,
|
|
21
|
+
server_name: str = "data-contracts",
|
|
22
|
+
server_version: str = "1.0.0",
|
|
23
|
+
) -> Any:
|
|
24
|
+
"""Create a Claude Agent SDK MCP server from a DataContract.
|
|
25
|
+
|
|
26
|
+
Wraps all 10 contract tools with the SDK's @tool decorator and
|
|
27
|
+
bundles them into an MCP server ready for ClaudeAgentOptions.mcp_servers.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
contract: The data contract to enforce.
|
|
31
|
+
adapter: Optional database adapter for query execution.
|
|
32
|
+
semantic_source: Optional semantic source (auto-loaded if not given).
|
|
33
|
+
session: Optional session for tracking enforcement state.
|
|
34
|
+
tools: Pre-built ToolDefs (if None, created via create_tools).
|
|
35
|
+
server_name: Name for the MCP server.
|
|
36
|
+
server_version: Version for the MCP server.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
McpSdkServerConfig ready for ClaudeAgentOptions.mcp_servers.
|
|
40
|
+
|
|
41
|
+
Raises:
|
|
42
|
+
ImportError: If claude-agent-sdk is not installed.
|
|
43
|
+
"""
|
|
44
|
+
try:
|
|
45
|
+
from claude_agent_sdk import create_sdk_mcp_server as _create_server
|
|
46
|
+
from claude_agent_sdk import tool as sdk_tool
|
|
47
|
+
except ImportError:
|
|
48
|
+
msg = (
|
|
49
|
+
"claude-agent-sdk is required for SDK integration. "
|
|
50
|
+
"Install with: pip install agentic-data-contracts[agent-sdk]"
|
|
51
|
+
)
|
|
52
|
+
raise ImportError(msg) from None
|
|
53
|
+
|
|
54
|
+
if tools is None:
|
|
55
|
+
tools = create_tools(
|
|
56
|
+
contract,
|
|
57
|
+
adapter=adapter,
|
|
58
|
+
semantic_source=semantic_source,
|
|
59
|
+
session=session,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
sdk_tools = []
|
|
63
|
+
for t in tools:
|
|
64
|
+
decorated = sdk_tool(t.name, t.description, t.input_schema)(t.callable)
|
|
65
|
+
sdk_tools.append(decorated)
|
|
66
|
+
|
|
67
|
+
return _create_server(
|
|
68
|
+
name=server_name,
|
|
69
|
+
version=server_version,
|
|
70
|
+
tools=sdk_tools,
|
|
71
|
+
)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""Tests for DataContract.to_sdk_config()."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from agentic_data_contracts.core.contract import DataContract
|
|
6
|
+
from agentic_data_contracts.core.schema import (
|
|
7
|
+
DataContractSchema,
|
|
8
|
+
ResourceConfig,
|
|
9
|
+
SemanticConfig,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test_sdk_config_from_full_contract(fixtures_dir: Path) -> None:
|
|
14
|
+
dc = DataContract.from_yaml(fixtures_dir / "valid_contract.yml")
|
|
15
|
+
config = dc.to_sdk_config()
|
|
16
|
+
assert config["task_budget"] == 50000
|
|
17
|
+
assert config["max_turns"] == 3
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_sdk_config_no_resources() -> None:
|
|
21
|
+
schema = DataContractSchema(name="test", semantic=SemanticConfig())
|
|
22
|
+
dc = DataContract(schema)
|
|
23
|
+
config = dc.to_sdk_config()
|
|
24
|
+
assert config == {}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_sdk_config_partial_resources() -> None:
|
|
28
|
+
schema = DataContractSchema(
|
|
29
|
+
name="test",
|
|
30
|
+
semantic=SemanticConfig(),
|
|
31
|
+
resources=ResourceConfig(token_budget=10000),
|
|
32
|
+
)
|
|
33
|
+
dc = DataContract(schema)
|
|
34
|
+
config = dc.to_sdk_config()
|
|
35
|
+
assert config["task_budget"] == 10000
|
|
36
|
+
assert "max_turns" not in config
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""Tests for Claude Agent SDK MCP server integration."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from agentic_data_contracts.adapters.duckdb import DuckDBAdapter
|
|
8
|
+
from agentic_data_contracts.core.contract import DataContract
|
|
9
|
+
from agentic_data_contracts.core.schema import (
|
|
10
|
+
AllowedTable,
|
|
11
|
+
DataContractSchema,
|
|
12
|
+
SemanticConfig,
|
|
13
|
+
)
|
|
14
|
+
from agentic_data_contracts.tools.factory import create_tools
|
|
15
|
+
from agentic_data_contracts.tools.sdk import create_sdk_mcp_server
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@pytest.fixture
|
|
19
|
+
def contract_no_source() -> DataContract:
|
|
20
|
+
"""Contract without a semantic source — avoids file path issues."""
|
|
21
|
+
schema = DataContractSchema(
|
|
22
|
+
name="test",
|
|
23
|
+
semantic=SemanticConfig(
|
|
24
|
+
allowed_tables=[
|
|
25
|
+
AllowedTable.model_validate(
|
|
26
|
+
{"schema": "analytics", "tables": ["orders"]}
|
|
27
|
+
),
|
|
28
|
+
],
|
|
29
|
+
),
|
|
30
|
+
)
|
|
31
|
+
return DataContract(schema)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@pytest.fixture
|
|
35
|
+
def contract_with_source(fixtures_dir: Path) -> DataContract:
|
|
36
|
+
"""Contract with semantic source pointing to real fixture."""
|
|
37
|
+
from agentic_data_contracts.core.schema import (
|
|
38
|
+
SemanticSource as SemanticSourceConfig,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
schema = DataContractSchema(
|
|
42
|
+
name="test",
|
|
43
|
+
semantic=SemanticConfig(
|
|
44
|
+
source=SemanticSourceConfig(
|
|
45
|
+
type="yaml",
|
|
46
|
+
path=str(fixtures_dir / "semantic_source.yml"),
|
|
47
|
+
),
|
|
48
|
+
allowed_tables=[
|
|
49
|
+
AllowedTable.model_validate(
|
|
50
|
+
{"schema": "analytics", "tables": ["orders"]}
|
|
51
|
+
),
|
|
52
|
+
],
|
|
53
|
+
),
|
|
54
|
+
)
|
|
55
|
+
return DataContract(schema)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@pytest.fixture
|
|
59
|
+
def adapter() -> DuckDBAdapter:
|
|
60
|
+
db = DuckDBAdapter(":memory:")
|
|
61
|
+
db.connection.execute(
|
|
62
|
+
"""
|
|
63
|
+
CREATE SCHEMA IF NOT EXISTS analytics;
|
|
64
|
+
CREATE TABLE analytics.orders (
|
|
65
|
+
id INTEGER, amount DECIMAL(10,2), tenant_id VARCHAR
|
|
66
|
+
);
|
|
67
|
+
INSERT INTO analytics.orders VALUES (1, 100.00, 'acme');
|
|
68
|
+
"""
|
|
69
|
+
)
|
|
70
|
+
return db
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def test_create_sdk_mcp_server_returns_config(
|
|
74
|
+
contract_no_source: DataContract, adapter: DuckDBAdapter
|
|
75
|
+
) -> None:
|
|
76
|
+
server = create_sdk_mcp_server(contract_no_source, adapter=adapter)
|
|
77
|
+
assert server is not None
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_create_sdk_mcp_server_with_prebuilt_tools(
|
|
81
|
+
contract_no_source: DataContract, adapter: DuckDBAdapter
|
|
82
|
+
) -> None:
|
|
83
|
+
tools = create_tools(contract_no_source, adapter=adapter)
|
|
84
|
+
server = create_sdk_mcp_server(contract_no_source, tools=tools)
|
|
85
|
+
assert server is not None
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def test_create_sdk_mcp_server_with_semantic_source(
|
|
89
|
+
contract_with_source: DataContract, adapter: DuckDBAdapter
|
|
90
|
+
) -> None:
|
|
91
|
+
server = create_sdk_mcp_server(contract_with_source, adapter=adapter)
|
|
92
|
+
assert server is not None
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def test_create_sdk_mcp_server_auto_creates_tools(
|
|
96
|
+
contract_no_source: DataContract,
|
|
97
|
+
) -> None:
|
|
98
|
+
server = create_sdk_mcp_server(contract_no_source)
|
|
99
|
+
assert server is not None
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def test_create_sdk_mcp_server_custom_name(
|
|
103
|
+
contract_no_source: DataContract,
|
|
104
|
+
) -> None:
|
|
105
|
+
server = create_sdk_mcp_server(
|
|
106
|
+
contract_no_source,
|
|
107
|
+
server_name="my-server",
|
|
108
|
+
server_version="2.0.0",
|
|
109
|
+
)
|
|
110
|
+
assert server is not None
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def test_top_level_import() -> None:
|
|
114
|
+
from agentic_data_contracts import create_sdk_mcp_server as fn
|
|
115
|
+
|
|
116
|
+
assert fn is not None
|
|
@@ -9,7 +9,7 @@ resolution-markers = [
|
|
|
9
9
|
|
|
10
10
|
[[package]]
|
|
11
11
|
name = "agentic-data-contracts"
|
|
12
|
-
version = "0.2.
|
|
12
|
+
version = "0.2.3"
|
|
13
13
|
source = { editable = "." }
|
|
14
14
|
dependencies = [
|
|
15
15
|
{ name = "pydantic" },
|
|
@@ -57,7 +57,7 @@ snowflake = [
|
|
|
57
57
|
requires-dist = [
|
|
58
58
|
{ name = "agentic-data-contracts", extras = ["agent-sdk", "agent-contracts", "bigquery", "snowflake", "postgres", "duckdb"], marker = "extra == 'all'" },
|
|
59
59
|
{ name = "ai-agent-contracts", marker = "extra == 'agent-contracts'", specifier = ">=0.2.0" },
|
|
60
|
-
{ name = "claude-agent-sdk", marker = "extra == 'agent-sdk'" },
|
|
60
|
+
{ name = "claude-agent-sdk", marker = "extra == 'agent-sdk'", specifier = ">=0.1.52" },
|
|
61
61
|
{ name = "duckdb", marker = "extra == 'dev'" },
|
|
62
62
|
{ name = "duckdb", marker = "extra == 'duckdb'" },
|
|
63
63
|
{ name = "google-cloud-bigquery", marker = "extra == 'bigquery'" },
|
|
@@ -412,19 +412,19 @@ wheels = [
|
|
|
412
412
|
|
|
413
413
|
[[package]]
|
|
414
414
|
name = "claude-agent-sdk"
|
|
415
|
-
version = "0.1.
|
|
415
|
+
version = "0.1.52"
|
|
416
416
|
source = { registry = "https://pypi.org/simple" }
|
|
417
417
|
dependencies = [
|
|
418
418
|
{ name = "anyio" },
|
|
419
419
|
{ name = "mcp" },
|
|
420
420
|
]
|
|
421
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
421
|
+
sdist = { url = "https://files.pythonhosted.org/packages/b1/d7/a56b7ba793918e5cc557447b25f2d428e11d6f025b6c0c7b1e6e3fa373c0/claude_agent_sdk-0.1.52.tar.gz", hash = "sha256:c27f35d850521c7cff18448b38ff0dd5e899a4aeb6de9d28c0b2a66863eaf134", size = 116267, upload-time = "2026-03-29T02:40:25.554Z" }
|
|
422
422
|
wheels = [
|
|
423
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
424
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
425
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
426
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
427
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
423
|
+
{ url = "https://files.pythonhosted.org/packages/31/e0/6759f98c699ef5da84750b93de543a839f3e3b905b5ce20424a5033c58fa/claude_agent_sdk-0.1.52-py3-none-macosx_11_0_arm64.whl", hash = "sha256:0f15c91319c20831f881fd4b6bcec1772a3599d66da5e7c057d79945bf603e1a", size = 57872944, upload-time = "2026-03-29T02:40:28.742Z" },
|
|
424
|
+
{ url = "https://files.pythonhosted.org/packages/cd/e8/d3c3ef7cb104d3ebb6348a82eab7574b8c0eaddb683efd3f606f3c22bc21/claude_agent_sdk-0.1.52-py3-none-macosx_11_0_x86_64.whl", hash = "sha256:f32ca2ca95e312678af63ee60a5fb1b765f98ed47825ea3ba90322ceb26736ff", size = 59615855, upload-time = "2026-03-29T02:40:31.765Z" },
|
|
425
|
+
{ url = "https://files.pythonhosted.org/packages/f0/b7/2c4def1c5c67b9bad8966b8839d6d9da812a6458050650dbaba3526d3824/claude_agent_sdk-0.1.52-py3-none-manylinux_2_17_aarch64.whl", hash = "sha256:97c238fda13f0bea057e546895a3dc67468fc1acdbbc00d0b53a46cb3ba588dc", size = 71217617, upload-time = "2026-03-29T02:40:35.127Z" },
|
|
426
|
+
{ url = "https://files.pythonhosted.org/packages/44/9e/4be542b58610bd74056dfed37dbdc5a12224a2fbde41a333ddbcd8255a8a/claude_agent_sdk-0.1.52-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:4cd3f2e6fd5b272b16114fbc8dcd4348cbe8615dcc1b3bea251a7d489bf83a5d", size = 71292911, upload-time = "2026-03-29T02:40:38.919Z" },
|
|
427
|
+
{ url = "https://files.pythonhosted.org/packages/93/73/4601d43d57354bd6e664444970bd5c1de8003542745a4388cf84611c9f26/claude_agent_sdk-0.1.52-py3-none-win_amd64.whl", hash = "sha256:a8a5455d248b76c17126abee0f69d0f9870cbc0d52cb2f8ad5eb3deddb05af39", size = 73447753, upload-time = "2026-03-29T02:40:42.786Z" },
|
|
428
428
|
]
|
|
429
429
|
|
|
430
430
|
[[package]]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/examples/revenue_agent/agent.py
RENAMED
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/examples/revenue_agent/contract.yml
RENAMED
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/examples/revenue_agent/semantic.yml
RENAMED
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/examples/revenue_agent/setup_db.py
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
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/src/agentic_data_contracts/py.typed
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
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/fixtures/minimal_contract.yml
RENAMED
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/fixtures/sample_cube_schema.yml
RENAMED
|
File without changes
|
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/fixtures/semantic_source.yml
RENAMED
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/fixtures/valid_contract.yml
RENAMED
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_adapters/__init__.py
RENAMED
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_adapters/test_duckdb.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_bridge/test_compiler.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_core/test_contract.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_core/test_schema.py
RENAMED
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_core/test_session.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_semantic/__init__.py
RENAMED
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_semantic/test_cube.py
RENAMED
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_semantic/test_dbt.py
RENAMED
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_semantic/test_search.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_tools/test_auto_load.py
RENAMED
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_tools/test_factory.py
RENAMED
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_tools/test_middleware.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_validation/__init__.py
RENAMED
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_validation/test_checkers.py
RENAMED
|
File without changes
|
{agentic_data_contracts-0.2.1 → agentic_data_contracts-0.2.3}/tests/test_validation/test_explain.py
RENAMED
|
File without changes
|
|
File without changes
|