fleet-memory/hindsight-api-slim/tests
Chris Bartholomew 3fc87e767c
fix(retain): run _ann_seeds temp table inside a transaction (#954)
compute_semantic_links_ann created a TEMP TABLE outside any transaction,
then ran a TRUNCATE / COPY / SELECT / DROP sequence as separate statements
on the same asyncpg connection. This is fine against a direct Postgres
connection but fails intermittently when the caller is routed through
PgBouncer in transaction pool mode:

  CREATE TEMP TABLE IF NOT EXISTS _ann_seeds (...)   -- backend A
  TRUNCATE _ann_seeds                                 -- backend B -> FAILS

Temp tables are session-scoped to the backend that created them. In
PgBouncer transaction mode the backend is only pinned to the client for
the duration of an actual transaction, so between standalone statements
the pooler can (and under concurrency, will) rebind the client to a
different backend. When that happens the _ann_seeds table disappears
and the follow-up statement fails with:

  relation "_ann_seeds" does not exist

Symptom: ~3% of sync retain calls (2 of 61) failed the Hindsight Cloud
smoke test on a recent hindsight-dev deploy. Async retains are masked
by the 3-attempt retry loop so they usually eventually succeed.

Fix: wrap the CREATE TEMP TABLE -> COPY -> SELECT sequence in a single
`async with conn.transaction():` block, and use ON COMMIT DROP so the
temp table is transaction-scoped and auto-cleaned at commit. Also
switch `SET hnsw.ef_search = 60` to `SET LOCAL` so the tuning is
transaction-scoped and no longer leaks onto the pooled backend for
subsequent recall queries. Drop the now-unnecessary manual TRUNCATE,
explicit DROP TABLE, and RESET hnsw.ef_search.

The function docstring still correctly describes this as running on a
separate connection outside the surrounding write transaction — this
change only adds an inner transaction around the ANN work itself to
keep the temp table visible to PgBouncer.

Tests:
- Add TestComputeSemanticLinksAnnPgBouncerSafety with 5 regression
  tests using a mocked connection. These are structural asserts — they
  check that the function enters conn.transaction(), uses ON COMMIT DROP,
  uses SET LOCAL, and does not reintroduce manual TRUNCATE / DROP /
  RESET calls. They would have caught the original bug if they had
  existed, and will catch any future reversion.
2026-04-10 18:36:03 +02:00
..
fixtures feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
__init__.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
conftest.py perf: 3-phase retain pipeline — fix deadlocks, cap temporal links, query-time entity expansion (#722) 2026-04-01 12:52:49 +02:00
test_admin_backup_restore.py fix(migrations): bypass PgBouncer for advisory locks via MIGRATION_DATABASE_URL (#726) 2026-03-27 16:01:38 +01:00
test_agents_api.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_async_batch_retain.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_async_retain_tags.py feat: add HINDSIGHT_API_DEFAULT_BANK_TEMPLATE env var (#966) 2026-04-10 16:41:28 +02:00
test_audit_log.py feat: add audit log for feature usage tracking (#717) 2026-03-27 09:52:03 +01:00
test_bank_templates.py feat: add HINDSIGHT_API_DEFAULT_BANK_TEMPLATE env var (#966) 2026-04-10 16:41:28 +02:00
test_base_path.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_batch_api.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_batch_api_integration.py fix(retain): preserve normalized experience fact types (#848) 2026-04-02 12:20:37 +02:00
test_batch_api_validation.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_batch_chunking.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_causal_relations.py refactor: replace LLMProvider classmethods with from_env() and document missing config fields (#816) 2026-03-31 18:00:41 +02:00
test_causal_relationships.py refactor: replace LLMProvider classmethods with from_env() and document missing config fields (#816) 2026-03-31 18:00:41 +02:00
test_chunking.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_codex_tool_choice.py Convert codex tool_choice test to pytest style (#752) 2026-03-30 11:58:59 +02:00
test_cohere_cross_encoder.py fix(reranker): use httpx for Cohere Azure endpoints to avoid 404 errors (#790) 2026-03-31 17:44:42 +02:00
test_combined_scoring.py fix(recall): cap entity fanout in graph expansion (#911) 2026-04-07 18:59:50 +02:00
test_config_validation.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_consolidation.py fix(consolidation): improve observation quality with structured processing rules (#814) 2026-04-01 12:44:52 +02:00
test_consolidation_failure_recovery.py fix: prevent silent memory loss on consolidation LLM failure (#601) 2026-03-17 20:15:33 +01:00
test_custom_embedding_dimension.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_delta_retain.py feat(retain): delta retain — skip LLM for unchanged chunks on upsert (#701) 2026-03-26 13:50:55 +01:00
test_document_tracking.py feat: expose document_metadata in API and control plane (#798) 2026-03-31 11:42:02 +02:00
test_entity_labels.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_entity_resolver.py fix(entity_resolver): prevent _pending_stats/_pending_cooccurrences memory leak (#662) 2026-03-23 16:06:04 +01:00
test_entity_resolver_pg_trgm.py test: add unit tests for pg_trgm auto-detection and ValidationResult.accept_with() enrichment (#650) 2026-03-23 10:33:09 +01:00
test_experience_fact_type_passthrough.py fix(retain): preserve normalized experience fact types (#848) 2026-04-02 12:20:37 +02:00
test_extensions.py fix(retain): preserve normalized experience fact types (#848) 2026-04-02 12:20:37 +02:00
test_fact_extraction_agent_experience.py refactor: replace LLMProvider classmethods with from_env() and document missing config fields (#816) 2026-03-31 18:00:41 +02:00
test_fact_extraction_analysis.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_fact_extraction_metadata.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_fact_extraction_output_ratio.py refactor: replace LLMProvider classmethods with from_env() and document missing config fields (#816) 2026-03-31 18:00:41 +02:00
test_fact_extraction_quality.py refactor: replace LLMProvider classmethods with from_env() and document missing config fields (#816) 2026-03-31 18:00:41 +02:00
test_fact_extraction_retry.py test: add regression tests for #874 and #894 (#901) 2026-04-07 09:43:25 +02:00
test_fact_ordering.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_file_retain.py Fix non-atomic async operation creation (#619) 2026-03-19 16:38:04 +01:00
test_file_storage_s3.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_format_facts_for_prompt.py feat: include occurred_end and mentioned_at in think-prompt fact serialization (#929) 2026-04-08 10:33:14 +02:00
test_gemini_embeddings.py feat(google): add support for google embeddings and reranker (#863) 2026-04-07 09:15:31 +02:00
test_gemini_safety_settings.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_google_cross_encoder.py feat(google): add support for google embeddings and reranker (#863) 2026-04-07 09:15:31 +02:00
test_graph_entity_fanout_cap.py fix(recall): cap entity fanout in graph expansion (#911) 2026-04-07 18:59:50 +02:00
test_graph_filtering.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_hierarchical_config.py fix: resolve 25 test regressions from streaming retain pipeline (#722) (#836) 2026-04-01 17:59:10 +02:00
test_hnsw_indexes.py fix: per-bank index creation respects HINDSIGHT_API_VECTOR_EXTENSION config (#755) 2026-03-30 11:37:26 +02:00
test_horse_observations.py fix(ci): resolve all CI failures (#847) 2026-04-02 17:17:42 +02:00
test_http_api_integration.py fix(api): clear memories endpoint no longer deletes the bank profile (#837) 2026-04-01 18:34:39 +02:00
test_iris_parser.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_link_expansion_retrieval.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_link_utils.py fix(retain): run _ann_seeds temp table inside a transaction (#954) 2026-04-10 18:36:03 +02:00
test_list_documents.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_litellm_sdk_cross_encoder.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_litellm_sdk_embeddings.py fix: make LiteLLM SDK embeddings encoding_format configurable (#928) 2026-04-08 09:41:11 +02:00
test_llm_provider.py fix(retain): preserve normalized experience fact types (#848) 2026-04-02 12:20:37 +02:00
test_llm_token_metrics.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_llm_tools.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_llm_wrapper.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_lmstudio_tool_choice.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_load_large_batch.py fix: prevent silent memory loss on consolidation LLM failure (#601) 2026-03-17 20:15:33 +01:00
test_main_module.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_mcp_endpoint_routing.py fix: MCP tool calls fail when MCP_AUTH_TOKEN and TENANT_API_KEY differ (#635) 2026-03-20 18:36:05 +01:00
test_mcp_extension.py fix(deps): address critical and high severity security vulnerabilities (#827) 2026-04-01 09:20:34 +02:00
test_mcp_routing.py fix(deps): address critical and high severity security vulnerabilities (#827) 2026-04-01 09:20:34 +02:00
test_mcp_string_coercion.py fix(mcp): auto-coerce string-encoded JSON in tool arguments (#849) (#899) 2026-04-07 09:33:12 +02:00
test_mcp_tool_filtering.py feat(mcp): add filter_mcp_tools hook for per-user tool visibility (#737) 2026-03-30 10:33:09 +02:00
test_mcp_tools.py fix(mcp): validate UUID inputs and add sync_retain tool (#906) 2026-04-07 11:59:59 +02:00
test_mental_model_hooks.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_mental_models.py fix(mental-models): add tags_match and tag_groups to trigger config (#786) (#804) 2026-03-31 18:09:01 +02:00
test_metrics.py fix: make bank_id metric label opt-in to prevent OTel memory leak (#898) 2026-04-07 09:42:59 +02:00
test_migration_backsweep.py fix(migration): backsweep orphaned observation memory units (#584) 2026-03-16 14:06:33 +01:00
test_migrations_thread_safety.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_multilingual.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_none_llm_provider.py feat: add 'none' LLM provider for chunk-only storage mode (#691) 2026-03-25 18:01:20 +01:00
test_observation_invalidation.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_observations.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_op_cancellation.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_per_operation_llm_config.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_provider_default_models.py security: exclude litellm 1.82.8 (supply chain compromise) (#673) 2026-03-25 10:21:02 +01:00
test_query_analyzer.py fix(query_analyzer): handle dateparser internal crashes gracefully (#893) 2026-04-07 09:26:27 +02:00
test_recall_chunks_independence.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_reflect_agent.py Add wall-clock timeout to reflect operations (#643) 2026-03-23 09:19:26 +01:00
test_reflect_empty_based_on.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_reflect_source_facts_config.py feat(reflect): make source facts in search_observations configurable (#688) 2026-03-25 17:54:49 +01:00
test_reflect_tracing.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_reflections.py feat: fact_types and mental model exclusion filters for reflect (#615) 2026-03-19 17:03:41 +01:00
test_reranker_error_handling.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_reranking_proof_count.py fix(recall): cap entity fanout in graph expansion (#911) 2026-04-07 18:59:50 +02:00
test_retain.py fix(ci): resolve all CI failures (#847) 2026-04-02 17:17:42 +02:00
test_retain_append_mode.py feat: add retain update_mode='append' for document content concatenation (#932) 2026-04-08 14:39:16 +02:00
test_schema_isolation.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_search_trace.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_server_module.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_source_facts_tokens.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_sql_schema_safety.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_strip_code_fences.py fix: strip markdown code fences from all LLM providers, not just local (#646) 2026-03-22 21:29:16 +01:00
test_supabase_tenant.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_tags_visibility.py feat: compound tag filtering via tag_groups (#562) 2026-03-13 14:30:11 +01:00
test_tei_cross_encoder.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_temporal_ranges.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_think.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_tracing.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_tracing_integration.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_tracing_spans_verification.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_unknown_params.py feat(api): warn on unknown request parameters via X-Ignored-Params header (#802) 2026-03-31 10:34:04 +02:00
test_validation_result_enrichment.py test: add unit tests for pg_trgm auto-detection and ValidationResult.accept_with() enrichment (#650) 2026-03-23 10:33:09 +01:00
test_vertexai_provider.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_webhooks.py feat: introduce hindsight-api-slim and hindsight-all-slim packages (#560) 2026-03-13 13:50:03 +01:00
test_worker.py fix(ci): resolve all CI failures (#847) 2026-04-02 17:17:42 +02:00