amfs-adapter-postgres 0.2.0__tar.gz → 0.2.2__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 (17) hide show
  1. {amfs_adapter_postgres-0.2.0 → amfs_adapter_postgres-0.2.2}/.gitignore +3 -0
  2. {amfs_adapter_postgres-0.2.0 → amfs_adapter_postgres-0.2.2}/PKG-INFO +2 -2
  3. {amfs_adapter_postgres-0.2.0 → amfs_adapter_postgres-0.2.2}/pyproject.toml +4 -3
  4. {amfs_adapter_postgres-0.2.0 → amfs_adapter_postgres-0.2.2}/src/amfs_postgres/adapter.py +29 -5
  5. {amfs_adapter_postgres-0.2.0 → amfs_adapter_postgres-0.2.2}/src/amfs_postgres/schema.sql +1 -0
  6. {amfs_adapter_postgres-0.2.0 → amfs_adapter_postgres-0.2.2}/src/amfs_postgres/__init__.py +0 -0
  7. {amfs_adapter_postgres-0.2.0 → amfs_adapter_postgres-0.2.2}/src/amfs_postgres/_fts.py +0 -0
  8. {amfs_adapter_postgres-0.2.0 → amfs_adapter_postgres-0.2.2}/src/amfs_postgres/async_adapter.py +0 -0
  9. {amfs_adapter_postgres-0.2.0 → amfs_adapter_postgres-0.2.2}/src/amfs_postgres/migrations/001_initial.sql +0 -0
  10. {amfs_adapter_postgres-0.2.0 → amfs_adapter_postgres-0.2.2}/src/amfs_postgres/migrations/002_artifact_refs.sql +0 -0
  11. {amfs_adapter_postgres-0.2.0 → amfs_adapter_postgres-0.2.2}/src/amfs_postgres/migrations/002_search_indexes.sql +0 -0
  12. {amfs_adapter_postgres-0.2.0 → amfs_adapter_postgres-0.2.2}/src/amfs_postgres/migrations/003_knowledge_graph.sql +0 -0
  13. {amfs_adapter_postgres-0.2.0 → amfs_adapter_postgres-0.2.2}/src/amfs_postgres/migrations/004_agent_groups.sql +0 -0
  14. {amfs_adapter_postgres-0.2.0 → amfs_adapter_postgres-0.2.2}/src/amfs_postgres/migrations/005_configurable_embedding_dim.sql +0 -0
  15. {amfs_adapter_postgres-0.2.0 → amfs_adapter_postgres-0.2.2}/src/amfs_postgres/migrations/006_is_artifact.sql +0 -0
  16. {amfs_adapter_postgres-0.2.0 → amfs_adapter_postgres-0.2.2}/src/amfs_postgres/migrations/006_outcome_confidence_semantics.sql +0 -0
  17. {amfs_adapter_postgres-0.2.0 → amfs_adapter_postgres-0.2.2}/src/amfs_postgres/tenant_context.py +0 -0
@@ -17,3 +17,6 @@ test.py
17
17
 
18
18
  # pytest temp dirs (created when basetemp lands in the repo)
19
19
  pytest-of-*/
20
+
21
+ # macOS finder metadata, committed three times by accident already.
22
+ .DS_Store
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: amfs-adapter-postgres
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: AMFS Postgres adapter with back-propagation triggers
5
5
  License-Expression: Apache-2.0
6
6
  Requires-Python: >=3.11
7
- Requires-Dist: amfs-core>=0.3.13
7
+ Requires-Dist: amfs-core>=0.3.14
8
8
  Requires-Dist: psycopg-pool>=3.1
9
9
  Requires-Dist: psycopg[binary]<4,>=3.1
@@ -1,12 +1,13 @@
1
1
  [project]
2
2
  name = "amfs-adapter-postgres"
3
- version = "0.2.0"
3
+ version = "0.2.2"
4
4
  description = "AMFS Postgres adapter with back-propagation triggers"
5
5
  requires-python = ">=3.11"
6
6
  license = "Apache-2.0"
7
7
  dependencies = [
8
- # 0.3.13 adds the capture fields this adapter now persists and selects back.
9
- "amfs-core>=0.3.13",
8
+ # 0.3.14 adds the capture fields this adapter now persists and selects back,
9
+ # tool_calls among them.
10
+ "amfs-core>=0.3.14",
10
11
  "psycopg[binary]>=3.1,<4",
11
12
  "psycopg-pool>=3.1",
12
13
  ]
@@ -60,7 +60,9 @@ from amfs_core.models import (
60
60
  QueryEvent,
61
61
  SearchQuery,
62
62
  SemanticQuery,
63
+ SessionMetadata,
63
64
  Tag,
65
+ ToolCall,
64
66
  TraceEntry,
65
67
  )
66
68
 
@@ -603,6 +605,12 @@ class PostgresAdapter(AdapterABC):
603
605
  ALTER TABLE amfs_decision_traces
604
606
  ADD COLUMN IF NOT EXISTS response_text TEXT
