soothe-client-python 1.0.9__tar.gz → 1.0.10__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.9 → soothe_client_python-1.0.10}/PKG-INFO +1 -1
  2. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/appkit/daemon_session.py +3 -8
  3. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/command_client.py +35 -31
  4. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/protocol_params.py +11 -0
  5. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/.gitignore +0 -0
  6. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/LICENSE +0 -0
  7. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/README.md +0 -0
  8. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/pyproject.toml +0 -0
  9. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/__init__.py +0 -0
  10. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/appkit/__init__.py +0 -0
  11. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/appkit/attachments.py +0 -0
  12. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/appkit/broadcaster.py +0 -0
  13. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/appkit/card_projection.py +0 -0
  14. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/appkit/chunk_filter.py +0 -0
  15. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/appkit/classifier.py +0 -0
  16. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/appkit/events.py +0 -0
  17. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/appkit/loop_session_store.py +0 -0
  18. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/appkit/managed_client.py +0 -0
  19. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/appkit/observability.py +0 -0
  20. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/appkit/pool.py +0 -0
  21. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/appkit/query_gate.py +0 -0
  22. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/appkit/thinking_step.py +0 -0
  23. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/appkit/turn.py +0 -0
  24. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/appkit/turn_boundary.py +0 -0
  25. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/appkit/turn_runner.py +0 -0
  26. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/errors.py +0 -0
  27. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/helpers.py +0 -0
  28. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/intent_hints.py +0 -0
  29. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/py.typed +0 -0
  30. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/schemas.py +0 -0
  31. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/session.py +0 -0
  32. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/stream_terminal.py +0 -0
  33. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/turn_boundary.py +0 -0
  34. {soothe_client_python-1.0.9 → soothe_client_python-1.0.10}/src/soothe_client/websocket.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: soothe-client-python
3
- Version: 1.0.9
3
+ Version: 1.0.10
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
@@ -450,9 +450,7 @@ class DaemonSession:
450
450
  # pre-admit early running can omit turn_id). Idle/stopped
451
451
  # fall through to their gates (cancel idle may omit turn_id).
452
452
  ev_turn_id = frame_turn_id(event)
453
- status_state = (
454
- str(event.get("state") or "") if event_type == "status" else ""
455
- )
453
+ status_state = str(event.get("state") or "") if event_type == "status" else ""
456
454
  is_running_status = status_state == "running"
457
455
  is_terminal_status = status_state in {"idle", "stopped"}
458
456
  if (
@@ -463,8 +461,7 @@ class DaemonSession:
463
461
  and not turn_ids_match(expected_turn_id, ev_turn_id)
464
462
  ):
