harness-sdk-python 0.13.2__tar.gz → 0.13.3__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 (31) hide show
  1. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/PKG-INFO +3 -3
  2. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/examples/runs_app.py +7 -7
  3. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/pyproject.toml +2 -2
  4. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/src/harness_sdk/run_manager.py +41 -41
  5. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/run_helpers.py +9 -9
  6. harness_sdk_python-0.13.2/tests/test_ack_visibility.py → harness_sdk_python-0.13.3/tests/test_applied_visibility.py +11 -11
  7. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/test_batches.py +10 -10
  8. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/test_branch_anchor.py +10 -10
  9. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/test_dispatching.py +21 -21
  10. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/test_edit_dispatched.py +8 -8
  11. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/test_edit_reload.py +6 -6
  12. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/test_enqueue.py +18 -18
  13. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/test_input_required.py +20 -20
  14. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/test_meta.py +16 -16
  15. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/test_outcomes.py +9 -9
  16. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/test_placement.py +1 -1
  17. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/test_prepare_hooks.py +4 -4
  18. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/test_restore.py +4 -4
  19. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/test_rewind_during_run.py +6 -6
  20. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/test_settle.py +14 -14
  21. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/test_steer.py +11 -11
  22. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/test_stop_continue.py +22 -22
  23. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/test_stopping_window.py +7 -7
  24. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/.gitignore +0 -0
  25. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/README.md +0 -0
  26. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/examples/__init__.py +0 -0
  27. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/src/harness_sdk/__init__.py +0 -0
  28. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/src/harness_sdk/fenced_postgres.py +0 -0
  29. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/src/harness_sdk/linear_thread.py +0 -0
  30. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/test_fenced_postgres.py +0 -0
  31. {harness_sdk_python-0.13.2 → harness_sdk_python-0.13.3}/tests/test_linear_thread.py +0 -0
@@ -1,11 +1,11 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: harness-sdk-python
3
- Version: 0.13.2
3
+ Version: 0.13.3
4
4
  Summary: RunManager: the harness-sdk runs subsystem for Python Statewire hosts
5
5
  Project-URL: Repository, https://github.com/assistant-ui/harness-sdk
6
6
  License-Expression: MIT
7
7
  Requires-Python: <4.0,>=3.11
8
- Requires-Dist: statewire<0.7,>=0.6.0
8
+ Requires-Dist: statewire<0.8,>=0.7.0
9
9
  Provides-Extra: deepagents
10
10
  Requires-Dist: deepagents>=0.6.12; extra == 'deepagents'
11
11
  Requires-Dist: langchain-core>=0.3; extra == 'deepagents'
@@ -107,7 +107,7 @@ class RunsHost(Statewire):
107
107
  "content": user_text(message),
108
108
  }
109
109
  )
110
- ctx.ack()
110
+ ctx.applied()
111
111
  outcome = await self.stream_turn(ctx)
112
112
  if outcome is not None:
113
113
  return outcome
@@ -158,11 +158,11 @@ class RunsHost(Statewire):
158
158
 
159
159
  @command("run/enqueue")
160
160
  async def run_enqueue(self, params, *, ctx):
161
- return await self.runs.enqueue(params, ack=ctx.ack)
161
+ return await self.runs.enqueue(params, applied=ctx.applied)
162
162
 
163
163
  @command("run/steer")
164
164
  async def run_steer(self, params, *, ctx):
165
- return await self.runs.steer(params, ack=ctx.ack)
165
+ return await self.runs.steer(params, applied=ctx.applied)
166
166
 
167
167
  @command("run/dequeue")
168
168
  async def run_dequeue(self, params):
@@ -170,19 +170,19 @@ class RunsHost(Statewire):
170
170
 
171
171
  @command("run/edit")
172
172
  async def run_edit(self, params, *, ctx):
173
- return await self.runs.edit(params, ack=ctx.ack)
173
+ return await self.runs.edit(params, applied=ctx.applied)
174
174
 
175
175
  @command("run/reload")
176
176
  async def run_reload(self, params, *, ctx):
177
- return await self.runs.reload(params, ack=ctx.ack)
177
+ return await self.runs.reload(params, applied=ctx.applied)
178
178
 
179
179
  @command("run/stop")
180
180
  async def run_stop(self, params=None, *, ctx):
