neural-context-protocol 0.1.0a1__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.
Files changed (61) hide show
  1. neural_context_protocol-0.1.0a1/PKG-INFO +242 -0
  2. neural_context_protocol-0.1.0a1/README.md +192 -0
  3. neural_context_protocol-0.1.0a1/ncp/__init__.py +35 -0
  4. neural_context_protocol-0.1.0a1/ncp/adapters/__init__.py +2 -0
  5. neural_context_protocol-0.1.0a1/ncp/adapters/anthropic.py +64 -0
  6. neural_context_protocol-0.1.0a1/ncp/adapters/base.py +76 -0
  7. neural_context_protocol-0.1.0a1/ncp/adapters/cohere.py +48 -0
  8. neural_context_protocol-0.1.0a1/ncp/adapters/gemini.py +39 -0
  9. neural_context_protocol-0.1.0a1/ncp/adapters/local.py +27 -0
  10. neural_context_protocol-0.1.0a1/ncp/adapters/mistral.py +46 -0
  11. neural_context_protocol-0.1.0a1/ncp/adapters/ollama.py +53 -0
  12. neural_context_protocol-0.1.0a1/ncp/adapters/openai.py +84 -0
  13. neural_context_protocol-0.1.0a1/ncp/api.py +210 -0
  14. neural_context_protocol-0.1.0a1/ncp/assembler.py +347 -0
  15. neural_context_protocol-0.1.0a1/ncp/benchmarks.py +269 -0
  16. neural_context_protocol-0.1.0a1/ncp/chunker.py +223 -0
  17. neural_context_protocol-0.1.0a1/ncp/cli.py +233 -0
  18. neural_context_protocol-0.1.0a1/ncp/coherence.py +101 -0
  19. neural_context_protocol-0.1.0a1/ncp/config.py +143 -0
  20. neural_context_protocol-0.1.0a1/ncp/costs.py +51 -0
  21. neural_context_protocol-0.1.0a1/ncp/dogfood.py +1351 -0
  22. neural_context_protocol-0.1.0a1/ncp/encoder.py +121 -0
  23. neural_context_protocol-0.1.0a1/ncp/hooks/__init__.py +2 -0
  24. neural_context_protocol-0.1.0a1/ncp/mcp/__init__.py +0 -0
  25. neural_context_protocol-0.1.0a1/ncp/mcp/server.py +537 -0
  26. neural_context_protocol-0.1.0a1/ncp/middleware/__init__.py +13 -0
  27. neural_context_protocol-0.1.0a1/ncp/middleware/base.py +88 -0
  28. neural_context_protocol-0.1.0a1/ncp/middleware/cost_tracking.py +45 -0
  29. neural_context_protocol-0.1.0a1/ncp/middleware/logging.py +67 -0
  30. neural_context_protocol-0.1.0a1/ncp/stores/__init__.py +2 -0
  31. neural_context_protocol-0.1.0a1/ncp/stores/base.py +96 -0
  32. neural_context_protocol-0.1.0a1/ncp/stores/sqlite.py +652 -0
  33. neural_context_protocol-0.1.0a1/ncp/templates/config.toml.example +28 -0
  34. neural_context_protocol-0.1.0a1/ncp/types.py +423 -0
  35. neural_context_protocol-0.1.0a1/ncp/version.py +1 -0
  36. neural_context_protocol-0.1.0a1/neural_context_protocol.egg-info/PKG-INFO +242 -0
  37. neural_context_protocol-0.1.0a1/neural_context_protocol.egg-info/SOURCES.txt +92 -0
  38. neural_context_protocol-0.1.0a1/neural_context_protocol.egg-info/dependency_links.txt +1 -0
  39. neural_context_protocol-0.1.0a1/neural_context_protocol.egg-info/entry_points.txt +2 -0
  40. neural_context_protocol-0.1.0a1/neural_context_protocol.egg-info/requires.txt +34 -0
  41. neural_context_protocol-0.1.0a1/neural_context_protocol.egg-info/top_level.txt +1 -0
  42. neural_context_protocol-0.1.0a1/pyproject.toml +79 -0
  43. neural_context_protocol-0.1.0a1/setup.cfg +4 -0
  44. neural_context_protocol-0.1.0a1/tests/test_adapters.py +377 -0
  45. neural_context_protocol-0.1.0a1/tests/test_api.py +146 -0
  46. neural_context_protocol-0.1.0a1/tests/test_assembler.py +148 -0
  47. neural_context_protocol-0.1.0a1/tests/test_assembler_phase3.py +335 -0
  48. neural_context_protocol-0.1.0a1/tests/test_benchmarks.py +59 -0
  49. neural_context_protocol-0.1.0a1/tests/test_chunker.py +100 -0
  50. neural_context_protocol-0.1.0a1/tests/test_cli.py +347 -0
  51. neural_context_protocol-0.1.0a1/tests/test_coherence.py +81 -0
  52. neural_context_protocol-0.1.0a1/tests/test_config.py +49 -0
  53. neural_context_protocol-0.1.0a1/tests/test_costs.py +33 -0
  54. neural_context_protocol-0.1.0a1/tests/test_dogfood.py +361 -0
  55. neural_context_protocol-0.1.0a1/tests/test_encoder.py +107 -0
  56. neural_context_protocol-0.1.0a1/tests/test_examples.py +58 -0
  57. neural_context_protocol-0.1.0a1/tests/test_imports.py +5 -0
  58. neural_context_protocol-0.1.0a1/tests/test_mcp_server.py +497 -0
  59. neural_context_protocol-0.1.0a1/tests/test_middleware.py +87 -0
  60. neural_context_protocol-0.1.0a1/tests/test_sqlite_store.py +231 -0
  61. neural_context_protocol-0.1.0a1/tests/test_types.py +256 -0
