ctxprotocol 0.15.0__tar.gz → 0.17.0__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 (53) hide show
  1. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/PKG-INFO +19 -11
  2. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/README.md +18 -10
  3. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/__init__.py +7 -1
  4. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/client/__init__.py +6 -0
  5. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/client/resources/query.py +12 -9
  6. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/client/types.py +41 -9
  7. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/examples/server/hummingbot-contributor/requirements.txt +1 -1
  8. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/pyproject.toml +1 -1
  9. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/tests/test_query.py +10 -8
  10. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/uv.lock +1 -1
  11. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/.codexignore +0 -0
  12. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/.gitignore +0 -0
  13. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/auth/__init__.py +0 -0
  14. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/client/client.py +0 -0
  15. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/client/resources/__init__.py +0 -0
  16. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/client/resources/developer.py +0 -0
  17. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/client/resources/discovery.py +0 -0
  18. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/client/resources/tools.py +0 -0
  19. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/context/__init__.py +0 -0
  20. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/context/hyperliquid.py +0 -0
  21. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/context/polymarket.py +0 -0
  22. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/context/wallet.py +0 -0
  23. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/contrib/__init__.py +0 -0
  24. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/contrib/search/__init__.py +0 -0
  25. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/contrib/search/core.py +0 -0
  26. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/contrib/search/trace.py +0 -0
  27. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/contrib/search/types.py +0 -0
  28. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/contrib/search/validation.py +0 -0
  29. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/handshake/__init__.py +0 -0
  30. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/ctxprotocol/py.typed +0 -0
  31. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/docs/README.md +0 -0
  32. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/examples/client/execute_client.py +0 -0
  33. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/examples/client/polymarket_query_trace_validation.py +0 -0
  34. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/examples/client/query_client.py +0 -0
  35. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/examples/client/test_favorites_only.py +0 -0
  36. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/examples/client/test_get_tool.py +0 -0
  37. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/examples/client/two_surfaces_client.py +0 -0
  38. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/examples/client/validation/generate_contributor_search_validation_artifacts.py +0 -0
  39. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/examples/client/validation/named-regression-iran-boots-on-ground.json +0 -0
  40. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/examples/client/validation/named-regression-supreme-court-tariffs.json +0 -0
  41. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/examples/client/validation/shared-capability-miss-unsupported-venue.json +0 -0
  42. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/examples/client/validation/shared-generic-overlap-best-match.json +0 -0
  43. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/examples/client/validation/shared-still-ambiguous-shortlist.json +0 -0
  44. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/examples/server/hummingbot-contributor/README.md +0 -0
  45. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/examples/server/hummingbot-contributor/env.example +0 -0
  46. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/examples/server/hummingbot-contributor/server.py +0 -0
  47. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/polymarket-query-trace-results-py.json +0 -0
  48. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/tests/__init__.py +0 -0
  49. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/tests/contrib_search_validation_cases.py +0 -0
  50. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/tests/test_client.py +0 -0
  51. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/tests/test_contrib_search.py +0 -0
  52. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/tests/test_discovery.py +0 -0
  53. {ctxprotocol-0.15.0 → ctxprotocol-0.17.0}/tests/test_tools.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ctxprotocol
3
- Version: 0.15.0
3
+ Version: 0.17.0
4
4
  Summary: Official Python SDK for the Context Protocol - Discover and execute AI tools programmatically
5
5
  Project-URL: Homepage, https://ctxprotocol.com
6
6
  Project-URL: Documentation, https://docs.ctxprotocol.com