181
- return await self.runs.stop(params, ack=ctx.ack)
181
+ return await self.runs.stop(params, applied=ctx.applied)
182
182
 
183
183
  @command("run/continue")
184
184
  async def run_continue(self, params=None, *, ctx):
185
- return await self.runs.continue_run(ack=ctx.ack)
185
+ return await self.runs.continue_run(applied=ctx.applied)
186
186
 
187
187
  @command("run/input")
188
188
  async def run_input(self, params):
@@ -1,11 +1,11 @@
1
1
  [project]
2
2
  name = "harness-sdk-python"
3
- version = "0.13.2"
3
+ version = "0.13.3"
4
4
  description = "RunManager: the harness-sdk runs subsystem for Python Statewire hosts"
5
5
  readme = "README.md"
6
6
  license = "MIT"
7
7
  requires-python = ">=3.11,<4.0"
8
- dependencies = ["statewire>=0.6.0,<0.7"]
8
+ dependencies = ["statewire>=0.7.0,<0.8"]
9
9
 
10
10
  [project.optional-dependencies]
11
11
  postgres = ["langgraph-checkpoint-postgres>=2.0.0"]
@@ -10,15 +10,15 @@ dispatchable send appends straight into ``dispatching`` — it never transits a
10
10
  queue lane — and everything staged there by the end of the drain dispatches
11
11
  as one run; in error/stop the dispatch is the continuation
12
12
  (``error-continue`` / ``stop-continue``) carrying the send's messages. Every
13
- initiator acks and settles accepted with its state-visible application:
13
+ initiator applies and settles accepted with its state-visible application:
14
14
  the verdict certifies the admission write — sends with their insert (lane
15
15
  or ``dispatching``), mid-run edit/reload with the stopping window,
16
16
  ``run/stop`` with ``stopping`` — never future execution.
17
17
 
18
- ``entry["dispatching"]`` is the dispatch record (absent between an ack and
18
+ ``entry["dispatching"]`` is the dispatch record (absent between an applied and
19
19
  the next dispatch or take): the payload the run callback receives.
20
- ``ctx.ack()`` clears it; ``steering.take()`` may refill it — at most one
21
- unacked batch ever exists. Settle consumes the delivered batch, acked or not;
20
+ ``ctx.applied()`` clears it; ``steering.take()`` may refill it — at most one
21
+ unapplied batch ever exists. Settle consumes the delivered batch, applied or not;
22
22
  steer entries still undelivered in the lane stay queued for the next run.
23
23
 
24
24
  A mid-run stop or rewind opens a stopping window on the entry:
@@ -87,7 +87,7 @@ class _Send:
87
87
  message_id: str
88
88
  source_meta: dict[str, Any] | None
89
89
  meta: Any
90
- ack: Callable[[], None]
90
+ applied: Callable[[], None]
91
91
  run_id: str = ""
92
92
  anchor: Any = _ABSENT
93
93
  anchor_meta: dict[str, Any] | None = None
@@ -107,7 +107,7 @@ class _Edit:
107
107
  source_meta: dict[str, Any]
108
108
  message: dict[str, Any]
109
109
  meta: Any
110
- ack: Callable[[], None]
110
+ applied: Callable[[], None]
111
111
  run_id: str
112
112
  future: "asyncio.Future[Any]" = field(default_factory=_future)
113
113
 
@@ -116,7 +116,7 @@ class _Edit:
116
116
  class _Reload:
117
117
  source_meta: dict[str, Any]
118
118
  meta: Any
119
- ack: Callable[[], None]
119
+ applied: Callable[[], None]
120
120
  run_id: str
121
121
  future: "asyncio.Future[Any]" = field(default_factory=_future)
122
122
 
@@ -145,11 +145,11 @@ class _Rewind:
145
145
  type: str
146
146
  messages: list[dict[str, Any]]
147
147
  rollback_to: Any
148
- ack: Callable[[], None]
148
+ applied: Callable[[], None]
149
149
  future: "asyncio.Future[Any]"
150
150
  run_id: str
151
151
  root_meta: Any = None
152
- acked: bool = False
152
+ applied_sent: bool = False
153
153
 
154
154
 
155
155
  @dataclass
@@ -373,8 +373,8 @@ class RunManager:
373
373
  rollback_to=rewind.rollback_to,
374
374
  root_meta=rewind.root_meta,
375
375
  )
