harness-sdk-python 0.36.4__tar.gz → 0.36.5__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.
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/PKG-INFO +1 -1
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/pyproject.toml +1 -1
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/src/harness_sdk/run_manager.py +11 -1
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_run_admission.py +49 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/.gitignore +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/README.md +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/examples/__init__.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/examples/runs_app.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/src/harness_sdk/__init__.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/src/harness_sdk/checkpoints.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/src/harness_sdk/deepagents.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/src/harness_sdk/fenced_postgres.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/src/harness_sdk/langgraph.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/src/harness_sdk/linear_thread.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/src/harness_sdk/protocol.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/src/harness_sdk/voice.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/run_helpers.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_admit_steer.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_applied_visibility.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_batches.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_branch_anchor.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_checkpoints.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_deepagents_messages.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_dispatching.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_durability.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_edit_dispatched.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_edit_reload.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_enqueue.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_fenced_postgres.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_input_required.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_langgraph.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_linear_thread.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_meta.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_mint_concurrency.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_outcomes.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_placement.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_prepare_hooks.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_restore.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_rewind_during_run.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_run_crash_sweep.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_run_eviction.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_run_ownership.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_run_sync.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_settle.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_steer.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_stop_continue.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_stopping_window.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_voice.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_voice_delegation.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/test_voice_frontend_tools.py +0 -0
- {harness_sdk_python-0.36.4 → harness_sdk_python-0.36.5}/tests/voice_helpers.py +0 -0
|
@@ -455,6 +455,12 @@ class RunManager(Tray):
|
|
|
455
455
|
self._replay_settle()
|
|
456
456
|
self._outcome = settled
|
|
457
457
|
recorded = self.outbox.value
|
|
458
|
+
if recorded is not None and not recorded["item"].get("durableAdmission", False):
|
|
459
|
+
self.steerQueue.untake(self.confirmedTakes.value)
|
|
460
|
+
self.confirmedTakes.value = 0
|
|
461
|
+
self.batchApplied.value = False
|
|
462
|
+
recorded = {**recorded, "item": {**recorded["item"], "durableAdmission": True}}
|
|
463
|
+
self.outbox.value = recorded
|
|
458
464
|
if recorded is not None and not self.batchApplied.value:
|
|
459
465
|
record = recorded["item"]["record"]
|
|
460
466
|
lanes = recorded["item"]["lanes"]
|
|
@@ -801,7 +807,11 @@ class RunManager(Tray):
|
|
|
801
807
|
root_meta=root_meta,
|
|
802
808
|
input_outcomes=input_outcomes,
|
|
803
809
|
)
|
|
804
|
-
item = {
|
|
810
|
+
item = {
|
|
811
|
+
"record": record,
|
|
812
|
+
"lanes": [lane for lane, _ in self._batch],
|
|
813
|
+
"durableAdmission": True,
|
|
814
|
+
}
|
|
805
815
|
self.kick()
|
|
806
816
|
self.stopReason.value = None
|
|
807
817
|
self.epoch.value = self.epoch.value + 1
|
|
@@ -144,3 +144,52 @@ async def test_unconfirmed_rewind_replacement_can_be_enqueued_after_stop():
|
|
|
144
144
|
assert [m["id"] for m in retry.ctx.messages] == ["m2"]
|
|
145
145
|
retry.applied()
|
|
146
146
|
retry.finish(RunManager.Complete())
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
@pytest.mark.parametrize("takes", [0, 2])
|
|
150
|
+
@pytest.mark.parametrize("checkpoint", [None, {"graph_input_checkpointed": True}])
|
|
151
|
+
async def test_pre_split_records_replay_inputs_and_restore_confirmed_steers(
|
|
152
|
+
takes, checkpoint
|
|
153
|
+
):
|
|
154
|
+
store = MemoryStateStore()
|
|
155
|
+
script = Script()
|
|
156
|
+
host_type = make_host(script)
|
|
157
|
+
async with instance(host_type, state_store=store) as host:
|
|
158
|
+
await host.runs.enqueue(
|
|
159
|
+
add("m1"), meta={"author": "first"}, applied=lambda: None, auth_result=None
|
|
160
|
+
)
|
|
161
|
+
call = await script.next_call()
|
|
162
|
+
call.ctx.set_state(checkpoint)
|
|
163
|
+
call.applied()
|
|
164
|
+
for index in range(takes):
|
|
165
|
+
await host.runs.steer(
|
|
166
|
+
add(f"s{index}"),
|
|
167
|
+
meta={"author": f"author{index}"},
|
|
168
|
+
applied=lambda: None,
|
|
169
|
+
auth_result=None,
|
|
170
|
+
)
|
|
171
|
+
if takes:
|
|
172
|
+
call.ctx.steering.take()
|
|
173
|
+
call.applied()
|
|
174
|
+
await host.frontier.wait()
|
|
175
|
+
for _, doc in store.trays.values():
|
|
176
|
+
if "outbox" in doc:
|
|
177
|
+
doc["outbox"]["item"].pop("durableAdmission")
|
|
178
|
+
|
|
179
|
+
async with instance(host_type, state_store=store) as host:
|
|
180
|
+
replay = await script.next_call()
|
|
181
|
+
assert not replay.ctx.resume
|
|
182
|
+
assert [m["id"] for m in replay.ctx.messages] == ["m1"]
|
|
183
|
+
assert replay.ctx.meta("m1") == {"author": "first"}
|
|
184
|
+
replay.applied()
|
|
185
|
+
if takes:
|
|
186
|
+
assert [m["id"] for m in replay.ctx.steering.take()] == ["s0", "s1"]
|
|
187
|
+
assert replay.ctx.meta("s0") == {"author": "author0"}
|
|
188
|
+
assert replay.ctx.meta("s1") == {"author": "author1"}
|
|
189
|
+
replay.applied()
|
|
190
|
+
await host.frontier.wait()
|
|
191
|
+
async with instance(host_type, state_store=store):
|
|
192
|
+
confirmed = await script.next_call()
|
|
193
|
+
assert confirmed.ctx.resume
|
|
194
|
+
assert confirmed.ctx.steering.take() == ()
|
|
195
|
+
confirmed.finish(RunManager.Complete())
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|