@@ -125,12 +125,12 @@ result = await client.tools.execute(
125
125
  print(result.session) # method_price, spent, remaining, max_spend, ...
126
126
  ```
127
127
 
128
- **Query mode** gives you a managed librarian contract — the server runs the live pipeline (`discover -> select -> iterative execute -> synthesize -> settle`) with model-aware context budgeting and can return plain answers or structured evidence packages for one flat fee:
128
+ **Query mode** gives you a managed librarian contract — the server runs the live pipeline (`discover -> select -> iterative execute -> synthesize -> settle`) with model-aware context budgeting and returns structured evidence packages for one flat fee:
129
129
  ```python
130
130
  answer = await client.query.run(
131
131
  query="What are the top whale movements on Base?",
132
- answer_model_id="glm-model", # optional: choose the final synthesis model
133
- response_shape="answer_with_evidence", # optional: answer | answer_with_evidence | evidence_only
132
+ agent_model_id="kimi-k2.6-model", # optional: choose the main librarian agent model
133
+ response_shape="answer_with_evidence", # optional: answer_with_evidence (default) | evidence_only
134
134
  include_data_url=True, # optional: persist full execution data to blob
135
135
  include_developer_trace=True, # optional: include runtime developer trace
136
136
  )
@@ -149,6 +149,15 @@ print(
149
149
  print(answer.orchestration_metrics) # Optional first-pass / rediscovery metrics
150
150
  ```
151
151
 
152
+ To see valid model slugs without guessing:
153
+
154
+ ```python
155
+ from ctxprotocol import AGENT_MODEL_IDS, DEFAULT_AGENT_MODEL_ID
156
+
157
+ print(DEFAULT_AGENT_MODEL_ID) # "kimi-k2.6-model"
158
+ print(AGENT_MODEL_IDS) # Supported agent_model_id values
159
+ ```
160
+
152
161
  > Mixed listings are first-class: one listing can expose methods to both surfaces. Methods without `_meta.pricing.executeUsd` remain query-only until priced.
153
162
  >
154
163
  > Compatibility: SDK/API payload fields such as `price` and `price_per_query` are retained for backward compatibility. In Query mode, they represent listing-level **price per response turn**.
@@ -156,9 +165,8 @@ print(answer.orchestration_metrics) # Optional first-pass / rediscovery metrics
156
165
 
157
166
  `response_shape` options:
158
167
 
159
- - `answer`: backward-compatible prose answer
160
- - `answer_with_evidence`: prose plus `summary`, `evidence`, `artifacts`, `freshness`, `confidence`, `usage`, `outcome`, and `controller`
161
- - `evidence_only`: machine-friendly summary plus the same evidence package for downstream agents
168
+ - `answer_with_evidence` (default): prose plus `summary`, `evidence`, `artifacts`, `freshness`, `confidence`, `usage`, `outcome`, and `controller`
169
+ - `evidence_only`: raw fetched data, computed artifacts, and provenance for downstream agents (no prose synthesis)
162
170
 
163
171
  Premium wedge answers can also expose `evidence.market_intelligence`, `view.rows`, `view.columns`, and the top-level controller fields `stop_reason`, `issue_class`, and `actions_taken`.
164
172
 
@@ -298,9 +306,9 @@ closed = await client.tools.close_session("sess_123")
298
306
 
299
307
  ### Query (Pay-Per-Response)
300
308
 
301
- #### `client.query.run(query, tools?, answer_model_id?, include_data?, include_data_url?, include_developer_trace?, idempotency_key?)`
309
+ #### `client.query.run(query, tools?, agent_model_id?, include_data?, include_data_url?, include_developer_trace?, idempotency_key?)`
302
310
 
303
- Run an agentic query. The server applies the live librarian pipeline (`discover -> select -> iterative execute -> synthesize -> settle`) with up to 100 MCP calls per response turn, then returns the selected Query response contract (`answer`, `answer_with_evidence`, or `evidence_only`).
311
+ Run an agentic query. The server applies the live librarian pipeline (`discover -> select -> iterative execute -> synthesize -> settle`) with up to 100 MCP calls per response turn, then returns the selected Query response contract (`answer_with_evidence` or `evidence_only`, default `answer_with_evidence`).
304
312
 
305
313
  `client.query.run()` buffers the same SSE transport used by `client.query.stream()` and returns the final `done` result. This keeps Python aligned with the TypeScript SDK and the live query runtime.
306
314
 
@@ -318,7 +326,7 @@ answer = await client.query.run("What are the top whale movements on Base?")
318
326
  answer = await client.query.run(
319
327
  query="Analyze whale activity on Base",
320
328
  tools=["tool-uuid-1", "tool-uuid-2"], # optional — auto-discover if omitted
321
- answer_model_id="kimi-model-thinking", # optional final synthesis model
329
+ agent_model_id="kimi-k2.6-model", # optional main librarian agent model
322
330
  include_data=True, # optional: include execution data inline
323
331
  include_data_url=True, # optional: include blob URL for full data
324
332
  include_developer_trace=True, # optional: include Developer Mode trace
@@ -341,7 +349,7 @@ print(answer.orchestration_metrics) # Optional first-pass / rediscovery metrics
341
349
 
342
350
  When retrieval-first synthesis rollout is enabled server-side, full-data or truncation-sensitive query requests can switch to retrieval-first context assembly using private stage artifacts and canonical execution data slices. `include_data` and `include_data_url` continue to reference the same canonical dataset used for synthesis.
343
351
 
344
- #### `client.query.stream(query, tools?, answer_model_id?, include_data?, include_data_url?, include_developer_trace?, idempotency_key?)`
352
+ #### `client.query.stream(query, tools?, agent_model_id?, include_data?, include_data_url?, include_developer_trace?, idempotency_key?)`
345
353
 
346
354
  Same as `run()` but streams events in real-time via SSE.
347
355
 
@@ -87,12 +87,12 @@ result = await client.tools.execute(
87
87
  print(result.session) # method_price, spent, remaining, max_spend, ...
88
88
  ```
89
89
 
90
- **Query mode** gives you a managed librarian contract — the server runs the live pipeline (`discover -> select -> iterative execute -> synthesize -> settle`) with model-aware context budgeting and can return plain answers or structured evidence packages for one flat fee:
90
+ **Query mode** gives you a managed librarian contract — the server runs the live pipeline (`discover -> select -> iterative execute -> synthesize -> settle`) with model-aware context budgeting and returns structured evidence packages for one flat fee:
91
91
  ```python
92
92
  answer = await client.query.run(
93
93
  query="What are the top whale movements on Base?",
94
- answer_model_id="glm-model", # optional: choose the final synthesis model
95
- response_shape="answer_with_evidence", # optional: answer | answer_with_evidence | evidence_only
94
+ agent_model_id="kimi-k2.6-model", # optional: choose the main librarian agent model
95
+ response_shape="answer_with_evidence", # optional: answer_with_evidence (default) | evidence_only
96
96
  include_data_url=True, # optional: persist full execution data to blob
97
97
  include_developer_trace=True, # optional: include runtime developer trace
98
98
  )
@@ -111,6 +111,15 @@ print(
111
111
  print(answer.orchestration_metrics) # Optional first-pass / rediscovery metrics
112
112
  ```
113
113
 
114
+ To see valid model slugs without guessing:
115
+
116
+ ```python
117
+ from ctxprotocol import AGENT_MODEL_IDS, DEFAULT_AGENT_MODEL_ID
118
+
119
+ print(DEFAULT_AGENT_MODEL_ID) # "kimi-k2.6-model"
120
+ print(AGENT_MODEL_IDS) # Supported agent_model_id values
121
+ ```
122
+
114
123
  > Mixed listings are first-class: one listing can expose methods to both surfaces. Methods without `_meta.pricing.executeUsd` remain query-only until priced.
115
124
  >
116
125
  > Compatibility: SDK/API payload fields such as `price` and `price_per_query` are retained for backward compatibility. In Query mode, they represent listing-level **price per response turn**.
@@ -118,9 +127,8 @@ print(answer.orchestration_metrics) # Optional first-pass / rediscovery metrics
118
127
 
119
128
  `response_shape` options:
120
129
 
121
- - `answer`: backward-compatible prose answer
122
- - `answer_with_evidence`: prose plus `summary`, `evidence`, `artifacts`, `freshness`, `confidence`, `usage`, `outcome`, and `controller`
123
- - `evidence_only`: machine-friendly summary plus the same evidence package for downstream agents
130
+ - `answer_with_evidence` (default): prose plus `summary`, `evidence`, `artifacts`, `freshness`, `confidence`, `usage`, `outcome`, and `controller`
131
+ - `evidence_only`: raw fetched data, computed artifacts, and provenance for downstream agents (no prose synthesis)
124
132
 
125
133
  Premium wedge answers can also expose `evidence.market_intelligence`, `view.rows`, `view.columns`, and the top-level controller fields `stop_reason`, `issue_class`, and `actions_taken`.
126
134
 
@@ -260,9 +268,9 @@ closed = await client.tools.close_session("sess_123")
260
268
 
261
269
  ### Query (Pay-Per-Response)
262
270
 
263
- #### `client.query.run(query, tools?, answer_model_id?, include_data?, include_data_url?, include_developer_trace?, idempotency_key?)`
271
+ #### `client.query.run(query, tools?, agent_model_id?, include_data?, include_data_url?, include_developer_trace?, idempotency_key?)`
264
272
 
265
- Run an agentic query. The server applies the live librarian pipeline (`discover -> select -> iterative execute -> synthesize -> settle`) with up to 100 MCP calls per response turn, then returns the selected Query response contract (`answer`, `answer_with_evidence`, or `evidence_only`).
273
+ Run an agentic query. The server applies the live librarian pipeline (`discover -> select -> iterative execute -> synthesize -> settle`) with up to 100 MCP calls per response turn, then returns the selected Query response contract (`answer_with_evidence` or `evidence_only`, default `answer_with_evidence`).
266
274
 
267
275
  `client.query.run()` buffers the same SSE transport used by `client.query.stream()` and returns the final `done` result. This keeps Python aligned with the TypeScript SDK and the live query runtime.
268
276
 
@@ -280,7 +288,7 @@ answer = await client.query.run("What are the top whale movements on Base?")
280
288
  answer = await client.query.run(
281
289
  query="Analyze whale activity on Base",
282
290
  tools=["tool-uuid-1", "tool-uuid-2"], # optional — auto-discover if omitted
283
- answer_model_id="kimi-model-thinking", # optional final synthesis model
291
+ agent_model_id="kimi-k2.6-model", # optional main librarian agent model
284
292
  include_data=True, # optional: include execution data inline
285
293
  include_data_url=True, # optional: include blob URL for full data
286
294
  include_developer_trace=True, # optional: include Developer Mode trace
@@ -303,7 +311,7 @@ print(answer.orchestration_metrics) # Optional first-pass / rediscovery metrics
303
311
 
304
312
  When retrieval-first synthesis rollout is enabled server-side, full-data or truncation-sensitive query requests can switch to retrieval-first context assembly using private stage artifacts and canonical execution data slices. `include_data` and `include_data_url` continue to reference the same canonical dataset used for synthesis.
305
313
 
306
- #### `client.query.stream(query, tools?, answer_model_id?, include_data?, include_data_url?, include_developer_trace?, idempotency_key?)`
314
+ #### `client.query.stream(query, tools?, agent_model_id?, include_data?, include_data_url?, include_developer_trace?, idempotency_key?)`
307
315
 
308
316
  Same as `run()` but streams events in real-time via SSE.
309
317
 
@@ -31,7 +31,7 @@ Example:
31
31
  For more information, visit: https://ctxprotocol.com
32
32
  """
33
33
 
34
- __version__ = "0.15.0"
34
+ __version__ = "0.17.0"
35
35
 
36
36
  # Re-export everything from client module
37
37
  from ctxprotocol.client import (
@@ -43,8 +43,10 @@ from ctxprotocol.client import (
43
43
  Tools,
44
44
  )
45
45
  from ctxprotocol.client.types import (
46
+ AGENT_MODEL_IDS,
46
47
  ContextClientOptions,
47
48
  ContextErrorCode,
49
+ DEFAULT_AGENT_MODEL_ID,
48
50
  ExecuteApiErrorResponse,
49
51
  ExecuteApiSuccessResponse,
50
52
  ExecuteMethodInfo,
@@ -83,6 +85,7 @@ from ctxprotocol.client.types import (
83
85
  SearchResponse,
84
86
  Tool,
85
87
  ToolInfo,
88
+ AgentModelId,
86
89
  )
87
90
 
88
91
  # Context types for portfolio injection
@@ -178,6 +181,9 @@ __all__ = [
178
181
  "ExecuteApiErrorResponse",
179
182
  "ExecuteSessionApiSuccessResponse",
180
183
  "ToolInfo",
184
+ "AGENT_MODEL_IDS",
185
+ "DEFAULT_AGENT_MODEL_ID",
186
+ "AgentModelId",
181
187
  # Query types (pay-per-response)
182
188
  "QueryOptions",
183
189
  "QueryResult",
@@ -10,9 +10,11 @@ from ctxprotocol.client.resources.discovery import Discovery
10
10
  from ctxprotocol.client.resources.query import Query
11
11
  from ctxprotocol.client.resources.tools import Tools
12
12
  from ctxprotocol.client.types import (
13
+ AGENT_MODEL_IDS,
13
14
  ContextClientOptions,
14
15
  ContextError,
15
16
  ContextErrorCode,
17
+ DEFAULT_AGENT_MODEL_ID,
16
18
  ExecuteApiErrorResponse,
17
19
  ExecuteApiSuccessResponse,
18
20
  ExecuteMethodInfo,
@@ -64,6 +66,7 @@ from ctxprotocol.client.types import (
64
66
  SearchResponse,
65
67
  Tool,
66
68
  ToolInfo,
69
+ AgentModelId,
67
70
  )
68
71
 
69
72
  __all__ = [
@@ -76,6 +79,9 @@ __all__ = [
76
79
  "Query",
77
80
  # Types
78
81
  "ContextClientOptions",
82
+ "AGENT_MODEL_IDS",
83
+ "DEFAULT_AGENT_MODEL_ID",
84
+ "AgentModelId",
79
85
  "Tool",
80
86
  "McpTool",
81
87
  "McpToolMeta",
@@ -14,6 +14,7 @@ from typing import TYPE_CHECKING, Any, AsyncGenerator
14
14
 
15
15
  from ctxprotocol.client.types import (
16
16
  ContextError,
17
+ AgentModelId,
17
18
  QueryAttemptReference,
18
19
  QueryDeveloperTrace,
19
20
  QueryForkReference,
@@ -193,7 +194,7 @@ class Query:
193
194
  query: str,
194
195
  tools: list[str] | None = None,
195
196
  favorites_only: bool | None = None,
196
- answer_model_id: str | None = None,
197
+ agent_model_id: AgentModelId | str | None = None,
197
198
  response_shape: QueryResponseShape | None = None,
198
199
  include_data: bool | None = None,
199
200
  include_data_url: bool | None = None,
@@ -215,8 +216,9 @@ class Query:
215
216
  query: The natural-language question to answer
216
217
  tools: Optional tool IDs to use (auto-discover if not provided)
217
218
  favorites_only: Restrict auto-discovery to favorite tools for this request
218
- answer_model_id: Optional answer model ID for final synthesis
219
- response_shape: Structured response mode for query answers
219
+ agent_model_id: Optional model ID for the main librarian agent loop
220
+ response_shape: Structured response mode (`answer_with_evidence` or
221
+ `evidence_only`; server default `answer_with_evidence`)
220
222
  include_data: Include execution data inline in the query response
221
223
  include_data_url: Persist execution data to blob and return URL
222
224
  include_developer_trace: Include machine-readable Developer Mode traces
@@ -252,7 +254,7 @@ class Query:
252
254
  query=query,
253
255
  tools=tools,
254
256
  favorites_only=favorites_only,
255
- answer_model_id=answer_model_id,
257
+ agent_model_id=agent_model_id,
256
258
  response_shape=response_shape,
257
259
  include_data=include_data,
258
260
  include_data_url=include_data_url,
@@ -281,7 +283,7 @@ class Query:
281
283
  query: str,
282
284
  tools: list[str] | None = None,
283
285
  favorites_only: bool | None = None,
284
- answer_model_id: str | None = None,
286
+ agent_model_id: AgentModelId | str | None = None,
285
287
  response_shape: QueryResponseShape | None = None,
286
288
  include_data: bool | None = None,
287
289
  include_data_url: bool | None = None,
@@ -303,8 +305,9 @@ class Query:
303
305
  query: The natural-language question to answer
304
306
  tools: Optional tool IDs to use (auto-discover if not provided)
305
307
  favorites_only: Restrict auto-discovery to favorite tools for this request
306
- answer_model_id: Optional answer model ID for final synthesis
307
- response_shape: Structured response mode for query answers
308
+ agent_model_id: Optional model ID for the main librarian agent loop
309
+ response_shape: Structured response mode (`answer_with_evidence` or
310
+ `evidence_only`; server default `answer_with_evidence`)
308
311
  include_data: Include execution data inline in the query response
309
312
  include_data_url: Persist execution data to blob and return URL
310
313
  include_developer_trace: Include machine-readable Developer Mode traces
@@ -343,8 +346,8 @@ class Query:
343
346
  )
344
347
  if favorites_only is not None:
345
348
  request_body["favoritesOnly"] = favorites_only
346
- if answer_model_id is not None:
347
- request_body["answerModelId"] = answer_model_id
349
+ if agent_model_id is not None:
350
+ request_body["agentModelId"] = agent_model_id
348
351
  if response_shape is not None:
349
352
  request_body["responseShape"] = response_shape
350
353
  if include_data is not None:
@@ -43,6 +43,33 @@ McpToolSurface = Literal["answer", "execute", "both"]
43
43
  McpToolLatencyClass = Literal["instant", "fast", "slow", "streaming"]
44
44
  ExecuteSessionStatus = Literal["open", "closed", "expired"]
45
45
  SuggestedPromptSource = Literal["contributor", "platform", "sdk"]
46
+ DEFAULT_AGENT_MODEL_ID = "kimi-k2.6-model"
47
+ AGENT_MODEL_IDS = (
48
+ "kimi-k2.6-model",
49
+ "deepseek-v4-pro-model",
50
+ "deepseek-v4-flash-model",
51
+ "gemini-3.5-flash-model",
52
+ "gemini-flash-model",
53
+ "gemini-lite-model",
54
+ "minimax-m3-model",
55
+ "qwen-3.7-plus-model",
56
+ "qwen-3.7-max-model",
57
+ "gpt-5.5-model",
58
+ "claude-opus-model",
59
+ )
60
+ AgentModelId = Literal[
61
+ "kimi-k2.6-model",
62
+ "deepseek-v4-pro-model",
63
+ "deepseek-v4-flash-model",
64
+ "gemini-3.5-flash-model",
65
+ "gemini-flash-model",
66
+ "gemini-lite-model",
67
+ "minimax-m3-model",
68
+ "qwen-3.7-plus-model",
69
+ "qwen-3.7-max-model",
70
+ "gpt-5.5-model",
71
+ "claude-opus-model",
72
+ ]
46
73
 
47
74
 
48
75
  class McpToolRateLimitHints(BaseModel):
@@ -601,7 +628,7 @@ class ExecuteSessionResult(BaseModel):
601
628
  # from the query; this is a soft hint rather than a hard switch.
602
629
  QueryDepth = Literal["fast", "auto", "deep"]
603
630
  QueryOutcomeType = Literal["answer", "capability_miss"]
604
- QueryResponseShape = Literal["answer", "answer_with_evidence", "evidence_only"]
631
+ QueryResponseShape = Literal["answer_with_evidence", "evidence_only"]
605
632
  QueryAttemptForkReason = Literal[
606
633
  "manual_fork",
607
634
  "bounded_rediscovery",
@@ -674,7 +701,7 @@ class QueryOptions(BaseModel):
674
701
  Attributes:
675
702
  query: The natural-language question to answer
676
703
  tools: Optional tool IDs to use (auto-discover if not provided)
677
- answer_model_id: Optional answer model ID for final synthesis
704
+ agent_model_id: Optional model ID for the main librarian agent loop
678
705
  include_data: Include execution data inline in the query response
679
706
  include_data_url: Persist execution data to blob and return URL
680
707
  include_developer_trace: Include machine-readable developer runtime traces
@@ -703,22 +730,27 @@ class QueryOptions(BaseModel):
703
730
  "Ignored when explicit tools are provided."
704
731
  ),
705
732
  )
706
- answer_model_id: str | None = Field(
733
+ agent_model_id: AgentModelId | str | None = Field(
707
734
  default=None,
708
- alias="answerModelId",
709
- description="Optional answer model ID for final synthesis",
735
+ alias="agentModelId",
736
+ description=(
737
+ "Optional model ID for the main librarian agent loop. Controls the "
738
+ "merged iterative execution + final response stage; internal tool "
739
+ "selection remains managed by the server."
740
+ ),
710
741
  )
711
742
  response_shape: QueryResponseShape | None = Field(
712
743
  default=None,
713
744
  alias="responseShape",
714
745
  description=(
715
- "Structured response mode. The runtime always produces a grounded "
716
- "result (raw data + computed artifacts + provenance); this controls "
717
- "whether a prose synthesis layer is added on top. "
746
+ "Structured response mode. Defaults to `answer_with_evidence` on the "
747
+ "server when omitted. The runtime always produces a grounded result "
748
+ "(raw data + computed artifacts + provenance); this controls whether "
749
+ "a prose synthesis layer is added on top. "
718
750
  "`answer_with_evidence` returns prose plus the structured grounding "
719
751
  "(chat parity); `evidence_only` returns grounding only with no prose "
720
752
  "(the agent-harness shape, with raw data + computed_artifacts + "
721
- "grounding by default); `answer` is the legacy prose-only shape."
753
+ "grounding by default)."
722
754
  ),
723
755
  )
724
756
  include_data: bool | None = Field(
@@ -14,7 +14,7 @@ uvicorn[standard]>=0.30.0
14
14
  hummingbot-api-client>=1.2.6
15
15
 
16
16
  # Context Protocol SDK for payment verification
17
- ctxprotocol>=0.8.3
17
+ ctxprotocol>=0.16.0
18
18
 
19
19
  # Environment management
20
20
  python-dotenv>=1.0.0
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "ctxprotocol"
7
- version = "0.15.0"
7
+ version = "0.17.0"
8
8
  description = "Official Python SDK for the Context Protocol - Discover and execute AI tools programmatically"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -468,7 +468,7 @@ class TestQueryRun:
468
468
  mock_stream.return_value = _make_done_stream_response(success_with_data)
469
469
  result = await client.query.run(
470
470
  query="Analyze whale activity",
471
- answer_model_id="glm-model",
471
+ agent_model_id="kimi-k2.6-model",
472
472
  response_shape="answer_with_evidence",
473
473
  include_data=True,
474
474
  include_data_url=True,
@@ -482,7 +482,7 @@ class TestQueryRun:
482
482
  "query": "Analyze whale activity",
483
483
  "tools": None,
484
484
  "stream": True,
485
- "answerModelId": "glm-model",
485
+ "agentModelId": "kimi-k2.6-model",
486
486
  "responseShape": "answer_with_evidence",
487
487
  "includeData": True,
488
488
  "includeDataUrl": True,
@@ -571,7 +571,9 @@ class TestQueryRun:
571
571
  def test_query_options_supports_public_aliases(self) -> None:
572
572
  """QueryOptions accepts supported public aliases."""
573
573
  trace_alias = QueryOptions(query="test", includeDeveloperTrace=True)
574
- answer_model_alias = QueryOptions(query="test", answerModelId="glm-model")
574
+ agent_model_alias = QueryOptions(
575
+ query="test", agentModelId="kimi-k2.6-model"
576
+ )
575
577
  resume_alias = QueryOptions(
576
578
  query="test",
577
579
  resumeFrom={
@@ -596,10 +598,10 @@ class TestQueryRun:
596
598
  assert (
597
599
  trace_alias.model_dump(by_alias=True)["includeDeveloperTrace"] is True
598
600
  )
599
- assert answer_model_alias.answer_model_id == "glm-model"
601
+ assert agent_model_alias.agent_model_id == "kimi-k2.6-model"
600
602
  assert (
601
- answer_model_alias.model_dump(by_alias=True)["answerModelId"]
602
- == "glm-model"
603
+ agent_model_alias.model_dump(by_alias=True)["agentModelId"]
604
+ == "kimi-k2.6-model"
603
605
  )
604
606
  assert response_shape_alias.response_shape == "evidence_only"
605
607
  assert (
@@ -1216,7 +1218,7 @@ class TestQueryStream:
1216
1218
  events = []
1217
1219
  async for event in client.query.stream(
1218
1220
  query="test",
1219
- answer_model_id="claude-sonnet-model",
1221
+ agent_model_id="claude-sonnet-model",
1220
1222
  include_data=True,
1221
1223
  include_data_url=True,
1222
1224
  include_developer_trace=True,
@@ -1225,7 +1227,7 @@ class TestQueryStream:
1225
1227
 
1226
1228
  call_kwargs = mock_stream.call_args
1227
1229
  assert (
1228
- call_kwargs[1]["json_body"]["answerModelId"]
1230
+ call_kwargs[1]["json_body"]["agentModelId"]
1229
1231
  == "claude-sonnet-model"
1230
1232
  )
1231
1233
  assert call_kwargs[1]["json_body"]["includeData"] is True
@@ -205,7 +205,7 @@ wheels = [
205
205
 
206
206
  [[package]]
207
207
  name = "ctxprotocol"
208
- version = "0.14.0"
208
+ version = "0.17.0"
209
209
  source = { editable = "." }
210
210
  dependencies = [
211
211
  { name = "cryptography" },
File without changes
File without changes