376
- if not rewind.acked:
377
- rewind.ack()
376
+ if not rewind.applied_sent:
377
+ rewind.applied()
378
378
  elif outcome is not None:
379
379
  self._settle_outcome(outcome)
380
380
  else:
@@ -384,8 +384,8 @@ class RunManager:
384
384
  ):
385
385
  assert self._ctx is not None
386
386
  self._ctx.stop_requested.set()
387
- for future, ack, result in fx.staged_sends:
388
- ack()
387
+ for future, applied, result in fx.staged_sends:
388
+ applied()
389
389
  if not future.done():
390
390
  future.set_result(result)
391
391
  for future in fx.continues:
@@ -601,11 +601,11 @@ class RunManager:
601
601
  entry.pop("dispatching", None)
602
602
  entry.pop("stopping", None)
603
603
 
604
- def _ack(self) -> None:
604
+ def _applied(self) -> None:
605
605
  entry = self._entry()
606
606
  record = plain(entry.get("dispatching"))
607
607
  if record is None:
608
- raise RuntimeError("ack() with no unacked batch")
608
+ raise RuntimeError("applied() with no unapplied batch")
609
609
  self._dispatching = []
610
610
  entry.pop("dispatching", None)
611
611
 
@@ -691,8 +691,8 @@ class RunManager:
691
691
  rollback_to=rewind.rollback_to,
692
692
  root_meta=rewind.root_meta,
693
693
  )
694
- rewind.ack()
695
- rewind.acked = True
694
+ rewind.applied()
695
+ rewind.applied_sent = True
696
696
  if not rewind.future.done():
697
697
  rewind.future.set_result(None)
698
698
 
@@ -941,7 +941,7 @@ class RunManager:
941
941
  if live_run_id is not None and e.anchor is not _ABSENT
942
942
  else None
943
943
  )
944
- fx.staged_sends.append((e.future, e.ack, result))
944
+ fx.staged_sends.append((e.future, e.applied, result))
945
945
  return _PARKED
946
946
 
947
947
  def _apply_move(self, e: _Send, fx: _Effects) -> Any:
@@ -981,7 +981,7 @@ class RunManager:
981
981
  "message-edit",
982
982
  [self._stamped(e.message, e.meta)],
983
983
  e.source_meta["parentId"],
984
- e.ack,
984
+ e.applied,
985
985
  e.future,
986
986
  e.run_id,
987
987
  )
@@ -1036,7 +1036,7 @@ class RunManager:
1036
1036
  "message-edit",
1037
1037
  [self._stamped(e.message, e.meta)],
1038
1038
  e.source_meta["parentId"],
1039
- e.ack,
1039
+ e.applied,
1040
1040
  e.future,
1041
1041
  e.run_id,
1042
1042
  )
@@ -1049,7 +1049,7 @@ class RunManager:
1049
1049
  "message-reload",
1050
1050
  [],
1051
1051
  e.source_meta["parentId"],
1052
- e.ack,
1052
+ e.applied,
1053
1053
  e.future,
1054
1054
  e.run_id,
1055
1055
  root_meta=e.meta,
@@ -1064,7 +1064,7 @@ class RunManager:
1064
1064
  lane: str,
1065
1065
  params: Any,
1066
1066
  meta: Any,
1067
- ack: Callable[[], None],
1067
+ applied: Callable[[], None],
1068
1068
  ) -> Any:
1069
1069
  if not isinstance(params, dict):
1070
1070
  raise _reject("invalid-message", "params must be an object")
@@ -1100,7 +1100,7 @@ class RunManager:
1100
1100
  message_id,
1101
1101
  None,
1102
1102
  None,
1103
- ack,
1103
+ applied,
1104
1104
  run_id=run_id,
1105
1105
  anchor=anchor,
1106
1106
  anchor_meta=anchor_meta,
@@ -1117,7 +1117,7 @@ class RunManager:
1117
1117
  message["id"],
1118
1118
  source_meta,
1119
1119
  meta,
1120
- ack,
1120
+ applied,
1121
1121
  run_id=run_id,
1122
1122
  anchor=anchor,
1123
1123
  anchor_meta=anchor_meta,
@@ -1126,14 +1126,14 @@ class RunManager:
1126
1126
  )
1127
1127
 
1128
1128
  async def enqueue(
1129
- self, params: Any, *, meta: Any = None, ack: Callable[[], None]
1129
+ self, params: Any, *, meta: Any = None, applied: Callable[[], None]
1130
1130
  ) -> Any:
1131
- return await self._send("queue", params, meta, ack)
1131
+ return await self._send("queue", params, meta, applied)
1132
1132
 
1133
1133
  async def steer(
1134
- self, params: Any, *, meta: Any = None, ack: Callable[[], None]
1134
+ self, params: Any, *, meta: Any = None, applied: Callable[[], None]
1135
1135
  ) -> Any:
1136
- return await self._send("steerQueue", params, meta, ack)
1136
+ return await self._send("steerQueue", params, meta, applied)
1137
1137
 
1138
1138
  async def dequeue(self, params: Any) -> None:
1139
1139
  message_id = params.get("messageId") if isinstance(params, dict) else None
@@ -1152,7 +1152,7 @@ class RunManager:
1152
1152
  raise _reject("capability-missing", "the rewind capability is not enabled")
1153
1153
 
1154
1154
  async def edit(
1155
- self, params: Any, *, meta: Any = None, ack: Callable[[], None]
1155
+ self, params: Any, *, meta: Any = None, applied: Callable[[], None]
1156
1156
  ) -> Any:
1157
1157
  self._check_rewind_gate("run/edit")
1158
1158
  run_id = _run_id_of(params)
@@ -1176,11 +1176,11 @@ class RunManager:
1176
1176
  ):
1177
1177
  raise _reject("duplicate-id", f"message id {message['id']} is already used")
1178
1178
  return await self._stage(
1179
- _Edit(source_id, source_meta, message, meta, ack, run_id)
1179
+ _Edit(source_id, source_meta, message, meta, applied, run_id)
1180
1180
  )
1181
1181
 
1182
1182
  async def reload(
1183
- self, params: Any, *, meta: Any = None, ack: Callable[[], None]
1183
+ self, params: Any, *, meta: Any = None, applied: Callable[[], None]
1184
1184
  ) -> Any:
1185
1185
  self._check_rewind_gate("run/reload")
1186
1186
  run_id = _run_id_of(params)
@@ -1204,9 +1204,9 @@ class RunManager:
1204
1204
  "capability-missing",
1205
1205
  "the assistant-continuation capability is not enabled",
1206
1206
  )
1207
- return await self._stage(_Reload(source_meta, meta, ack, run_id))
1207
+ return await self._stage(_Reload(source_meta, meta, applied, run_id))
1208
1208
 
1209
- async def stop(self, params: Any = None, *, ack: Callable[[], None]) -> Any:
1209
+ async def stop(self, params: Any = None, *, applied: Callable[[], None]) -> Any:
1210
1210
  if params is not None and not isinstance(params, dict):
1211
1211
  raise _reject("invalid-message", "params must be an object")
1212
1212
  reason = (params or {}).get("reason", _ABSENT)
@@ -1224,7 +1224,7 @@ class RunManager:
1224
1224
  self._stop_reason = reason
1225
1225
  entry = _Stop()
1226
1226
  self._intake.append(entry)
1227
- ack()
1227
+ applied()
1228
1228
  self._schedule(self._drain)
1229
1229
  return await entry.future
1230
1230
 
@@ -1274,7 +1274,7 @@ class RunManager:
1274
1274
  response = self._validated_response(request["type"], params["response"])
1275
1275
  return await self._stage(_Input(request_id, response, meta))
1276
1276
 
1277
- async def continue_run(self, *, meta: Any = None, ack: Callable[[], None]) -> Any:
1277
+ async def continue_run(self, *, meta: Any = None, applied: Callable[[], None]) -> Any:
1278
1278
  status = self._status()
1279
1279
  if status not in ("error", "stopped"):
1280
1280
  raise _reject("wrong-state", f"run/continue is rejected in {status}")
@@ -1287,7 +1287,7 @@ class RunManager:
1287
1287
  )
1288
1288
  entry = _Continue(meta)
1289
1289
  self._intake.append(entry)
1290
- ack()
1290
+ applied()
1291
1291
  self._schedule(self._drain)
1292
1292
  return await entry.future
1293
1293
 
@@ -1340,12 +1340,12 @@ class RunManager:
1340
1340
  _ctx: "RunManager.RunContext"
1341
1341
 
1342
1342
  def take(self) -> tuple[dict[str, Any], ...]:
