amfs-http-server 0.1.1__tar.gz → 0.1.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: amfs-http-server
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: AMFS HTTP/REST API server with SSE support
5
5
  License-Expression: Apache-2.0
6
6
  Requires-Python: >=3.11
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "amfs-http-server"
3
- version = "0.1.1"
3
+ version = "0.1.2"
4
4
  description = "AMFS HTTP/REST API server with SSE support"
5
5
  requires-python = ">=3.11"
6
6
  license = "Apache-2.0"
@@ -1939,6 +1939,92 @@ async def expertise_graph(
1939
1939
  }
1940
1940
 
1941
1941
 
1942
+ @app.post("/api/v1/pro/graph/backfill")
1943
+ async def graph_backfill(
1944
+ _auth: str | None = Depends(verify_api_key),
1945
+ ) -> dict[str, Any]:
1946
+ """Backfill knowledge graph edges from existing entries and outcomes.
1947
+
1948
+ Materializes edges from: pattern_refs → 'references' edges,
1949
+ outcome causal chains → 'informed' + 'read' edges,
1950
+ agent writes → 'wrote' edges.
1951
+ """
1952
+ from amfs_core.models import GraphEdge
1953
+
1954
+ mem = _get_memory()
1955
+ entries = mem.list()
1956
+ outcomes = mem._adapter.list_outcomes(namespace=mem.namespace) if hasattr(mem._adapter, "list_outcomes") else []
1957
+
1958
+ created = 0
1959
+ errors = 0
1960
+
1961
+ for e in entries:
1962
+ aid = e.provenance.agent_id
1963
+ ep = e.entity_path
1964
+ ek = f"{ep}/{e.key}"
1965
+
1966
+ try:
1967
+ mem._adapter.upsert_graph_edge(
1968
+ GraphEdge(
1969
+ source_entity=aid,
1970
+ source_type="agent",
1971
+ relation="wrote",
1972
+ target_entity=ek,
1973
+ target_type="entry",
1974
+ confidence=e.confidence,
1975
+ provenance={"agent_id": aid, "trigger": "backfill"},
1976
+ ),
1977
+ namespace=mem.namespace,
1978
+ branch=e.branch or "main",
1979
+ )
1980
+ created += 1
1981
+ except Exception:
1982
+ errors += 1
1983
+
1984
+ for ref in (e.provenance.pattern_refs or []):
1985
+ try:
1986
+ mem._adapter.upsert_graph_edge(
1987
+ GraphEdge(
1988
+ source_entity=ek,
1989
+ source_type="entry",
1990
+ relation="references",
1991
+ target_entity=ref,
1992
+ target_type="entry",
1993
+ provenance={"agent_id": aid, "trigger": "backfill"},
1994
+ ),
1995
+ namespace=mem.namespace,
1996
+ branch=e.branch or "main",
1997
+ )
1998
+ created += 1
1999
+ except Exception:
2000
+ errors += 1
2001
+
2002
+ for o in outcomes:
2003
+ otype = getattr(o, "outcome_type", None)
2004
+ edge_conf = 1.0 if otype and otype.value == "success" else 0.7
2005
+ aid = getattr(o, "agent_id", "unknown")
2006
+ for ek in getattr(o, "causal_entry_keys", []):
2007
+ try:
2008
+ mem._adapter.upsert_graph_edge(
2009
+ GraphEdge(
2010
+ source_entity=ek,
2011
+ source_type="entry",
2012
+ relation="informed",
2013
+ target_entity=o.outcome_ref,
2014
+ target_type="outcome",
2015
+ confidence=edge_conf,
2016
+ provenance={"agent_id": aid, "trigger": "backfill"},
2017
+ ),
2018
+ namespace=mem.namespace,
2019
+ branch="main",
2020
+ )
2021
+ created += 1
2022
+ except Exception:
2023
+ errors += 1
2024
+
2025
+ return {"edges_created": created, "errors": errors, "entries_scanned": len(entries), "outcomes_scanned": len(outcomes)}
2026
+
2027
+
1942
2028
  # ──────────────────────────────────────────────────────────────────────
1943
2029
  # Pro — HMO Memory Tiers
1944
2030
  # ──────────────────────────────────────────────────────────────────────
@@ -1955,11 +2041,14 @@ def _compute_tiers(entries: list) -> tuple[dict[str, int], dict[str, float]]:
1955
2041
 
1956
2042
  @app.get("/api/v1/pro/tiers/distribution")
1957
2043
  async def tiers_distribution(
2044
+ agent_id: str | None = Query(None),
1958
2045
  _auth: str | None = Depends(verify_api_key),
1959
2046
  ) -> dict[str, Any]:
1960
2047
  """Return HMO tier distribution (Hot / Warm / Archive)."""
1961
2048
  mem = _get_memory()
1962
2049
  entries = mem.list()
2050
+ if agent_id:
2051
+ entries = [e for e in entries if e.provenance.agent_id == agent_id]
1963
2052
 
1964
2053
  tiers, scores = _compute_tiers(entries)
1965
2054
 
@@ -1991,11 +2080,14 @@ async def tiers_distribution(
1991
2080
  async def tiers_entries(
1992
2081
  tier: int = Query(..., ge=1, le=3),
1993
2082
  limit: int = Query(50, ge=1, le=500),
2083
+ agent_id: str | None = Query(None),
1994
2084
  _auth: str | None = Depends(verify_api_key),
1995
2085
  ) -> list[dict[str, Any]]:
1996
2086
  """Return entries for a given HMO tier as a flat array."""
1997
2087
  mem = _get_memory()
1998
2088
  entries = mem.list()
2089
+ if agent_id:
2090
+ entries = [e for e in entries if e.provenance.agent_id == agent_id]
1999
2091
 
2000
2092
  tier_map, score_map = _compute_tiers(entries)
2001
2093