diff --git a/memory/Dockerfile.hindsight b/memory/Dockerfile.hindsight index 76a5222..5b4b72c 100644 --- a/memory/Dockerfile.hindsight +++ b/memory/Dockerfile.hindsight @@ -2,15 +2,23 @@ FROM ghcr.io/vectorize-io/hindsight:0.8.4@sha256:2c60f233eaba8f51db31adb920a5607 USER root +COPY patches/408d7c34-observation-history-fk-race.patch /tmp/ + # Hindsight runs from its bundled virtualenv and invokes Node directly. Remove -# package managers left by the upstream build and apply available OS fixes. +# package managers left by the upstream build, apply available OS fixes, and +# backport upstream PR #2620 until it is included in a tagged release. RUN apt-get update \ && apt-get upgrade -y --no-install-recommends \ + && apt-get install -y --no-install-recommends patch \ + && patch --batch --forward -d /app/api -p1 \ + < /tmp/408d7c34-observation-history-fk-race.patch \ + && apt-get purge -y --auto-remove patch \ && rm -rf \ /app/sdk/node_modules/@hey-api/openapi-ts \ /usr/lib/node_modules/npm \ /usr/local/lib/python3.11/site-packages/* \ /var/lib/apt/lists/* \ + /tmp/408d7c34-observation-history-fk-race.patch \ && rm -f \ /usr/bin/npm \ /usr/bin/npx \ diff --git a/memory/compose.yml b/memory/compose.yml index ee342c3..25adef8 100644 --- a/memory/compose.yml +++ b/memory/compose.yml @@ -3,7 +3,7 @@ services: build: context: . dockerfile: Dockerfile.hindsight - image: telefire-hindsight:0.8.4-hardened + image: telefire-hindsight:0.8.4-hardened-r1 container_name: memory-api environment: HINDSIGHT_API_LLM_PROVIDER: openai diff --git a/memory/patches/408d7c34-observation-history-fk-race.patch b/memory/patches/408d7c34-observation-history-fk-race.patch new file mode 100644 index 0000000..90c16f3 --- /dev/null +++ b/memory/patches/408d7c34-observation-history-fk-race.patch @@ -0,0 +1,34 @@ +diff --git a/hindsight_api/engine/consolidation/consolidator.py b/hindsight_api/engine/consolidation/consolidator.py +--- a/hindsight_api/engine/consolidation/consolidator.py ++++ b/hindsight_api/engine/consolidation/consolidator.py +@@ -30,0 +31 @@ ++import asyncpg +@@ -1775,15 +1776,22 @@ async def _append_observation_history( + history from growing without bound. + """ + obs_uuid = uuid.UUID(observation_id) +- await conn.execute( +- f""" ++ try: ++ await conn.execute( ++ f""" + INSERT INTO {fq_table("observation_history")} (observation_id, bank_id, content, changed_at) + VALUES ($1, $2, $3::jsonb, now()) + """, +- obs_uuid, +- bank_id, +- json.dumps(asdict(snapshot)), +- ) ++ obs_uuid, ++ bank_id, ++ json.dumps(asdict(snapshot)), ++ ) ++ except asyncpg.exceptions.ForeignKeyViolationError: ++ logger.warning( ++ f"FK violation writing observation_history for {observation_id}: " ++ "observation was removed before history could be written (race with parallel consolidation). Skipping." ++ ) ++ return + if max_entries and max_entries > 0: + await conn.execute( + f"""