1343
- """Drain the steer lane into a fresh dispatch record; requires the current batch to be acked."""
1343
+ """Drain the steer lane into a fresh dispatch record; requires the current batch to be applied."""
1344
1344
  self._ctx._ensure_active()
1345
1345
  manager = self._ctx._manager
1346
1346
  entry = manager._entry()
1347
1347
  if plain(entry.get("dispatching")) is not None:
1348
- raise RuntimeError("take before the current batch is acked")
1348
+ raise RuntimeError("take before the current batch is applied")
1349
1349
  items = manager._lane_items("steerQueue")
1350
1350
  if not items:
1351
1351
  return ()
@@ -1410,10 +1410,10 @@ class RunManager:
1410
1410
  if self._manager._ctx is not self:
1411
1411
  raise RuntimeError("this run has already settled")
1412
1412
 
1413
- def ack(self) -> None:
1414
- """Ack the current batch: clears the dispatch record."""
1413
+ def applied(self) -> None:
1414
+ """Applied the current batch: clears the dispatch record."""
1415
1415
  self._ensure_active()
1416
- self._manager._ack()
1416
+ self._manager._applied()
1417
1417
 
1418
1418
  def set_recovery_state(self, value: Any) -> None:
1419
1419
  self._ensure_active()
@@ -16,8 +16,8 @@ class Call:
16
16
  ctx: RunManager.RunContext
17
17
  outcome: "asyncio.Future[Any]"
18
18
 
19
- def ack(self) -> None:
20
- self.ctx.ack()
19
+ def applied(self) -> None:
20
+ self.ctx.applied()
21
21
 
22
22
  def finish(self, outcome: Any) -> None:
23
23
  self.outcome.set_result(outcome)