@@ -0,0 +1,242 @@
1
+ Metadata-Version: 2.4
2
+ Name: neural-context-protocol
3
+ Version: 0.1.0a1
4
+ Summary: Neural Context Protocol (NCP): bounded, persistent context for multi-agent pipelines.
5
+ Author: kulkarni2u
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/kulkarni2u/neural-context-protocol
8
+ Project-URL: Repository, https://github.com/kulkarni2u/neural-context-protocol
9
+ Project-URL: Issues, https://github.com/kulkarni2u/neural-context-protocol/issues
10
+ Keywords: mcp,agents,multi-agent,context,memory,sqlite,llm,protocol
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ Requires-Dist: pydantic>=2.7
22
+ Requires-Dist: rank-bm25>=0.2.2
23
+ Requires-Dist: click>=8.1
24
+ Requires-Dist: rich>=13.0
25
+ Requires-Dist: httpx>=0.27
26
+ Requires-Dist: anyio>=4.3
27
+ Requires-Dist: orjson>=3.10
28
+ Requires-Dist: structlog>=24.0
29
+ Provides-Extra: providers
30
+ Requires-Dist: anthropic; extra == "providers"
31
+ Requires-Dist: openai; extra == "providers"
32
+ Requires-Dist: google-generativeai; extra == "providers"
33
+ Requires-Dist: mistralai; extra == "providers"
34
+ Requires-Dist: cohere; extra == "providers"
35
+ Provides-Extra: http
36
+ Requires-Dist: aiohttp; extra == "http"
37
+ Provides-Extra: redis
38
+ Requires-Dist: redis; extra == "redis"
39
+ Provides-Extra: pgvector
40
+ Requires-Dist: psycopg2-binary; extra == "pgvector"
41
+ Requires-Dist: pgvector; extra == "pgvector"
42
+ Provides-Extra: dev
43
+ Requires-Dist: build; extra == "dev"
44
+ Requires-Dist: pytest; extra == "dev"
45
+ Requires-Dist: pytest-asyncio; extra == "dev"
46
+ Requires-Dist: pytest-httpx; extra == "dev"
47
+ Requires-Dist: pytest-cov; extra == "dev"
48
+ Requires-Dist: ruff; extra == "dev"
49
+ Requires-Dist: mypy; extra == "dev"
50
+
51
+ # Neural Context Protocol
52
+
53
+ [![CI](https://github.com/kulkarni2u/neural-context-protocol/actions/workflows/ci.yml/badge.svg)](https://github.com/kulkarni2u/neural-context-protocol/actions/workflows/ci.yml)
54
+ ![Python](https://img.shields.io/badge/python-3.10%2B-blue)
55
+ ![License](https://img.shields.io/badge/license-MIT-green)
56
+
57
+ Neural Context Protocol (NCP) is a local-first context runtime for multi-agent
58
+ systems. It keeps context bounded, persists useful memory across turns and
59
+ restarts, and exposes that shared context over MCP so multiple tools can work
60
+ from the same state instead of replaying full history.
61
+
62
+ In the included benchmarks, NCP reduced peak prompt size by `17.52x` on a
63
+ coding pipeline and `16.35x` on a research pipeline versus naive history replay.
64
+
65
+ ## Why NCP
66
+
67
+ Multi-agent workflows usually break down in three predictable ways:
68
+
69
+ - prompt history keeps growing until token cost and latency get ugly
70
+ - agents lose useful state between turns or after a restart
71
+ - each tool has its own silo, so context does not move cleanly across workers
72
+
73
+ NCP addresses that with:
74
+
75
+ - bounded context assembly for the current turn
76
+ - durable shared memory in a project-local SQLite store
77
+ - targeted mid-turn retrieval with `ncp_fetch`
78
+ - cross-agent signaling with whispers
79
+ - one MCP surface that multiple coding tools can share
80
+
81
+ ## What Is Proven Today
82
+
83
+ This repo is in an early alpha V1 state with a SQLite-first runtime and
84
+ HTTP/SSE MCP as the public transport.
85
+
86
+ What is already proven in this repository:
87
+
88
+ - Claude and OpenCode both connect to the same NCP MCP server over HTTP
89
+ - both hosts can write shared memory through MCP
90
+ - both hosts can retrieve memory written by the other host
91
+ - both hosts can deliver and receive whispers through the shared MCP runtime
92
+ - restart persistence is validated by the dogfood harness
93
+ - bounded-context benchmarks are reproducible and show large prompt reduction
94
+
95
+ Current benchmark snapshot:
96
+
97
+ - coding pipeline: peak `174` NCP tokens vs `1927` naive replay, `17.52x` reduction
98
+ - research pipeline: peak `156` NCP tokens vs `1700` naive replay, `16.35x` reduction
99
+
100
+ ## Quick Start
101
+
102
+ ```bash
103
+ pip install -e .
104
+ ncp init
105
+ ncp serve --host 127.0.0.1 --port 4242 --cwd /path/to/project
106
+ ncp status --cwd /path/to/project
107
+ ```
108
+
109
+ Expected success signals:
110
+
111
+ - `ncp init` creates `.ncp/config.toml` and `CLAUDE.md`
112
+ - `ncp serve` starts the local HTTP MCP server on `127.0.0.1:4242`
113
+ - `ncp status` prints store metrics such as chunk count and whisper count
114
+
115
+ Published alpha install path:
116
+
117
+ ```bash
118
+ pip install neural-context-protocol
119
+ ```
120
+
121
+ For a deeper setup path, see [docs/NCP_SETUP.md](./docs/NCP_SETUP.md).
122
+
123
+ ## How It Works
124
+
125
+ NCP keeps one shared SQLite store per project and serves it over MCP:
126
+
127
+ ```text
128
+ Claude Code ─┐
129
+ Codex ─┼→ ncp serve (HTTP/SSE MCP) → .ncp/store.db
130
+ OpenCode ─┘
131
+ ```
132
+
133
+ Each agent turn works roughly like this:
134
+
135
+ 1. call `ncp_get_context`
136
+ 2. get a bounded, assembled context block for the current role and task
137
+ 3. optionally call `ncp_fetch` for targeted retrieval mid-turn
138
+ 4. persist useful results with `ncp_write_memory`
139
+ 5. send light-weight cross-agent signals with `ncp_emit_whisper`
140
+
141
+ Example assembled context:
142
+
143
+ ```text
144
+ [NCP:CONSCIOUS]
145
+ agent:planner role:plan task:verify_shared_memory slot:bounded_context
146
+
147
+ [NCP:SUBCON]
148
+ chunk:sub_2267717ed22a layer:semantic
149
+ opencode_http_probe_20260524T230734Z
150
+
151
+ [NCP:WHISPERS]
152
+ wsp from:opencode to:claude t:nudge c:0.96 age:1s
153
+ whisper_probe_opencode_to_claude_20260524T232132Z
154
+ ```
155
+
156
+ ## MCP Transport
157
+
158
+ NCP’s public transport is HTTP/SSE MCP:
159
+
160
+ ```bash
161
+ ncp serve --host 127.0.0.1 --port 4242 --cwd /path/to/project
162
+ ```
163
+
164
+ Endpoints:
165
+
166
+ - `GET /healthz`
167
+ - `GET /sse`
168
+ - `POST /mcp`
169
+
170
+ Use this endpoint in MCP host configs:
171
+
172
+ - `http://127.0.0.1:4242/mcp`
173
+
174
+ The public HTTP path is validated end to end by the dogfood harness, not just
175
+ by unit tests.
176
+
177
+ ## Benchmarks
178
+
179
+ Runnable benchmark commands:
180
+
181
+ ```bash
182
+ python3 benchmarks/coding_pipeline/run.py --turns 40
183
+ python3 benchmarks/research_pipeline/run.py --turns 36
184
+ ```
185
+
186
+ Benchmark write-ups:
187
+
188
+ - [docs/NCP_BENCHMARK_CODING_PIPELINE.md](./docs/NCP_BENCHMARK_CODING_PIPELINE.md)
189
+ - [docs/NCP_BENCHMARK_RESEARCH_PIPELINE.md](./docs/NCP_BENCHMARK_RESEARCH_PIPELINE.md)
190
+
191
+ ## Examples
192
+
193
+ Runnable examples:
194
+
195
+ ```bash
196
+ python3 examples/01_quickstart.py
197
+ python3 examples/02_multi_agent.py
198
+ ```
199
+
200
+ Integration examples:
201
+
202
+ - `examples/06_claude_code/` - Claude Code setup and MCP config
203
+ - `examples/07_codex_cli/` - Codex CLI MCP config and session loop
204
+
205
+ ## Current Scope
206
+
207
+ This repository currently ships:
208
+
209
+ - core NCP types and encoder
210
+ - chunking and bounded assembly
211
+ - SQLite-backed persistence
212
+ - HTTP/SSE MCP server
213
+ - dogfood validation harness
214
+ - local adapter plus provider adapter surface
215
+ - release preflight script
216
+ - minimal CI for `ruff`, `pytest`, and `build`
217
+
218
+ Next release step:
219
+
220
+ - publish the first alpha release
221
+
222
+ ## Documentation
223
+
224
+ - [docs/NCP_SETUP.md](./docs/NCP_SETUP.md) - install and first-run setup
225
+ - [docs/NCP_PROTOCOL_SPEC.md](./docs/NCP_PROTOCOL_SPEC.md) - normative protocol reference
226
+ - [docs/NCP_MCP_DOGFOOD_LOOP.md](./docs/NCP_MCP_DOGFOOD_LOOP.md) - deterministic MCP proof path
227
+ - [docs/NCP_PROVIDER_PARITY_BASELINE.md](./docs/NCP_PROVIDER_PARITY_BASELINE.md) - current live host parity snapshot
228
+ - [CHANGELOG.md](./CHANGELOG.md) - release-facing change summary
229
+
230
+ ## Release Preflight
231
+
232
+ ```bash
233
+ bash scripts/release_preflight.sh
234
+ ```
235
+
236
+ <details>
237
+ <summary>Provider notes</summary>
238
+
239
+ - `GeminiAdapter` currently uses `google.generativeai`, which is deprecated upstream. The adapter is functionally green in tests, but should migrate to `google.genai` in a future pass.
240
+ - `CohereAdapter` is functionally green, but the current upstream SDK emits Python deprecation warnings during tests.
241
+
242
+ </details>
@@ -0,0 +1,192 @@
1
+ # Neural Context Protocol
2
+
3
+ [![CI](https://github.com/kulkarni2u/neural-context-protocol/actions/workflows/ci.yml/badge.svg)](https://github.com/kulkarni2u/neural-context-protocol/actions/workflows/ci.yml)
4
+ ![Python](https://img.shields.io/badge/python-3.10%2B-blue)
5
+ ![License](https://img.shields.io/badge/license-MIT-green)
6
+
7
+ Neural Context Protocol (NCP) is a local-first context runtime for multi-agent
8
+ systems. It keeps context bounded, persists useful memory across turns and
9
+ restarts, and exposes that shared context over MCP so multiple tools can work
10
+ from the same state instead of replaying full history.
11
+
12
+ In the included benchmarks, NCP reduced peak prompt size by `17.52x` on a
13
+ coding pipeline and `16.35x` on a research pipeline versus naive history replay.
14
+
15
+ ## Why NCP
16
+
17
+ Multi-agent workflows usually break down in three predictable ways:
18
+
19
+ - prompt history keeps growing until token cost and latency get ugly
20
+ - agents lose useful state between turns or after a restart
21
+ - each tool has its own silo, so context does not move cleanly across workers
22
+
23
+ NCP addresses that with:
24
+
25
+ - bounded context assembly for the current turn
26
+ - durable shared memory in a project-local SQLite store
27
+ - targeted mid-turn retrieval with `ncp_fetch`
28
+ - cross-agent signaling with whispers
29
+ - one MCP surface that multiple coding tools can share
30
+
31
+ ## What Is Proven Today
32
+
33
+ This repo is in an early alpha V1 state with a SQLite-first runtime and
34
+ HTTP/SSE MCP as the public transport.
35
+
36
+ What is already proven in this repository:
37
+
38
+ - Claude and OpenCode both connect to the same NCP MCP server over HTTP
39
+ - both hosts can write shared memory through MCP
40
+ - both hosts can retrieve memory written by the other host
41
+ - both hosts can deliver and receive whispers through the shared MCP runtime
42
+ - restart persistence is validated by the dogfood harness
43
+ - bounded-context benchmarks are reproducible and show large prompt reduction
44
+
45
+ Current benchmark snapshot:
46
+
47
+ - coding pipeline: peak `174` NCP tokens vs `1927` naive replay, `17.52x` reduction
48
+ - research pipeline: peak `156` NCP tokens vs `1700` naive replay, `16.35x` reduction
49
+
50
+ ## Quick Start
51
+
52
+ ```bash
53
+ pip install -e .
54
+ ncp init
55
+ ncp serve --host 127.0.0.1 --port 4242 --cwd /path/to/project
56
+ ncp status --cwd /path/to/project
57
+ ```
58
+
59
+ Expected success signals:
60
+
61
+ - `ncp init` creates `.ncp/config.toml` and `CLAUDE.md`
62
+ - `ncp serve` starts the local HTTP MCP server on `127.0.0.1:4242`
63
+ - `ncp status` prints store metrics such as chunk count and whisper count
64
+
65
+ Published alpha install path:
66
+
67
+ ```bash
68
+ pip install neural-context-protocol
69
+ ```
70
+
71
+ For a deeper setup path, see [docs/NCP_SETUP.md](./docs/NCP_SETUP.md).
72
+
73
+ ## How It Works
74
+
75
+ NCP keeps one shared SQLite store per project and serves it over MCP:
76
+
77
+ ```text
78
+ Claude Code ─┐
79
+ Codex ─┼→ ncp serve (HTTP/SSE MCP) → .ncp/store.db
80
+ OpenCode ─┘
81
+ ```
82
+
83
+ Each agent turn works roughly like this:
84
+
85
+ 1. call `ncp_get_context`
86
+ 2. get a bounded, assembled context block for the current role and task
87
+ 3. optionally call `ncp_fetch` for targeted retrieval mid-turn
88
+ 4. persist useful results with `ncp_write_memory`
89
+ 5. send light-weight cross-agent signals with `ncp_emit_whisper`
90
+
91
+ Example assembled context:
92
+
93
+ ```text
94
+ [NCP:CONSCIOUS]
95
+ agent:planner role:plan task:verify_shared_memory slot:bounded_context
96
+
97
+ [NCP:SUBCON]
98
+ chunk:sub_2267717ed22a layer:semantic
99
+ opencode_http_probe_20260524T230734Z
100
+
101
+ [NCP:WHISPERS]
102
+ wsp from:opencode to:claude t:nudge c:0.96 age:1s
103
+ whisper_probe_opencode_to_claude_20260524T232132Z
104
+ ```
105
+
106
+ ## MCP Transport
107
+
108
+ NCP’s public transport is HTTP/SSE MCP:
109
+
110
+ ```bash
111
+ ncp serve --host 127.0.0.1 --port 4242 --cwd /path/to/project
112
+ ```
113
+
114
+ Endpoints:
115
+
116
+ - `GET /healthz`
117
+ - `GET /sse`
118
+ - `POST /mcp`
119
+
120
+ Use this endpoint in MCP host configs:
121
+
122
+ - `http://127.0.0.1:4242/mcp`
123
+
124
+ The public HTTP path is validated end to end by the dogfood harness, not just
125
+ by unit tests.
126
+
127
+ ## Benchmarks
128
+
129
+ Runnable benchmark commands:
130
+
131
+ ```bash
132
+ python3 benchmarks/coding_pipeline/run.py --turns 40
133
+ python3 benchmarks/research_pipeline/run.py --turns 36
134
+ ```
135
+
136
+ Benchmark write-ups:
137
+
138
+ - [docs/NCP_BENCHMARK_CODING_PIPELINE.md](./docs/NCP_BENCHMARK_CODING_PIPELINE.md)
139
+ - [docs/NCP_BENCHMARK_RESEARCH_PIPELINE.md](./docs/NCP_BENCHMARK_RESEARCH_PIPELINE.md)
140
+
141
+ ## Examples
142
+
143
+ Runnable examples:
144
+
145
+ ```bash
146
+ python3 examples/01_quickstart.py
147
+ python3 examples/02_multi_agent.py
148
+ ```
149
+
150
+ Integration examples:
151
+
152
+ - `examples/06_claude_code/` - Claude Code setup and MCP config
153
+ - `examples/07_codex_cli/` - Codex CLI MCP config and session loop
154
+
155
+ ## Current Scope
156
+
157
+ This repository currently ships:
158
+
159
+ - core NCP types and encoder
160
+ - chunking and bounded assembly
161
+ - SQLite-backed persistence
162
+ - HTTP/SSE MCP server
163
+ - dogfood validation harness
164
+ - local adapter plus provider adapter surface
165
+ - release preflight script
166
+ - minimal CI for `ruff`, `pytest`, and `build`
167
+
168
+ Next release step:
169
+
170
+ - publish the first alpha release
171
+
172
+ ## Documentation
173
+
174
+ - [docs/NCP_SETUP.md](./docs/NCP_SETUP.md) - install and first-run setup
175
+ - [docs/NCP_PROTOCOL_SPEC.md](./docs/NCP_PROTOCOL_SPEC.md) - normative protocol reference
176
+ - [docs/NCP_MCP_DOGFOOD_LOOP.md](./docs/NCP_MCP_DOGFOOD_LOOP.md) - deterministic MCP proof path
177
+ - [docs/NCP_PROVIDER_PARITY_BASELINE.md](./docs/NCP_PROVIDER_PARITY_BASELINE.md) - current live host parity snapshot
178
+ - [CHANGELOG.md](./CHANGELOG.md) - release-facing change summary
179
+
180
+ ## Release Preflight
181
+
182
+ ```bash
183
+ bash scripts/release_preflight.sh
184
+ ```
185
+
186
+ <details>
187
+ <summary>Provider notes</summary>
188
+
189
+ - `GeminiAdapter` currently uses `google.generativeai`, which is deprecated upstream. The adapter is functionally green in tests, but should migrate to `google.genai` in a future pass.
190
+ - `CohereAdapter` is functionally green, but the current upstream SDK emits Python deprecation warnings during tests.
191
+
192
+ </details>
@@ -0,0 +1,35 @@
1
+ """Public package surface for Neural Context Protocol."""
2
+
3
+ from .api import agent, configure, emit, get_context, run, stream, write_memory
4
+ from .benchmarks import estimate_tokens, run_coding_pipeline_benchmark, run_research_pipeline_benchmark
5
+ from .dogfood import (
6
+ get_live_provider_readiness,
7
+ load_dogfood_adapter,
8
+ run_adapter_continuation_dogfood_loop,
9
+ run_canonical_dogfood_loop,
10
+ run_canonical_http_dogfood_loop,
11
+ run_live_adapter_continuation_attempt,
12
+ run_repeatability_dogfood_loop,
13
+ )
14
+ from .version import __version__
15
+
16
+ __all__ = [
17
+ "__version__",
18
+ "agent",
19
+ "configure",
20
+ "estimate_tokens",
21
+ "emit",
22
+ "get_live_provider_readiness",
23
+ "get_context",
24
+ "load_dogfood_adapter",
25
+ "run_adapter_continuation_dogfood_loop",
26
+ "run_canonical_dogfood_loop",
27
+ "run_canonical_http_dogfood_loop",
28
+ "run_live_adapter_continuation_attempt",
29
+ "run_repeatability_dogfood_loop",
30
+ "run",
31
+ "run_coding_pipeline_benchmark",
32
+ "run_research_pipeline_benchmark",
33
+ "stream",
34
+ "write_memory",
35
+ ]
@@ -0,0 +1,2 @@
1
+ """Provider adapters package."""
2
+
@@ -0,0 +1,64 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Iterator
4
+ from os import environ
5
+
6
+ from ncp.adapters.base import BaseAdapter
7
+
8
+
9
+ class AnthropicAdapter(BaseAdapter):
10
+ @property
11
+ def ctx_window(self) -> int:
12
+ return 200000
13
+
14
+ def __init__(
15
+ self,
16
+ api_key: str = "",
17
+ model: str = "claude-sonnet-4-20250514",
18
+ max_tokens: int = 4096,
19
+ timeout: float = 120.0,
20
+ ) -> None:
21
+ try:
22
+ import anthropic
23
+ except ImportError as err:
24
+ raise ImportError(
25
+ "anthropic is required. Install it with: pip install 'ncp-sdk[providers]'"
26
+ ) from err
27
+ self._anthropic = anthropic
28
+ resolved_key = api_key or environ.get("ANTHROPIC_API_KEY", "")
29
+ self._client = anthropic.Anthropic(
30
+ api_key=self._require_api_key(resolved_key, env_var="ANTHROPIC_API_KEY"),
31
+ timeout=timeout,
32
+ )
33
+ self._model = model
34
+ self._max_tokens = max_tokens
35
+
36
+ def call(self, ncp_context: str, user_turn: str) -> str:
37
+ msg = self._run_provider_call(
38
+ lambda: self._client.messages.create(
39
+ model=self._model,
40
+ max_tokens=self._max_tokens,
41
+ system=ncp_context,
42
+ messages=[{"role": "user", "content": user_turn}],
43
+ ),
44
+ provider="Anthropic",
45
+ timeout_types=(self._anthropic.APITimeoutError, TimeoutError),
46
+ )
47
+ texts = [b.text for b in msg.content if b.type == "text"]
48
+ return self._coerce_text("".join(texts), provider="Anthropic")
49
+
50
+ def stream(self, ncp_context: str, user_turn: str) -> Iterator[str]:
51
+ stream_ctx = self._run_provider_call(
52
+ lambda: self._client.messages.stream(
53
+ model=self._model,
54
+ max_tokens=self._max_tokens,
55
+ system=ncp_context,
56
+ messages=[{"role": "user", "content": user_turn}],
57
+ ),
58
+ provider="Anthropic",
59
+ timeout_types=(self._anthropic.APITimeoutError, TimeoutError),
60
+ )
61
+ with stream_ctx as stream:
62
+ for event in stream:
63
+ if event.type == "content_block_delta" and event.delta.type == "text_delta":
64
+ yield event.delta.text
@@ -0,0 +1,76 @@
1
+ """Base adapter contract."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from abc import ABC, abstractmethod
6
+ from collections.abc import Iterator
7
+ from typing import Callable, TypeVar
8
+
9
+
10
+ class NCPAdapterError(RuntimeError):
11
+ """Base class for provider adapter failures."""
12
+
13
+
14
+ class NCPAdapterConfigurationError(NCPAdapterError):
15
+ """Raised when an adapter is misconfigured before making a call."""
16
+
17
+
18
+ class NCPAdapterTimeoutError(NCPAdapterError):
19
+ """Raised when a provider call times out."""
20
+
21
+
22
+ class NCPAdapterResponseError(NCPAdapterError):
23
+ """Raised when a provider returns an unusable response."""
24
+
25
+
26
+ _T = TypeVar("_T")
27
+
28
+
29
+ class BaseAdapter(ABC):
30
+ """Minimal provider adapter contract for the first NCP API slice."""
31
+
32
+ @property
33
+ def ctx_window(self) -> int:
34
+ return 200000
35
+
36
+ @abstractmethod
37
+ def call(self, ncp_context: str, user_turn: str) -> str:
38
+ """Return a blocking response for one assembled context."""
39
+
40
+ def stream(self, ncp_context: str, user_turn: str) -> Iterator[str]:
41
+ """Yield a streamed response for one assembled context.
42
+
43
+ Tier 2 providers override only if they support streaming.
44
+ """
45
+ raise NotImplementedError(
46
+ f"{type(self).__name__} does not support streaming in NCP V1; use blocking call()"
47
+ )
48
+
49
+ def _require_api_key(self, api_key: str, *, env_var: str) -> str:
50
+ if api_key.strip():
51
+ return api_key
52
+ raise NCPAdapterConfigurationError(
53
+ f"{type(self).__name__} requires {env_var}; configure it or pass api_key explicitly"
54
+ )
55
+
56
+ def _coerce_text(self, value: str | None, *, provider: str) -> str:
57
+ text = (value or "").strip()
58
+ if text:
59
+ return text
60
+ raise NCPAdapterResponseError(f"{provider} returned an empty text response")
61
+
62
+ def _run_provider_call(
63
+ self,
64
+ call: Callable[[], _T],
65
+ *,
66
+ provider: str,
67
+ timeout_types: tuple[type[BaseException], ...] = (TimeoutError,),
68
+ ) -> _T:
69
+ try:
70
+ return call()
71
+ except NCPAdapterError:
72
+ raise
73
+ except timeout_types as exc:
74
+ raise NCPAdapterTimeoutError(f"{provider} timed out: {exc}") from exc
75
+ except Exception as exc:
76
+ raise NCPAdapterError(f"{provider} call failed: {exc}") from exc
@@ -0,0 +1,48 @@
1
+ from __future__ import annotations
2
+
3
+ from os import environ
4
+
5
+ from ncp.adapters.base import BaseAdapter
6
+
7
+
8
+ class CohereAdapter(BaseAdapter):
9
+ @property
10
+ def ctx_window(self) -> int:
11
+ return 128000
12
+
13
+ def __init__(
14
+ self,
15
+ api_key: str = "",
16
+ model: str = "command-a-03-2025",
17
+ max_tokens: int = 4096,
18
+ timeout: float = 120.0,
19
+ ) -> None:
20
+ try:
21
+ import cohere
22
+ except ImportError as err:
23
+ raise ImportError(
24
+ "cohere is required. Install it with: pip install 'ncp-sdk[providers]'"
25
+ ) from err
26
+ resolved_key = api_key or environ.get("COHERE_API_KEY", "")
27
+ self._client = cohere.Client(
28
+ api_key=self._require_api_key(resolved_key, env_var="COHERE_API_KEY"),
29
+ timeout=timeout,
30
+ )
31
+ self._model = model
32
+ self._max_tokens = max_tokens
33
+
34
+ def call(self, ncp_context: str, user_turn: str) -> str:
35
+ from cohere.types import ChatMessage
36
+
37
+ resp = self._run_provider_call(
38
+ lambda: self._client.chat(
39
+ model=self._model,
40
+ max_tokens=self._max_tokens,
41
+ preamble=ncp_context,
42
+ messages=[
43
+ ChatMessage(role="user", message=user_turn),
44
+ ],
45
+ ),
46
+ provider="Cohere",
47
+ )
48
+ return self._coerce_text(resp.text, provider="Cohere")
@@ -0,0 +1,39 @@
1
+ from __future__ import annotations
2
+
3
+ from os import environ
4
+
5
+ from ncp.adapters.base import BaseAdapter
6
+
7
+
8
+ class GeminiAdapter(BaseAdapter):
9
+ @property
10
+ def ctx_window(self) -> int:
11
+ return 1000000
12
+
13
+ def __init__(
14
+ self,
15
+ api_key: str = "",
16
+ model: str = "gemini-2.0-flash",
17
+ timeout: float = 120.0,
18
+ ) -> None:
19
+ try:
20
+ import google.generativeai as genai
21
+ except ImportError as err:
22
+ raise ImportError(
23
+ "google-generativeai is required. Install it with: pip install 'ncp-sdk[providers]'"
24
+ ) from err
25
+ resolved_key = api_key or environ.get("GOOGLE_API_KEY", "")
26
+ genai.configure(api_key=self._require_api_key(resolved_key, env_var="GOOGLE_API_KEY"))
27
+ self._model = genai.GenerativeModel(model)
28
+ self._timeout = timeout
29
+
30
+ def call(self, ncp_context: str, user_turn: str) -> str:
31
+ prompt = f"{ncp_context}\n\n{user_turn}"
32
+ resp = self._run_provider_call(
33
+ lambda: self._model.generate_content(
34
+ prompt,
35
+ request_options={"timeout": self._timeout},
36
+ ),
37
+ provider="Gemini",
38
+ )
39
+ return self._coerce_text(resp.text, provider="Gemini")