soothe-client-python 1.0.14__tar.gz → 1.0.17__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 (34) hide show
  1. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/PKG-INFO +3 -3
  2. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/pyproject.toml +1 -1
  3. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/appkit/daemon_session.py +4 -0
  4. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/command_client.py +37 -4
  5. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/protocol_params.py +4 -0
  6. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/websocket.py +12 -0
  7. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/.gitignore +0 -0
  8. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/LICENSE +0 -0
  9. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/README.md +0 -0
  10. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/__init__.py +0 -0
  11. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/appkit/__init__.py +0 -0
  12. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/appkit/attachments.py +0 -0
  13. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/appkit/broadcaster.py +0 -0
  14. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/appkit/card_projection.py +0 -0
  15. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/appkit/chunk_filter.py +0 -0
  16. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/appkit/classifier.py +0 -0
  17. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/appkit/events.py +0 -0
  18. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/appkit/loop_session_store.py +0 -0
  19. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/appkit/managed_client.py +0 -0
  20. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/appkit/observability.py +0 -0
  21. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/appkit/pool.py +0 -0
  22. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/appkit/query_gate.py +0 -0
  23. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/appkit/thinking_step.py +0 -0
  24. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/appkit/turn.py +0 -0
  25. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/appkit/turn_boundary.py +0 -0
  26. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/appkit/turn_runner.py +0 -0
  27. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/errors.py +0 -0
  28. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/helpers.py +0 -0
  29. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/intent_hints.py +0 -0
  30. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/py.typed +0 -0
  31. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/schemas.py +0 -0
  32. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/session.py +0 -0
  33. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/stream_terminal.py +0 -0
  34. {soothe_client_python-1.0.14 → soothe_client_python-1.0.17}/src/soothe_client/turn_boundary.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: soothe-client-python
3
- Version: 1.0.14
3
+ Version: 1.0.17
4
4
  Summary: WebSocket client + appkit for soothe-daemon (Python)
5
5
  Project-URL: Homepage, https://github.com/mirasoth/soothe-client-python
6
6
  Project-URL: Documentation, https://soothe.readthedocs.io
@@ -21,7 +21,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
21
  Requires-Python: <3.15,>=3.11
22
22
  Requires-Dist: pillow<12.0.0,>=10.0.0
23
23
  Requires-Dist: pydantic<3.0.0,>=2.0.0
24
- Requires-Dist: soothe-sdk<2.0.0,>=1.0.2
24
+ Requires-Dist: soothe-sdk<2.0.0,>=1.0.9
25
25
  Requires-Dist: websockets>=12.0
26
26
  Provides-Extra: dev
27
27
  Requires-Dist: mypy>=1.0.0; extra == 'dev'
@@ -23,7 +23,7 @@ classifiers = [
23
23
  "Topic :: Software Development :: Libraries :: Python Modules",
24
24
  ]
25
25
  dependencies = [
26
- "soothe-sdk>=1.0.2,<2.0.0",
26
+ "soothe-sdk>=1.0.9,<2.0.0",
27
27
  "pydantic>=2.0.0,<3.0.0",
28
28
  "websockets>=12.0",
29
29
  "pillow>=10.0.0,<12.0.0",
@@ -285,6 +285,7 @@ class DaemonSession:
285
285
  router_profile: str | None = None,
286
286
  attachments: list[dict[str, str]] | None = None,
287
287
  clarification_mode: str | None = None,
288
+ interaction_mode: str | None = None,
288
289
  clarification_answer: bool = False,
289
290
  clarification_answers: list[str] | None = None,
290
291
  intent_hint: str | None = None,
@@ -305,6 +306,7 @@ class DaemonSession:
305
306
  router_profile=router_profile,
306
307
  attachments=attachments,
307
308
  clarification_mode=clarification_mode,
309
+ interaction_mode=interaction_mode,
308
310
  clarification_answer=clarification_answer,
309
311
  clarification_answers=clarification_answers,
310
312
  intent_hint=intent_hint,
@@ -750,6 +752,7 @@ class DaemonSession:
750
752
  args: str = "",
751
753
  *,
752
754
  clarification_mode: str | None = None,
755
+ interaction_mode: str | None = None,
753
756
  ) -> dict[str, Any]:
754
757
  """Invoke a skill on the **stream** socket (required for turn enqueue)."""
