graphharbor-runtime 0.13.0.post33__tar.gz → 0.13.0.post35__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.
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/PKG-INFO +1 -1
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/pyproject.toml +1 -1
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/authorization.py +3 -1
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_event_retention.py +79 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/.gitignore +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/LICENSE +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/README.md +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/__init__.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/auth.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/checkpoint.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/checkpoint_mutations.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/database.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/graph_executor.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/graph_registry.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/lifespan.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/metrics.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/migrate.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/migrations/__init__.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/migrations/env.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/migrations/script.py.mako +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/migrations/versions/001_initial_schema.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/migrations/versions/002_production_runtime.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/migrations/versions/003_cron_scope.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/migrations/versions/004_thread_event_seq.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/migrations/versions/005_run_retry_schedule.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/migrations/versions/006_terminal_events.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/migrations/versions/007_checkpoint_baselines.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/migrations/versions/008_remove_business_scope.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/migrations/versions/009_event_retention_watermarks.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/migrations/versions/__init__.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/models.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/observability.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/ops.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/production.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/production_worker.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/protocol.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/queue.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/redis_stream.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/retry.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/routes.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/run_state.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/run_store.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/schema_setup.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/store.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/src/langgraph_runtime_pg/thread_config.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/conftest.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_business_boundary.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_checkpoint_mutation_safety.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_e2e.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_interface.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_observability.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_official_sdk_contract.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_ops_eager_iterators.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_persistence_contract.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_production_contract.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_public_runtime.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_queue.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_rest_contract.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_run_submission_concurrency.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_runtime_service_p0_e2e.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_schema_setup.py +0 -0
- {graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_vue_protocol_events.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: graphharbor-runtime
|
|
3
|
-
Version: 0.13.0.
|
|
3
|
+
Version: 0.13.0.post35
|
|
4
4
|
Summary: GraphHarbor PostgreSQL and Redis runtime for the LangGraph Agent Server
|
|
5
5
|
Project-URL: Homepage, https://github.com/ljxpython/graphharbor
|
|
6
6
|
Project-URL: Repository, https://github.com/ljxpython/graphharbor
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "graphharbor-runtime"
|
|
3
3
|
# GraphHarbor has its own release line; langgraph-api is compatibility-spike-only.
|
|
4
|
-
version = "0.13.0.
|
|
4
|
+
version = "0.13.0.post35"
|
|
5
5
|
description = "GraphHarbor PostgreSQL and Redis runtime for the LangGraph Agent Server"
|
|
6
6
|
readme = "README.md"
|
|
7
7
|
license = "MIT"
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import inspect
|
|
5
6
|
from collections.abc import Mapping
|
|
6
7
|
from typing import Any, cast
|
|
7
8
|
|
|
@@ -59,7 +60,8 @@ async def authorize(
|
|
|
59
60
|
action=cast(Any, action),
|
|
60
61
|
)
|
|
61
62
|
try:
|
|
62
|
-
|
|
63
|
+
raw_result = handler(ctx=ctx, value=value)
|
|
64
|
+
result: Any = await raw_result if inspect.isawaitable(raw_result) else raw_result
|
|
63
65
|
except Auth.exceptions.HTTPException as exc:
|
|
64
66
|
raise HTTPException(exc.status_code, exc.detail, headers=exc.headers) from exc
|
|
65
67
|
except AssertionError as exc:
|
|
@@ -167,6 +167,85 @@ async def test_redis_heartbeat_outage_does_not_cancel_postgres_owned_run(monkeyp
|
|
|
167
167
|
await asyncio.gather(task, return_exceptions=True)
|
|
168
168
|
|
|
169
169
|
|
|
170
|
+
@pytest.mark.asyncio
|
|
171
|
+
async def test_pruning_waits_for_inflight_thread_replay() -> None:
|
|
172
|
+
assert "graphharbor_event_retention_verify" in os.environ.get("DATABASE_URI", "")
|
|
173
|
+
|
|
174
|
+
from langgraph_runtime_pg.database import connect, start_pool, stop_pool
|
|
175
|
+
from langgraph_runtime_pg.models import AssistantRow, RunRow, RuntimeEventRow, ThreadRow
|
|
176
|
+
from langgraph_runtime_pg.run_store import RunRepository
|
|
177
|
+
|
|
178
|
+
assistant_id, thread_id, run_id = uuid4(), uuid4(), uuid4()
|
|
179
|
+
old = datetime.now(UTC) - timedelta(days=2)
|
|
180
|
+
await start_pool()
|
|
181
|
+
try:
|
|
182
|
+
async with connect() as conn:
|
|
183
|
+
conn.session.add(AssistantRow(assistant_id=assistant_id, graph_id="retention-test"))
|
|
184
|
+
conn.session.add(ThreadRow(thread_id=thread_id, metadata_={}, config={}, interrupts={}))
|
|
185
|
+
conn.session.add(
|
|
186
|
+
RunRow(
|
|
187
|
+
run_id=run_id,
|
|
188
|
+
thread_id=thread_id,
|
|
189
|
+
assistant_id=assistant_id,
|
|
190
|
+
status="success",
|
|
191
|
+
updated_at=old,
|
|
192
|
+
kwargs={},
|
|
193
|
+
metadata_={},
|
|
194
|
+
)
|
|
195
|
+
)
|
|
196
|
+
await conn.session.flush()
|
|
197
|
+
conn.session.add(
|
|
198
|
+
RuntimeEventRow(
|
|
199
|
+
run_id=run_id,
|
|
200
|
+
thread_id=thread_id,
|
|
201
|
+
sequence=1,
|
|
202
|
+
topic="messages",
|
|
203
|
+
payload={"event": "messages"},
|
|
204
|
+
created_at=old,
|
|
205
|
+
)
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
async with connect() as reader:
|
|
209
|
+
thread = await reader.session.scalar(
|
|
210
|
+
select(ThreadRow)
|
|
211
|
+
.where(ThreadRow.thread_id == thread_id)
|
|
212
|
+
.with_for_update(read=True)
|
|
213
|
+
)
|
|
214
|
+
assert thread is not None and thread.event_pruned_through == 0
|
|
215
|
+
|
|
216
|
+
async def prune() -> int:
|
|
217
|
+
async with connect() as writer:
|
|
218
|
+
return await RunRepository().prune_expired_events(
|
|
219
|
+
writer.session, retention_seconds=86400, now=datetime.now(UTC)
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
task = asyncio.create_task(prune())
|
|
223
|
+
try:
|
|
224
|
+
with pytest.raises(TimeoutError):
|
|
225
|
+
await asyncio.wait_for(asyncio.shield(task), timeout=0.2)
|
|
226
|
+
rows = (
|
|
227
|
+
await reader.session.scalars(
|
|
228
|
+
select(RuntimeEventRow).where(RuntimeEventRow.thread_id == thread_id)
|
|
229
|
+
)
|
|
230
|
+
).all()
|
|
231
|
+
assert [row.sequence for row in rows] == [1]
|
|
232
|
+
finally:
|
|
233
|
+
if task.done():
|
|
234
|
+
await task
|
|
235
|
+
assert await asyncio.wait_for(task, timeout=5) == 1
|
|
236
|
+
async with connect() as conn:
|
|
237
|
+
thread = await conn.session.get(ThreadRow, thread_id)
|
|
238
|
+
rows = (
|
|
239
|
+
await conn.session.scalars(
|
|
240
|
+
select(RuntimeEventRow).where(RuntimeEventRow.thread_id == thread_id)
|
|
241
|
+
)
|
|
242
|
+
).all()
|
|
243
|
+
assert thread is not None and thread.event_pruned_through == 1
|
|
244
|
+
assert rows == []
|
|
245
|
+
finally:
|
|
246
|
+
await stop_pool()
|
|
247
|
+
|
|
248
|
+
|
|
170
249
|
@pytest.mark.asyncio
|
|
171
250
|
@pytest.mark.parametrize("terminal_status", ["success", "error"])
|
|
172
251
|
async def test_expired_event_pruning_is_bounded_and_preserves_active_state(
|
|
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
|
{graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_interface.py
RENAMED
|
File without changes
|
{graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_observability.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_public_runtime.py
RENAMED
|
File without changes
|
|
File without changes
|
{graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_rest_contract.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphharbor_runtime-0.13.0.post33 → graphharbor_runtime-0.13.0.post35}/tests/test_schema_setup.py
RENAMED
|
File without changes
|
|
File without changes
|