@@ -87,11 +87,11 @@ def make_host(
87
87
 
88
88
  @command("run/enqueue")
89
89
  async def run_enqueue(self, params, *, ctx):
90
- return await self.runs.enqueue(params, meta=_meta(params), ack=ctx.ack)
90
+ return await self.runs.enqueue(params, meta=_meta(params), applied=ctx.applied)
91
91
 
92
92
  @command("run/steer")
93
93
  async def run_steer(self, params, *, ctx):
94
- return await self.runs.steer(params, meta=_meta(params), ack=ctx.ack)
94
+ return await self.runs.steer(params, meta=_meta(params), applied=ctx.applied)
95
95
 
96
96
  @command("run/dequeue")
97
97
  async def run_dequeue(self, params):
@@ -99,19 +99,19 @@ def make_host(
99
99
 
100
100
  @command("run/edit")
101
101
  async def run_edit(self, params, *, ctx):
102
- return await self.runs.edit(params, meta=_meta(params), ack=ctx.ack)
102
+ return await self.runs.edit(params, meta=_meta(params), applied=ctx.applied)
103
103
 
104
104
  @command("run/reload")
105
105
  async def run_reload(self, params, *, ctx):
106
- return await self.runs.reload(params, meta=_meta(params), ack=ctx.ack)
106
+ return await self.runs.reload(params, meta=_meta(params), applied=ctx.applied)
107
107
 
108
108
  @command("run/stop")
109
109
  async def run_stop(self, params=None, *, ctx):
110
- return await self.runs.stop(params, ack=ctx.ack)
110
+ return await self.runs.stop(params, applied=ctx.applied)
111
111
 
112
112
  @command("run/continue")
113
113
  async def run_continue(self, params=None, *, ctx):
114
- return await self.runs.continue_run(meta=_meta(params), ack=ctx.ack)
114
+ return await self.runs.continue_run(meta=_meta(params), applied=ctx.applied)
115
115
 
116
116
  @command("run/input")
117
117
  async def run_input(self, params):
@@ -205,7 +205,7 @@ class RunDriver:
205
205
  return await self.res(self._seq)
206
206
 
207
207
  async def res(self, seq: int, *, terminal: bool = True) -> dict[str, Any]:
208
- # A payload-less accept rides only the ack; rejections and late
208
+ # A payload-less accept rides only the legacy ack; rejections and late
209
209
  # settles ride res.
210
210
  while True:
211
211
  entries = self._res.get(seq, [])
@@ -1,8 +1,8 @@
1
- """Contract: acks ride visibility. A send's covering ack only rides an
1
+ """Contract: applied rides visibility. A send's covering applied only rides an
2
2
  envelope whose state carries the command's effect — the item in a published
3
3
  queue lane or in ``dispatching``. An idle send's insert lands in
4
- ``dispatching`` directly, so its ack rides the dispatch envelope and the queue
5
- lane never holds the item; a rewind's ack rides its dispatch the same way."""
4
+ ``dispatching`` directly, so its applied rides the dispatch envelope and the queue
5
+ lane never holds the item; a rewind's applied rides its dispatch the same way."""
6
6
 
7
7
  import copy
8
8
 
@@ -35,7 +35,7 @@ def assert_never_queued(drv, message_id):
35
35
  assert message_id not in queue_ids(state, "queue")
36
36
 
37
37
 
38
- async def test_idle_send_acks_with_its_dispatching_insert():
38
+ async def test_idle_send_applies_with_its_dispatching_insert():
39
39
  script = Script()
40
40
  async with run_host(script) as (drv, host):
41
41
  seq = drv.post("run/enqueue", add("m1"))
@@ -44,23 +44,23 @@ async def test_idle_send_acks_with_its_dispatching_insert():
44
44
  assert dispatching_ids(covered_state(drv, seq)) == ["m1"]
45
45
  assert_never_queued(drv, "m1")
46
46
  host.live.state["messages"] = [msg("m1")]
47
- call.ack()
47
+ call.applied()
48
48
  call.finish(RunManager.Complete())
49
49
 
50
50
 
51
- async def test_parked_send_acks_with_its_queue_insert():
51
+ async def test_parked_send_applies_with_its_queue_insert():
52
52
  script = Script()
53
53
  async with run_host(script) as (drv, host):
54
54
  drv.post("run/enqueue", add("m1"))
55
55
  call = await script.next_call()
56
- call.ack()
56
+ call.applied()
57
57
  res = await drv.command("run/enqueue", add("m2"))
58
58
  assert res["type"] == "accepted"
59
59
  assert "m2" in queue_ids(covered_state(drv, res["seq"]), "queue")
60
60
  call.finish(RunManager.Complete())
61
61
 
62
62
 
63
- async def test_unacked_run_end_consumes_the_direct_dispatch():
63
+ async def test_unapplied_run_end_consumes_the_direct_dispatch():
64
64
  script = Script()
65
65
  async with run_host(script) as (drv, host):
66
66
  seq = drv.post("run/enqueue", add("m1"))
@@ -72,7 +72,7 @@ async def test_unacked_run_end_consumes_the_direct_dispatch():
72
72
  assert queue_ids(drv.replica, "queue") == []
73
73
 
74
74
 
75
- async def test_unacked_run_end_consumes_the_direct_steer_send():
75
+ async def test_unapplied_run_end_consumes_the_direct_steer_send():
76
76
  script = Script()
77
77
  async with run_host(script) as (drv, host):
78
78
  seq = drv.post("run/steer", add("s1"))
@@ -85,7 +85,7 @@ async def test_unacked_run_end_consumes_the_direct_steer_send():
85
85
  assert queue_ids(drv.replica, "queue") == []
86
86
 
87
87
 
88
- async def test_rewind_edit_acks_with_its_dispatch():
88
+ async def test_rewind_edit_applies_with_its_dispatch():
89
89
  script = Script()
90
90
  script.thread["u1"] = {"parentId": None, "role": "user", "isLeaf": True}
91
91
  async with run_host(script, capabilities=("rewind",)) as (drv, host):
@@ -95,6 +95,6 @@ async def test_rewind_edit_acks_with_its_dispatch():
95
95
  await drv.wait_status("running")
96
96
  assert dispatching_ids(covered_state(drv, seq)) == ["u2"]
97
97
  host.live.state["messages"] = [msg("u2")]
98
- rerun.ack()
98
+ rerun.applied()
99
99
  rerun.finish(RunManager.Complete())
100
100
  assert (await drv.res(seq))["type"] == "accepted"
@@ -25,7 +25,7 @@ async def test_multi_steer_batch_places_all_and_dispatches_once():
25
25
  assert [m["id"] for m in call.ctx.messages] == ["s1", "s2", "s3"]
26
26
  script.no_call()
27
27
  assert queue_ids(drv.replica, "steerQueue") == []
28
- call.ack()
28
+ call.applied()
29
29
  call.finish(RunManager.Complete())
30
30
  for offset in range(3):
31
31
  assert (await drv.res(first + offset))["type"] == "accepted"
@@ -45,7 +45,7 @@ async def test_same_tick_sends_dispatch_as_one_run():
45
45
  merged = await drv.res(first + 1)
46
46
  assert merged["type"] == "accepted"
47
47
  assert merged["payload"] == {"runId": mint["runId"]}
48
- call.ack()
48
+ call.applied()
49
49
  call.finish(RunManager.Complete())
50
50
 
51
51
 
@@ -54,7 +54,7 @@ async def test_steer_and_stop_in_one_batch_nets_to_stop():
54
54
  async with run_host(script) as (drv, host):
55
55
  drv.post("run/enqueue", add("m1"))
56
56
  call = await script.next_call()
57
- call.ack()
57
+ call.applied()
58
58
  first = drv.batch(
59
59
  [("run/steer", add("s1")), ("run/stop", {"runId": await drv.run_id()})]
60
60
  )
@@ -72,7 +72,7 @@ async def test_stop_settles_at_the_stopping_write():
72
72
  async with run_host(script) as (drv, host):
73
73
  drv.post("run/enqueue", add("m1"))
74
74
  call = await script.next_call()
75
- call.ack()
75
+ call.applied()
76
76
  settled = await drv.stop()
77
77
  assert settled["type"] == "accepted"
78
78
  assert drv.replica["status"] == "running"
@@ -104,10 +104,10 @@ async def test_handler_tail_staging_decides_in_its_own_envelope():
104
104
  )
105
105
  )