465
463
  logger.debug(
466
- "Ignoring unbound/mismatched turn_id frame type=%s "
467
- "got=%s expected=%s",
464
+ "Ignoring unbound/mismatched turn_id frame type=%s got=%s expected=%s",
468
465
  event_type,
469
466
  (ev_turn_id or "<absent>")[-24:],
470
467
  expected_turn_id[-24:],
@@ -518,9 +515,7 @@ class DaemonSession:
518
515
  self._expected_turn_id = status_turn
519
516
  elif query_started and state == "stopped":
520
517
  stop_turn = frame_turn_id(event)
521
- if expected_turn_id and not turn_ids_match(
522
- expected_turn_id, stop_turn
523
- ):
518
+ if expected_turn_id and not turn_ids_match(expected_turn_id, stop_turn):
524
519
  continue
525
520
  self.last_turn_end_state = state
526
521
  if ev_seq is not None:
@@ -132,34 +132,6 @@ async def _perform_handshake(ws: Any, *, timeout: float) -> None:
132
132
  raise RuntimeError(f"Daemon state is {state}")
133
133
 
134
134
 
135
- # Command message types
136
- _AUTOPilot_COMMANDS = {
137
- "status": "autopilot_status",
138
- "submit": "autopilot_submit",
139
- "list_goals": "autopilot_list_goals",
140
- "get_goal": "autopilot_get_goal",
141
- "cancel_goal": "autopilot_cancel_goal",
142
- "cancel_all": "autopilot_cancel_all",
143
- "wake": "autopilot_wake",
144
- "dream": "autopilot_dream",
145
- "resume": "autopilot_resume",
146
- "list_jobs": "autopilot_list_jobs",
147
- "get_job": "autopilot_get_job",
148
- }
149
-
150
- _CRON_COMMANDS = {
151
- "add": "cron_add",
152
- "list": "cron_list",
153
- "list_jobs": "cron_list",
154
- "show": "cron_show",
155
- "cancel": "cron_cancel",
156
- }
157
-
158
- _MEMORY_COMMANDS = {
159
- "stats": "memory_stats",
160
- }
161
-
162
-
163
135
  class AsyncCommandClient:
164
136
  """Async client for one-shot daemon RPCs (jobs, autopilot, cron).
165
137
 
@@ -270,12 +242,19 @@ class AsyncCommandClient:
270
242
  return await self._send_command("autopilot_status")
271
243
 
272
244
  async def autopilot_submit(
273
- self, description: str, *, priority: int = 50, workspace: str | None = None
245
+ self,
246
+ description: str,
247
+ *,
248
+ priority: int = 50,
249
+ workspace: str | None = None,
250
+ rail_id: str | None = None,
274
251
  ) -> dict[str, Any]:
275
252
  """Submit a new autopilot goal (returns ``goal_id``)."""
276
253
  payload: dict[str, Any] = {"description": description, "priority": priority}
277
254
  if workspace:
278
255
  payload["workspace"] = workspace
256
+ if rail_id:
257
+ payload["rail_id"] = rail_id
279
258
  return await self._send_command("autopilot_submit", payload)
280
259
 
281
260
  async def autopilot_list_goals(self) -> dict[str, Any]:
@@ -318,6 +297,14 @@ class AsyncCommandClient:
318
297
  """Get a root job with DAG snapshot. Prefer ``job_status`` / ``job_dag``."""
319
298
  return await self._send_command("autopilot_get_job", {"job_id": job_id})
320
299
 
300
+ async def autopilot_top(self, *, include_terminal: bool = False) -> dict[str, Any]:
301
+ """Jobs → goals → loops snapshot for CLI ``top`` (IG-679 / IG-688).
302
+
303
+ Args:
304
+ include_terminal: When true, include terminal goals and jobs.
305
+ """
306
+ return await self._send_command("autopilot_top", {"include_terminal": include_terminal})
307
+
321
308
  async def autopilot_subscribe(self) -> dict[str, Any]:
322
309
  """Subscribe this connection to autopilot worker events."""
323
310
  return await self._send_command("autopilot_subscribe")
@@ -442,13 +429,23 @@ class CommandClient:
442
429
  return cast(dict[str, Any], self._run_async(self._client.autopilot_status()))
443
430
 
444
431
  def autopilot_submit(
445
- self, description: str, *, priority: int = 50, workspace: str | None = None
432
+ self,
433
+ description: str,
434
+ *,
435
+ priority: int = 50,
436
+ workspace: str | None = None,
437
+ rail_id: str | None = None,
446
438
  ) -> dict[str, Any]:
447
439
  """Submit a new autopilot goal."""
448
440
  return cast(
449
441
  dict[str, Any],
450
442
  self._run_async(
451
- self._client.autopilot_submit(description, priority=priority, workspace=workspace)
443
+ self._client.autopilot_submit(
444
+ description,
445
+ priority=priority,
446
+ workspace=workspace,
447
+ rail_id=rail_id,
448
+ )
452
449
  ),
453
450
  )
454
451
 
@@ -488,6 +485,13 @@ class CommandClient:
488
485
  """Get a root job with DAG snapshot."""
489
486
  return cast(dict[str, Any], self._run_async(self._client.autopilot_get_job(job_id)))
490
487
 
488
+ def autopilot_top(self, *, include_terminal: bool = False) -> dict[str, Any]:
489
+ """Jobs → goals → loops snapshot for CLI ``top``."""
490
+ return cast(
491
+ dict[str, Any],
492
+ self._run_async(self._client.autopilot_top(include_terminal=include_terminal)),
493
+ )
494
+
491
495
  def autopilot_subscribe(self) -> dict[str, Any]:
492
496
  """Subscribe to autopilot worker events."""
493
497
  return cast(dict[str, Any], self._run_async(self._client.autopilot_subscribe()))
@@ -38,6 +38,7 @@ __all__ = [
38
38
  "AutopilotResumeParams",
39
39
  "AutopilotListJobsParams",
40
40
  "AutopilotGetJobParams",
41
+ "AutopilotTopParams",
41
42
  # Job RPC params
42
43
  "JobCreateParams",
43
44
  "JobStatusParams",
@@ -401,6 +402,16 @@ class AutopilotGetJobParams(ParamsBase):
401
402
  job_id: str = Field(..., min_length=1)
402
403
 
403
404
 
405
+ class AutopilotTopParams(ParamsBase):
406
+ """Params for ``method=autopilot_top`` (IG-679 / IG-688).
407
+
408
+ Attributes:
409
+ include_terminal: Include terminal goals/jobs when true (default false).
410
+ """
411
+
412
+ include_terminal: bool = False
413
+
414
+
404
415
  # ---------------------------------------------------------------------------
405
416
  # Job RPC params
406
417
  # ---------------------------------------------------------------------------