amfs-adapter-postgres 0.2.28__tar.gz → 0.2.29__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.
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/PKG-INFO +1 -1
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/pyproject.toml +1 -1
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/adapter.py +53 -22
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/.gitignore +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/__init__.py +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/_fts.py +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/async_adapter.py +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/knn.py +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/migrations/001_initial.sql +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/migrations/002_artifact_refs.sql +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/migrations/002_search_indexes.sql +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/migrations/003_knowledge_graph.sql +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/migrations/004_agent_groups.sql +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/migrations/005_configurable_embedding_dim.sql +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/migrations/006_is_artifact.sql +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/migrations/006_outcome_confidence_semantics.sql +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/migrations/007_outcome_propagation_row_copy.sql +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/migrations/008_outcome_evidence.sql +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/migrations/009_action_priors.sql +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/migrations/010_local_evidence.sql +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/migrations/011_outcome_task_text.sql +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/retention.py +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/schema.sql +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/tenant_context.py +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/tenant_gucs.py +0 -0
- {amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/trace_partitions.py +0 -0
|
@@ -465,12 +465,26 @@ from amfs_core.aggregates import ( # noqa: E402
|
|
|
465
465
|
RECALL_TOKENS_FLOOR as _RECALL_TOKENS_FLOOR,
|
|
466
466
|
)
|
|
467
467
|
|
|
468
|
+
# Guarded by recall_count, because an entry never recalled contributes zero
|
|
469
|
+
# whatever its size, and ``value::text`` is the expensive part: it serialises
|
|
470
|
+
# the whole JSONB document for every row the aggregate sees. Multiplying that
|
|
471
|
+
# by zero afterwards still paid for it — on 400k entries it was half the
|
|
472
|
+
# ``/stats`` statement (4.8 s → 2.3 s with the guard, same result) and half
|
|
473
|
+
# of ``/entities``. CASE evaluates only the branch taken, so the unrecalled
|
|
474
|
+
# majority of rows skip the serialisation.
|
|
468
475
|
_RECALLED_TOKENS_SQL = (
|
|
469
|
-
"COALESCE(SUM(recall_count * LEAST(GREATEST("
|
|
476
|
+
"COALESCE(SUM(CASE WHEN recall_count > 0 THEN recall_count * LEAST(GREATEST("
|
|
470
477
|
f"length(value::text) / {_CHARS_PER_TOKEN}, {_RECALL_TOKENS_FLOOR}), "
|
|
471
|
-
f"{_RECALL_TOKENS_CEIL})), 0)"
|
|
478
|
+
f"{_RECALL_TOKENS_CEIL}) ELSE 0 END), 0)"
|
|
472
479
|
)
|
|
473
480
|
|
|
481
|
+
#: ``work_mem`` for the grouped aggregate statements below. Grouping 400k
|
|
482
|
+
#: entries by entity_path spilled to disk at the 4 MB default (``Sort Method:
|
|
483
|
+
#: external merge``) and took 1.9 s; at 64 MB the same statement hash-
|
|
484
|
+
#: aggregates in memory in 0.6 s. Set ``LOCAL`` so it ends with the
|
|
485
|
+
#: transaction and cannot leak to whatever borrows the pooled connection next.
|
|
486
|
+
_AGGREGATE_WORK_MEM = "64MB"
|
|
487
|
+
|
|
474
488
|
|
|
475
489
|
class _SingleConnectionPool:
|
|
476
490
|
"""Minimal pool shim wrapping a single connection for environments
|
|
@@ -3360,6 +3374,10 @@ class PostgresAdapter(AdapterABC):
|
|
|
3360
3374
|
"""
|
|
3361
3375
|
with self._pool.connection() as conn:
|
|
3362
3376
|
with conn.cursor() as cur:
|
|
3377
|
+
# The checkout is one transaction (see _TenantRLSConnection),
|
|
3378
|
+
# so LOCAL ends with it and the pooled connection goes back
|
|
3379
|
+
# with the default.
|
|
3380
|
+
cur.execute(f"SET LOCAL work_mem = '{_AGGREGATE_WORK_MEM}'")
|
|
3363
3381
|
cur.execute(sql, params)
|
|
3364
3382
|
rows = cur.fetchall()
|
|
3365
3383
|
|
|
@@ -3537,12 +3555,19 @@ class PostgresAdapter(AdapterABC):
|
|
|
3537
3555
|
|
|
3538
3556
|
with self._pool.connection() as conn:
|
|
3539
3557
|
with conn.cursor() as cur:
|
|
3558
|
+
# The checkout is one transaction (see _TenantRLSConnection),
|
|
3559
|
+
# so LOCAL ends with it and the pooled connection goes back
|
|
3560
|
+
# with the default.
|
|
3561
|
+
cur.execute(f"SET LOCAL work_mem = '{_AGGREGATE_WORK_MEM}'")
|
|
3562
|
+
# No COUNT(DISTINCT ...) here: the two distinct counts are the
|
|
3563
|
+
# row counts of the agent and entity breakdowns below, over the
|
|
3564
|
+
# same WHERE. As aggregates they forced two sorts of every row
|
|
3565
|
+
# and kept the statement off the parallel plan — 2.3 s against
|
|
3566
|
+
# 0.24 s for the same answer on 400k entries.
|
|
3540
3567
|
cur.execute(
|
|
3541
3568
|
f"""
|
|
3542
3569
|
SELECT
|
|
3543
3570
|
COUNT(*) AS total_entries,
|
|
3544
|
-
COUNT(DISTINCT entity_path) AS total_entities,
|
|
3545
|
-
COUNT(DISTINCT agent_id) AS total_agents,
|
|
3546
3571
|
AVG(confidence) AS confidence_avg,
|
|
3547
3572
|
MIN(confidence) AS confidence_min,
|
|
3548
3573
|
MAX(confidence) AS confidence_max,
|
|
@@ -3618,22 +3643,28 @@ class PostgresAdapter(AdapterABC):
|
|
|
3618
3643
|
recalls_this_week = 0
|
|
3619
3644
|
recalls_last_week = 0
|
|
3620
3645
|
try:
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3646
|
+
# Its own savepoint: a failed statement aborts the
|
|
3647
|
+
# transaction it runs in, and this method is inside the
|
|
3648
|
+
# checkout's. Rolling back to the savepoint leaves that
|
|
3649
|
+
# transaction healthy, so the checkout still commits and
|
|
3650
|
+
# the connection goes back to the pool usable.
|
|
3651
|
+
with conn.transaction():
|
|
3652
|
+
cur.execute(
|
|
3653
|
+
f"""
|
|
3654
|
+
SELECT
|
|
3655
|
+
COUNT(*) FILTER (
|
|
3656
|
+
WHERE created_at >= NOW() - INTERVAL '7 days'
|
|
3657
|
+
) AS recalls_this_week,
|
|
3658
|
+
COUNT(*) FILTER (
|
|
3659
|
+
WHERE created_at >= NOW() - INTERVAL '14 days'
|
|
3660
|
+
AND created_at < NOW() - INTERVAL '7 days'
|
|
3661
|
+
) AS recalls_last_week
|
|
3662
|
+
FROM amfs_events
|
|
3663
|
+
WHERE {event_where}
|
|
3664
|
+
""",
|
|
3665
|
+
event_params,
|
|
3666
|
+
)
|
|
3667
|
+
event_row = cur.fetchone()
|
|
3637
3668
|
if event_row:
|
|
3638
3669
|
recalls_this_week = int(event_row["recalls_this_week"] or 0)
|
|
3639
3670
|
recalls_last_week = int(event_row["recalls_last_week"] or 0)
|
|
@@ -3646,8 +3677,8 @@ class PostgresAdapter(AdapterABC):
|
|
|
3646
3677
|
"recalls_this_week": recalls_this_week,
|
|
3647
3678
|
"recalls_last_week": recalls_last_week,
|
|
3648
3679
|
"total_entries": row["total_entries"] if row else 0,
|
|
3649
|
-
"total_entities":
|
|
3650
|
-
"total_agents":
|
|
3680
|
+
"total_entities": len(entity_rows),
|
|
3681
|
+
"total_agents": len(agent_rows),
|
|
3651
3682
|
"agents": {r["agent_id"]: r["cnt"] for r in agent_rows},
|
|
3652
3683
|
"entities": {r["entity_path"]: r["cnt"] for r in entity_rows},
|
|
3653
3684
|
"confidence_avg": float(row["confidence_avg"] or 0) if row else 0.0,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/async_adapter.py
RENAMED
|
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
|
{amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/retention.py
RENAMED
|
File without changes
|
|
File without changes
|
{amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/tenant_context.py
RENAMED
|
File without changes
|
{amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/tenant_gucs.py
RENAMED
|
File without changes
|
{amfs_adapter_postgres-0.2.28 → amfs_adapter_postgres-0.2.29}/src/amfs_postgres/trace_partitions.py
RENAMED
|
File without changes
|