106
106
  # The decide ran outside the batch segment: its ops flush in an
107
- # envelope of their own, carrying the send's covering ack.
107
+ # envelope of their own, carrying the send's covering applied.
108
108
  assert dispatch_env.get("ack", 0) >= seq
109
109
  assert (await drv.res(seq))["type"] == "accepted"
110
- call.ack()
110
+ call.applied()
111
111
 
112
112
 
113
113
  async def test_rewind_outranks_send_and_continue_in_one_batch():
@@ -129,7 +129,7 @@ async def test_rewind_outranks_send_and_continue_in_one_batch():
129
129
  "isLeaf": True,
130
130
  "onActiveBranch": True,
131
131
  }
132
- call.ack()
132
+ call.applied()
133
133
  call.fail(RuntimeError("boom"))
134
134
  await drv.wait_status("error")
135
135
  first = drv.batch(
@@ -147,7 +147,7 @@ async def test_rewind_outranks_send_and_continue_in_one_batch():
147
147
  assert (await drv.res(first + 1))["type"] == "accepted"
148
148
  assert (await drv.res(first + 2))["type"] == "accepted"
149
149
  assert queue_ids(drv.replica, "queue") == ["q1"]
150
- rerun.ack()
150
+ rerun.applied()
151
151
  rerun.finish(RunManager.Complete())
152
152
 
153
153
 
@@ -156,7 +156,7 @@ async def test_send_outranks_the_completing_input_answer():
156
156
  async with run_host(script) as (drv, host):
157
157
  drv.post("run/enqueue", add("m1"))
158
158
  call = await script.next_call()
159
- call.ack()
159
+ call.applied()
160
160
  request = {"type": "tool-call", "id": "r1", "toolCallId": "tc1"}
161
161
  call.finish(RunManager.InputRequired((request,)))
162
162
  await drv.wait_status("input-required")
@@ -173,6 +173,6 @@ async def test_send_outranks_the_completing_input_answer():
173
173
  script.no_call()
174
174
  assert (await drv.res(first))["type"] == "accepted"
175
175
  assert (await drv.res(first + 1))["type"] == "accepted"
176
- run.ack()
176
+ run.applied()
177
177
  run.finish(RunManager.Complete())
178
178
  await drv.wait_status("ready")
@@ -48,7 +48,7 @@ async def test_anchorless_send_targets_the_live_run():
48
48
  script = Script()
49
49
  async with run_host(script) as (drv, host):
50
50
  drv.post("run/enqueue", add("m1"))
51
- (await script.next_call()).ack()
51
+ (await script.next_call()).applied()
52
52
  res = await drv.command(
53
53
  "run/steer", {"runId": await drv.run_id(), "message": msg("s1")}, terminal=False
54
54
  )
@@ -60,7 +60,7 @@ async def test_null_anchor_valid_only_on_an_empty_thread():
60
60
  script = Script()
61
61
  async with run_host(script) as (drv, host):
62
62
  drv.post("run/enqueue", add("m1"))
63
- (await script.next_call()).ack()
63
+ (await script.next_call()).applied()
64
64
  script.thread["m1"] = {
65
65
  "parentId": None, "role": "user", "isLeaf": True, "onActiveBranch": True
66
66
  }
@@ -82,7 +82,7 @@ async def test_active_branch_anchor_accepted_off_branch_and_unknown_rejected():
82
82
  )
