soothe-client-python 1.0.15__tar.gz → 1.0.18__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.15 → soothe_client_python-1.0.18}/PKG-INFO +3 -3
  2. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/pyproject.toml +1 -1
  3. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/appkit/daemon_session.py +4 -0
  4. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/protocol_params.py +4 -0
  5. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/websocket.py +102 -0
  6. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/.gitignore +0 -0
  7. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/LICENSE +0 -0
  8. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/README.md +0 -0
  9. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/__init__.py +0 -0
  10. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/appkit/__init__.py +0 -0
  11. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/appkit/attachments.py +0 -0
  12. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/appkit/broadcaster.py +0 -0
  13. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/appkit/card_projection.py +0 -0
  14. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/appkit/chunk_filter.py +0 -0
  15. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/appkit/classifier.py +0 -0
  16. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/appkit/events.py +0 -0
  17. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/appkit/loop_session_store.py +0 -0
  18. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/appkit/managed_client.py +0 -0
  19. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/appkit/observability.py +0 -0
  20. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/appkit/pool.py +0 -0
  21. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/appkit/query_gate.py +0 -0
  22. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/appkit/thinking_step.py +0 -0
  23. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/appkit/turn.py +0 -0
  24. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/appkit/turn_boundary.py +0 -0
  25. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/appkit/turn_runner.py +0 -0
  26. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/command_client.py +0 -0
  27. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/errors.py +0 -0
  28. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/helpers.py +0 -0
  29. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/intent_hints.py +0 -0
  30. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/py.typed +0 -0
  31. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/schemas.py +0 -0
  32. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/session.py +0 -0
  33. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/src/soothe_client/stream_terminal.py +0 -0
  34. {soothe_client_python-1.0.15 → soothe_client_python-1.0.18}/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.15
3
+ Version: 1.0.18
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:
@@ -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:
@@ -1117,6 +1123,96 @@ class WebSocketClient:
1117
1123
  params["as_node"] = as_node
1118
1124
  return await self.request("loop_state_update", params, timeout=timeout)
1119
1125
 
1126
+ async def loop_tree(
1127
+ self,
1128
+ loop_id: str,
1129
+ *,
1130
+ timeout: float = 15.0,
1131
+ ) -> dict[str, Any]:
1132
+ """Fetch the loop checkpoint tree (``loop_tree``)."""
1133
+ return await self.request(
1134
+ "loop_tree",
1135
+ {"loop_id": loop_id},
1136
+ timeout=timeout,
1137
+ )
1138
+
1139
+ async def loop_prune(
1140
+ self,
1141
+ loop_id: str,
1142
+ *,
1143
+ keep_latest: int = 1,
1144
+ timeout: float = 15.0,
1145
+ ) -> dict[str, Any]:
1146
+ """Prune old checkpoints from a loop (``loop_prune``)."""
1147
+ return await self.request(
1148
+ "loop_prune",
1149
+ {"loop_id": loop_id, "keep_latest": keep_latest},
1150
+ timeout=timeout,
1151
+ )
1152
+
1153
+ async def loop_delete(self, loop_id: str, *, timeout: float = 15.0) -> dict[str, Any]:
1154
+ """Delete a loop and its checkpoints (``loop_delete``)."""
1155
+ return await self.request(
1156
+ "loop_delete",
1157
+ {"loop_id": loop_id},
1158
+ timeout=timeout,
1159
+ )
1160
+
1161
+ async def loop_reattach(self, loop_id: str, *, timeout: float = 15.0) -> dict[str, Any]:
1162
+ """Reattach to an existing loop (``loop_reattach``)."""
1163
+ return await self.request(
1164
+ "loop_reattach",
1165
+ {"loop_id": loop_id},
1166
+ timeout=timeout,
1167
+ )
1168
+
1169
+ async def config_get(
1170
+ self,
1171
+ section: str | None = None,
1172
+ *,
1173
+ timeout: float = 10.0,
1174
+ ) -> dict[str, Any]:
1175
+ """Fetch a daemon config section (``config_get``)."""
1176
+ params: dict[str, Any] = {}
1177
+ if section:
1178
+ params["section"] = section
1179
+ return await self.request("config_get", params, timeout=timeout)
1180
+
1181
+ async def config_reload(self, *, timeout: float = 15.0) -> dict[str, Any]:
1182
+ """Reload daemon config from disk (``config_reload``)."""
1183
+ return await self.request("config_reload", {}, timeout=timeout)
1184
+
1185
+ async def daemon_shutdown(self, *, timeout: float = 10.0) -> dict[str, Any]:
1186
+ """Request a graceful daemon shutdown (``daemon_shutdown``)."""
1187
+ return await self.request("daemon_shutdown", {}, timeout=timeout)
1188
+
1189
+ async def authenticate(
1190
+ self,
1191
+ access_key: str,
1192
+ secret_key: str,
1193
+ *,
1194
+ timeout: float = 15.0,
1195
+ ) -> dict[str, Any]:
1196
+ """Submit credentials for daemon-side auth (``auth``)."""
1197
+ return await self.request(
1198
+ "auth",
1199
+ {"access_key": access_key, "secret_key": secret_key},
1200
+ timeout=timeout,
1201
+ )
1202
+
1203
+ async def refresh_auth_token(
1204
+ self,
1205
+ refresh_token: str,
1206
+ *,
1207
+ timeout: float = 15.0,
1208
+ ) -> dict[str, Any]:
1209
+ """Refresh the daemon-side auth token (``auth_refresh``)."""
1210
+ return await self.request(
1211
+ "auth_refresh",
1212
+ {"refresh_token": refresh_token},
1213
+ timeout=timeout,
1214
+ )
1215
+
1120
1216
  def _reset_disconnect_signal(self) -> None:
1121
1217
  """Clear the mid-session drop signal (called from ``connect``)."""
1122
1218
  self._disconn_event = asyncio.Event()
@@ -1256,6 +1352,7 @@ class WebSocketClient:
1256
1352
  *,
1257
1353
  timeout: float = 120.0,
1258
1354
  clarification_mode: str | None = None,
1355
+ interaction_mode: str | None = None,
1259
1356
  ) -> dict[str, Any]:
1260
1357
  """Resolve a skill on the daemon host and receive echo before streaming.
1261
1358
 
@@ -1269,10 +1366,15 @@ class WebSocketClient:
1269
1366
  configured default. Without this, slash-skill turns ignore
1270
1367
  the client's Manual badge and always defer to the config
1271
1368
  default — typically ``"auto"`` (veritas).
1369
+ interaction_mode: CoreAgent interaction mode for the synthetic turn
1370
+ (``"agent"`` / ``"ask"``). ``None`` lets the daemon fall back
1371
+ to its configured default.
1272
1372
  """
1273
1373
  params: dict[str, Any] = {"skill": skill, "args": args}
1274
1374
  if clarification_mode is not None:
1275
1375
  params["clarification_mode"] = clarification_mode
1376
+ if interaction_mode is not None:
1377
+ params["interaction_mode"] = interaction_mode
1276
1378
  return await self.request("invoke_skill", params, timeout=timeout)
1277
1379
 
1278
1380
  async def fetch_daemon_status(