fix(dreamer): threshold and time-guard semantics
Finding 2: filter count_stmt on documents.level == 'explicit' in check_and_schedule_dream. Dreamer-created levels (deductive, inductive, contradiction) are consolidation output, not input, and would otherwise inflate the threshold count and create a feedback loop. Finding 3 (code-level): relocate last_dream_at write from enqueue_dream (enqueue.py) to process_dream (orchestrator.py), inside the 'if result is not None' block. Duplicate enqueues can no longer reset the 8-hour time guard clock. Failed/never-run dreams don't advance it. Success criteria: lenient (any non-null DreamResult counts). Pending Vineeth confirmation — will adjust to strict/middle if requested. Tests pending in follow-up commits. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
952435848c
commit
1487cd269f
|
|
@ -1,5 +1,4 @@
|
|||
import logging
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any, Literal
|
||||
|
||||
from sqlalchemy import exists, insert, select
|
||||
|
|
@ -516,8 +515,8 @@ async def enqueue_dream(
|
|||
stmt = insert(QueueItem).returning(QueueItem)
|
||||
await db_session.execute(stmt, [dream_record])
|
||||
|
||||
# Update collection metadata (CRUD handles cache invalidation)
|
||||
now_iso = datetime.now(timezone.utc).isoformat()
|
||||
# Update collection metadata (CRUD handles cache invalidation).
|
||||
# last_dream_at is written at completion in process_dream, not here.
|
||||
await crud.update_collection_internal_metadata(
|
||||
db_session,
|
||||
workspace_name,
|
||||
|
|
@ -526,7 +525,6 @@ async def enqueue_dream(
|
|||
update_data={
|
||||
"dream": {
|
||||
"last_dream_document_count": document_count,
|
||||
"last_dream_at": now_iso,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -254,11 +254,13 @@ async def check_and_schedule_dream(
|
|||
last_dream_document_count = dream_metadata.get("last_dream_document_count", 0)
|
||||
last_dream_at = dream_metadata.get("last_dream_at")
|
||||
|
||||
# Count current documents in the collection
|
||||
# Count explicit-level docs only: dreamer output (deductive/inductive/
|
||||
# contradiction) would inflate the threshold and create a feedback loop.
|
||||
count_stmt = select(func.count(models.Document.id)).where(
|
||||
models.Document.workspace_name == collection.workspace_name,
|
||||
models.Document.observer == collection.observer,
|
||||
models.Document.observed == collection.observed,
|
||||
models.Document.level == "explicit",
|
||||
)
|
||||
current_document_count = int(await db.scalar(count_stmt) or 0)
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import logging
|
|||
import time
|
||||
import uuid
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any
|
||||
|
||||
import sentry_sdk
|
||||
|
|
@ -323,6 +324,18 @@ DREAM: {payload.dream_type} documents for {workspace_name}/{payload.observer}/{p
|
|||
+ f"duration={result.total_duration_ms:.0f}ms"
|
||||
)
|
||||
|
||||
# Write last_dream_at at completion (not enqueue) so duplicate
|
||||
# enqueues can't reset the 8h guard. Lenient: any non-null result.
|
||||
now_iso = datetime.now(timezone.utc).isoformat()
|
||||
async with tracked_db("dream.last_dream_at_write") as db:
|
||||
await crud.update_collection_internal_metadata(
|
||||
db,
|
||||
workspace_name,
|
||||
payload.observer,
|
||||
payload.observed,
|
||||
update_data={"dream": {"last_dream_at": now_iso}},
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"Error processing dream task {payload.dream_type} for {payload.observer}/{payload.observed}: {str(e)}",
|
||||
|
|
|
|||
Loading…
Reference in New Issue