83
83
  async with run_host(script) as (drv, host):
84
84
  drv.post("run/enqueue", add("m1", anchor="a1"))
85
- (await script.next_call()).ack()
85
+ (await script.next_call()).applied()
86
86
  assert_rejected(
87
87
  await drv.command("run/enqueue", add("m2", anchor="old"), terminal=False),
88
88
  "wrong-anchor",
@@ -97,7 +97,7 @@ async def test_queued_item_and_dispatched_ids_are_valid_anchors():
97
97
  script = Script()
98
98
  async with run_host(script) as (drv, host):
99
99
  drv.post("run/enqueue", add("m1"))
100
- (await script.next_call()).ack()
100
+ (await script.next_call()).applied()
101
101
  await drv.command("run/enqueue", add("m2", anchor="m1"), terminal=False)
102
102
  await drv.command("run/steer", add("s1", anchor="m2"), terminal=False)
103
103
  assert queue_ids(drv.replica, "queue") == ["m2"]
@@ -113,7 +113,7 @@ async def test_replaced_tail_anchor_rejects_after_an_edit_rewrite():
113
113
  )
114
114
  async with run_host(script, capabilities=("rewind",)) as (drv, host):
115
115
  drv.post("run/edit", edit_params("u1", msg("m2"), anchor=None))
116
- (await script.next_call()).ack()
116
+ (await script.next_call()).applied()
117
117
  script.thread["u1"] = {
118
118
  "parentId": None, "role": "user", "isLeaf": True, "onActiveBranch": False
119
119
  }
@@ -128,7 +128,7 @@ async def test_replaced_tail_anchor_rejects_after_an_edit_rewrite():
128
128
  assert res["type"] == "pending"
129
129
 
130
130
 
131
- async def test_unacked_edit_crash_invalidates_the_replacement_anchor():
131
+ async def test_unapplied_edit_crash_invalidates_the_replacement_anchor():
132
132
  script = Script()
133
133
  script.thread["u1"] = {
134
134
  "parentId": None, "role": "user", "isLeaf": True, "onActiveBranch": True
@@ -146,12 +146,12 @@ async def test_unacked_edit_crash_invalidates_the_replacement_anchor():
146
146
  assert [m["id"] for m in call.ctx.messages] == ["q1"]
147
147
 
148
148
 
149
- async def test_unacked_recovery_run_keeps_acked_dispatch_anchors():
149
+ async def test_unapplied_recovery_run_keeps_applied_dispatch_anchors():
150
150
  script = Script()
151
151
  async with run_host(script, capabilities=("incomplete-continuation",)) as (drv, host):
152
152
  drv.post("run/enqueue", add("m1"))
153
153
  call = await script.next_call()
154
- call.ack()
154
+ call.applied()
155
155
  call.fail(RuntimeError("boom"))
156
156
  await drv.wait_status("error")
157
157
  await drv.command("run/continue", terminal=False)
@@ -167,7 +167,7 @@ async def test_anchor_on_the_queued_edit_form_is_validated_never_ignored():
167
167
  script = Script()
168
168
  async with run_host(script) as (drv, host):
169
169
  drv.post("run/enqueue", add("m1"))
170
- (await script.next_call()).ack()
170
+ (await script.next_call()).applied()
171
171
  await drv.command("run/enqueue", add("m2", anchor="m1"), terminal=False)
172
172
  assert_rejected(
173
173
  await drv.command(
@@ -197,7 +197,7 @@ async def test_post_reload_sends_anchor_on_the_reload_targets_parent():
197
197
  drv.post("run/reload", reload_params("a1", anchor="u1"))
198
198
  call = await script.next_call()
199
199
  assert call.ctx.trigger == "message-reload"
200
- call.ack()
200
+ call.applied()
201
201
  script.thread["a1"] = {
202
202
  "parentId": "u1", "role": "assistant", "isLeaf": True, "onActiveBranch": False
203
203
  }