755
758
  async with self._read_lock:
@@ -758,6 +761,7 @@ class DaemonSession:
758
761
  args,
759
762
  timeout=120.0,
760
763
  clarification_mode=clarification_mode,
764
+ interaction_mode=interaction_mode,
761
765
  )
762
766
 
763
767
  async def _ensure_rpc_connected(self) -> None:
@@ -27,6 +27,12 @@ logger = logging.getLogger(__name__)
27
27
  _TRANSITIONAL_DAEMON_READY_STATES = frozenset({"starting", "warming"})
28
28
  _DAEMON_READY_POLL_INTERVAL_S = 0.05
29
29
 
30
+ # Align with soothe_daemon.config.models.WebSocketConfig.max_frame_size (default 10 MiB)
31
+ # and WebSocketClient._DEFAULT_MAX_FRAME_SIZE. The websockets library defaults
32
+ # max_size to 1 MiB, which closes the connection (1009) when the daemon replies
33
+ # with larger JSON payloads (e.g. autopilot goal forests) to command RPCs.
34
+ _DEFAULT_MAX_FRAME_SIZE = 10 * 1024 * 1024
35
+
30
36
  try:
31
37
  from soothe_sdk import __version__ as _client_version
32
38
  except Exception: # pragma: no cover
@@ -151,11 +157,21 @@ class AsyncCommandClient:
151
157
  Args:
152
158
  ws_url: Daemon WebSocket URL (e.g. ``ws://127.0.0.1:8765``).
153
159
  timeout: Per-command timeout in seconds.
160
+ max_frame_size: Maximum incoming WebSocket message size in bytes. Should be
161
+ at least the daemon's ``transport.websocket.max_frame_size`` when that
162
+ is customized; defaults to 10 MiB to match the daemon default.
154
163
  """
155
164
 
156
- def __init__(self, ws_url: str, *, timeout: float = 30.0) -> None:
165
+ def __init__(
166
+ self,
167
+ ws_url: str,
168
+ *,
169
+ timeout: float = 30.0,
170
+ max_frame_size: int = _DEFAULT_MAX_FRAME_SIZE,
171
+ ) -> None:
157
172
  self._ws_url = ws_url.rstrip("/")
158
173
  self._timeout = timeout
174
+ self._max_frame_size = max_frame_size
159
175
 
160
176
  async def _send_command(
161
177
  self,
@@ -197,7 +213,11 @@ class AsyncCommandClient:
197
213
  )
198
214
 
199
215
  try:
200
- async with websockets.connect(self._ws_url, open_timeout=cmd_timeout) as ws:
216
+ async with websockets.connect(
217
+ self._ws_url,
218
+ open_timeout=cmd_timeout,
219
+ max_size=self._max_frame_size,
220
+ ) as ws:
201
221
  await _perform_handshake(ws, timeout=cmd_timeout)
202
222
 
203
223
  # Send the protocol-1 request envelope.
@@ -411,10 +431,23 @@ class CommandClient:
411
431
  Args:
412
432
  ws_url: Daemon WebSocket URL.
413
433
  timeout: Per-command timeout in seconds.
434
+ max_frame_size: Maximum incoming WebSocket message size in bytes. Should be
435
+ at least the daemon's ``transport.websocket.max_frame_size`` when that
436
+ is customized; defaults to 10 MiB to match the daemon default.
414
437
  """
415
438
 
416
- def __init__(self, ws_url: str, *, timeout: float = 30.0) -> None:
417
- self._client = AsyncCommandClient(ws_url, timeout=timeout)
439
+ def __init__(
440
+ self,
441
+ ws_url: str,
442
+ *,
443
+ timeout: float = 30.0,
444
+ max_frame_size: int = _DEFAULT_MAX_FRAME_SIZE,
445
+ ) -> None:
446
+ self._client = AsyncCommandClient(
447
+ ws_url,
448
+ timeout=timeout,
449
+ max_frame_size=max_frame_size,
450
+ )
418
451
 
419
452
  def _run_async(self, coro: Any) -> Any:
420
453
  """Run an async coroutine from sync code."""
@@ -205,6 +205,7 @@ class LoopInputParams(ParamsBase):
205
205
  response_schema_name: Schema name for logging.
206
206
  response_schema_strict: Enable strict schema validation.
207
207
  clarification_mode: clarification relay mode.
208
+ interaction_mode: CoreAgent interaction mode (``agent``|``ask``).
208
209
  clarification_answer: Mark as answer to pending clarification.
209
210
  clarification_answers: Per-question answers for multi-question clarification.
210
211
  """
@@ -222,6 +223,7 @@ class LoopInputParams(ParamsBase):
222
223
  response_schema_name: str | None = None
223
224
  response_schema_strict: bool | None = None
224
225
  clarification_mode: str | None = Field(default=None, pattern=r"^(auto|manual)$")
226
+ interaction_mode: str | None = Field(default=None, pattern=r"^(agent|ask)$")
225
227
  clarification_answer: bool = False
226
228
  clarification_answers: list[str] | None = None
227
229
 
@@ -591,11 +593,13 @@ class InvokeSkillParams(ParamsBase):
591
593
  skill: Skill name (required).
592
594
  args: Skill arguments.
593
595
  clarification_mode: clarification relay mode.
596
+ interaction_mode: CoreAgent interaction mode (``agent``|``ask``).
594
597
  """
595
598
 
596
599
  skill: str = Field(..., min_length=1)
597
600
  args: str = ""
598
601
  clarification_mode: str | None = Field(default=None, pattern=r"^(auto|manual)$")
602
+ interaction_mode: str | None = Field(default=None, pattern=r"^(agent|ask)$")
599
603
 
600
604
 
601
605
  class McpStatusParams(EmptyParams):
@@ -949,6 +949,7 @@ class WebSocketClient:
949
949
  response_schema_name: str | None = None,
950
950
  response_schema_strict: bool | None = None,
951
951
  clarification_mode: str | None = None,
952
+ interaction_mode: str | None = None,
952
953
  clarification_answer: bool = False,
953
954
  clarification_answers: list[str] | None = None,
954
955
  ) -> None:
@@ -976,6 +977,9 @@ class WebSocketClient:
976
977
  clarification_mode: clarification relay mode for this turn
977
978
  (``"auto"`` / ``"manual"``). ``None`` lets the daemon fall back
978
979
  to its configured default.
980
+ interaction_mode: CoreAgent interaction mode for this turn
981
+ (``"agent"`` / ``"ask"``). ``None`` lets the daemon fall back
982
+ to its configured default.
979
983
  clarification_answer: When True, the daemon treats this input as the
980
984
  answer to the loop's currently pending clarification interrupt and resumes the graph via ``Command(resume=...)``
981
985
  instead of starting a new turn. Hint only — daemon verifies via
@@ -1014,6 +1018,8 @@ class WebSocketClient:
1014
1018
  params["response_schema_strict"] = response_schema_strict
1015
1019
  if clarification_mode is not None:
1016
1020
  params["clarification_mode"] = clarification_mode
1021
+ if interaction_mode is not None:
1022
+ params["interaction_mode"] = interaction_mode
1017
1023
  if clarification_answer:
1018
1024
  params["clarification_answer"] = True
1019
1025
  if clarification_answers is not None:
@@ -1256,6 +1262,7 @@ class WebSocketClient:
1256
1262
  *,
1257
1263
  timeout: float = 120.0,
1258
1264
  clarification_mode: str | None = None,
1265
+ interaction_mode: str | None = None,
1259
1266
  ) -> dict[str, Any]:
1260
1267
  """Resolve a skill on the daemon host and receive echo before streaming.
1261
1268
 
@@ -1269,10 +1276,15 @@ class WebSocketClient:
1269
1276
  configured default. Without this, slash-skill turns ignore
1270
1277
  the client's Manual badge and always defer to the config
1271
1278
  default — typically ``"auto"`` (veritas).
1279
+ interaction_mode: CoreAgent interaction mode for the synthetic turn
1280
+ (``"agent"`` / ``"ask"``). ``None`` lets the daemon fall back
1281
+ to its configured default.
1272
1282
  """
1273
1283
  params: dict[str, Any] = {"skill": skill, "args": args}
1274
1284
  if clarification_mode is not None:
1275
1285
  params["clarification_mode"] = clarification_mode
1286
+ if interaction_mode is not None:
1287
+ params["interaction_mode"] = interaction_mode
1276
1288
  return await self.request("invoke_skill", params, timeout=timeout)
1277
1289
 
1278
1290
  async def fetch_daemon_status(