diff --git a/hindsight-api-slim/hindsight_api/engine/memory_engine.py b/hindsight-api-slim/hindsight_api/engine/memory_engine.py index 4f633e91b..8eb9830e9 100644 --- a/hindsight-api-slim/hindsight_api/engine/memory_engine.py +++ b/hindsight-api-slim/hindsight_api/engine/memory_engine.py @@ -52,6 +52,7 @@ # Context variable for current schema (async-safe, per-task isolation) # Note: default is None, actual default comes from config via get_current_schema() _current_schema: contextvars.ContextVar[str | None] = contextvars.ContextVar("current_schema", default=None) +MENTAL_MODEL_PENDING_CONTENT = "Generating content..." def get_current_schema() -> str: @@ -7596,7 +7597,8 @@ async def refresh_mental_model( # stub out the DB don't hit an unexpected pool access). use_delta = False stored_structured_content: dict[str, Any] | None = None - if refresh_mode == "delta" and current_content: + has_delta_baseline = bool(current_content) and current_content != MENTAL_MODEL_PENDING_CONTENT + if refresh_mode == "delta" and has_delta_baseline: backend = await self._get_backend() async with acquire_with_retry(backend) as conn: tracking_row = await conn.fetchrow( diff --git a/hindsight-api-slim/hindsight_api/engine/providers/openai_compatible_llm.py b/hindsight-api-slim/hindsight_api/engine/providers/openai_compatible_llm.py index 9bb6fdba0..0f02949d5 100644 --- a/hindsight-api-slim/hindsight_api/engine/providers/openai_compatible_llm.py +++ b/hindsight-api-slim/hindsight_api/engine/providers/openai_compatible_llm.py @@ -306,15 +306,19 @@ def __init__( self.api_key = "local" # Validate API key for cloud providers - if self.provider in ( - "openai", - "groq", - "minimax", - "deepseek", - "openrouter", - "zai", - "opencode-go", - ) and not self.api_key: + if ( + self.provider + in ( + "openai", + "groq", + "minimax", + "deepseek", + "openrouter", + "zai", + "opencode-go", + ) + and not self.api_key + ): raise ValueError(f"API key is required for {self.provider}") # Service tier configuration (from config, not env vars) diff --git a/hindsight-api-slim/tests/test_mental_model_delta.py b/hindsight-api-slim/tests/test_mental_model_delta.py index fbbb41952..4f1a18214 100644 --- a/hindsight-api-slim/tests/test_mental_model_delta.py +++ b/hindsight-api-slim/tests/test_mental_model_delta.py @@ -187,6 +187,46 @@ async def test_delta_mode_empty_content_falls_back_to_full( await memory.delete_bank(bank_id, request_context=request_context) + async def test_delta_mode_pending_placeholder_falls_back_to_full( + self, + memory: MemoryEngine, + request_context: RequestContext, + patch_reflect, + patch_llm_call, + ): + """The async creation placeholder is not a real delta baseline. + + A first refresh for a newly-created model must do a full recall over + pre-existing facts instead of scoping recall to last_refreshed_at. + """ + bank_id = f"test-delta-placeholder-{uuid.uuid4().hex[:8]}" + await memory.get_bank_profile(bank_id, request_context=request_context) + + mm = await memory.create_mental_model( + bank_id=bank_id, + name="Backend Overview", + source_query="What is the backend architecture?", + content="Generating content...", + trigger={"mode": "delta"}, + request_context=request_context, + ) + + reflect_calls = patch_reflect(memory, text="# Backend\n\nFull fresh synthesis.") + llm_calls = patch_llm_call(memory, returns="should-not-be-called") + + refreshed = await memory.refresh_mental_model( + bank_id=bank_id, mental_model_id=mm["id"], request_context=request_context + ) + + assert refreshed["content"] == "# Backend\n\nFull fresh synthesis." + assert len(llm_calls) == 0 + assert "created_after" not in reflect_calls[0] + rr = refreshed.get("reflect_response") or {} + assert rr.get("delta_applied") is not True + assert rr.get("delta_skipped_reason") is None + + await memory.delete_bank(bank_id, request_context=request_context) + async def test_delta_mode_source_query_change_falls_back_to_full( self, memory: MemoryEngine, diff --git a/skills/hindsight-docs/references/developer/models.md b/skills/hindsight-docs/references/developer/models.md index b50e625a4..51278726a 100644 --- a/skills/hindsight-docs/references/developer/models.md +++ b/skills/hindsight-docs/references/developer/models.md @@ -30,6 +30,7 @@ Used for fact extraction, entity resolution, mental model consolidation, and ans - MiniMax - DeepSeek - z.ai +- opencode-go - Volcano Engine - OpenRouter - OpenAI Codex diff --git a/skills/hindsight-docs/references/faq.md b/skills/hindsight-docs/references/faq.md index 8b8b96a62..f4f8f2aca 100644 --- a/skills/hindsight-docs/references/faq.md +++ b/skills/hindsight-docs/references/faq.md @@ -76,6 +76,7 @@ Browse all supported integrations in the Integrations Hub. - MiniMax - DeepSeek - z.ai +- opencode-go - Volcano Engine - OpenRouter - OpenAI Codex