605
607
  """)
608
+ # The action side of that pair. Training predicts the action from the
609
+ # request, so a trace carrying only the request is half an example.
610
+ cur.execute("""
611
+ ALTER TABLE amfs_decision_traces
612
+ ADD COLUMN IF NOT EXISTS tool_calls JSONB DEFAULT '[]'
613
+ """)
606
614
  # Entry-to-trace resolution for knowledge lineage. The shared session id
607
615
  # is the only link from a written entry back to the trace that committed
608
616
  # it, since causal_entries records reads rather than writes.
@@ -2539,7 +2547,7 @@ class PostgresAdapter(AdapterABC):
2539
2547
  cur.execute(
2540
2548
  """
2541
2549
  SELECT id, agent_id, session_id, outcome_ref, outcome_type,
2542
- decision_summary, task_input, response_text,
2550
+ decision_summary, task_input, response_text, tool_calls,
2543
2551
  causal_entries, external_contexts,
2544
2552
  query_events, session_started_at, session_ended_at,
2545
2553
  session_duration_ms,
@@ -2567,10 +2575,10 @@ class PostgresAdapter(AdapterABC):
2567
2575
  query_events, session_started_at, session_ended_at,
2568
2576
  session_duration_ms,
2569
2577
  error_events, state_diff, session_metadata, created_at,
2570
- task_input, response_text)
2578
+ task_input, response_text, tool_calls)
2571
2579
  VALUES (%s, %s, %s, %s, %s, %s, %s::jsonb, %s::jsonb,
2572
2580
  %s::jsonb, %s, %s, %s, %s::jsonb, %s::jsonb, %s::jsonb, %s,
2573
- %s, %s)
2581
+ %s, %s, %s::jsonb)
2574
2582
  RETURNING id, created_at
2575
2583
  """,
2576
2584
  (
@@ -2588,10 +2596,22 @@ class PostgresAdapter(AdapterABC):
2588
2596
  trace.session_duration_ms,
2589
2597
  json.dumps([e.model_dump(mode="json") for e in trace.error_events]),
2590
2598
  json.dumps(trace.state_diff.model_dump(mode="json")) if trace.state_diff else None,
2591
- json.dumps(trace.session_metadata) if trace.session_metadata else "{}",
2599
+ # Dumped like every other model field on this row. The
2600
+ # field is typed, so anything arriving over
2601
+ # ``POST /api/v1/traces`` is a ``SessionMetadata`` by the
2602
+ # time it reaches here and ``json.dumps`` cannot encode
2603
+ # it — the trace was lost with a 500. A plain dict still
2604
+ # gets through ``model_copy(update=...)``, which does not
2605
+ # validate, so both shapes are accepted.
2606
+ json.dumps(
2607
+ trace.session_metadata.model_dump(mode="json")
2608
+ if isinstance(trace.session_metadata, SessionMetadata)
2609
+ else trace.session_metadata
2610
+ ) if trace.session_metadata else "{}",
2592
2611
  trace.created_at,
2593
2612
  trace.task_input,
2594
2613
  trace.response_text,
2614
+ json.dumps([t.model_dump(mode="json") for t in trace.tool_calls]),
2595
2615
  ),
2596
2616
  )
2597
2617
  row = cur.fetchone()
@@ -2624,7 +2644,7 @@ class PostgresAdapter(AdapterABC):
2624
2644
  where = " AND ".join(conditions)
2625
2645
  sql = f"""
2626
2646
  SELECT id, agent_id, session_id, outcome_ref, outcome_type,
2627
- decision_summary, task_input, response_text,
2647
+ decision_summary, task_input, response_text, tool_calls,
2628
2648
  causal_entries, external_contexts,
2629
2649
  query_events, session_started_at, session_ended_at,
2630
2650
  session_duration_ms,
@@ -2827,7 +2847,10 @@ class PostgresAdapter(AdapterABC):
2827
2847
  ec_raw = row["external_contexts"] or []
2828
2848
  qe_raw = row.get("query_events") or []
2829
2849
  ee_raw = row.get("error_events") or []
2850
+ tc_raw = row.get("tool_calls") or []
2830
2851
  sd_raw = row.get("state_diff")
2852
+ if isinstance(tc_raw, str):
2853
+ tc_raw = json.loads(tc_raw)
2831
2854
  if isinstance(ce_raw, str):
2832
2855
  ce_raw = json.loads(ce_raw)
2833
2856
  if isinstance(ec_raw, str):
@@ -2856,6 +2879,7 @@ class PostgresAdapter(AdapterABC):
2856
2879
  decision_summary=row.get("decision_summary"),
2857
2880
  task_input=row.get("task_input"),
2858
2881
  response_text=row.get("response_text"),
2882
+ tool_calls=[ToolCall(**t) for t in tc_raw],
2859
2883
  causal_entries=[TraceEntry(**e) for e in ce_raw],
2860
2884
  external_contexts=[ExternalContext(**c) for c in ec_raw],
2861
2885
  query_events=[QueryEvent(**q) for q in qe_raw],
@@ -60,6 +60,7 @@ CREATE TABLE IF NOT EXISTS amfs_decision_traces (
60
60
  decision_summary TEXT,
61
61
  task_input TEXT,
62
62
  response_text TEXT,
63
+ tool_calls JSONB DEFAULT '[]',
63
64
  causal_entries JSONB DEFAULT '[]',
64
65
  external_contexts JSONB DEFAULT '[]',
65
66
  query_events JSONB DEFAULT '[]',