- MemoryService 异步路径委托 MemoryIngestService / MemoryRetrievalService;富化派发经 MemoryEnrichmentScheduler - WebSocket pipeline 经 ChatTurnService 与显式 DTO 编排单轮对话;回忆录片段入队由 MemoirIngestScheduler 封装 - 新增 LlmGateway(LlmUseCase),各 agent、任务与适配器对齐 ports - 补充 memory 提示适配、runtime 类型、memory-retrieval 文档、ai-touchpoints 说明与扫描脚本及配套测试 Made-with: Cursor
78 lines
2.1 KiB
Python
78 lines
2.1 KiB
Python
"""Memoir ingest scheduling boundary.
|
|
|
|
The real batching logic still lives in ``BackgroundTaskRunner``. This adapter
|
|
keeps conversation code from depending on that implementation directly.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Literal, Sequence
|
|
|
|
from app.features.memoir.background_runner import BackgroundTaskRunner
|
|
|
|
MemoirTrigger = Literal[
|
|
"turn",
|
|
"conversation_end",
|
|
"manual_flush",
|
|
"evaluation_replay",
|
|
]
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class MemoirPhasePlan:
|
|
"""A visible plan for submitting segments into the memoir pipeline."""
|
|
|
|
user_id: str
|
|
segment_ids: tuple[str, ...]
|
|
trigger: MemoirTrigger
|
|
|
|
|
|
class MemoirIngestScheduler:
|
|
"""Small facade over debounce batching and Phase2 flush dispatch."""
|
|
|
|
def __init__(self, runner: BackgroundTaskRunner | None = None) -> None:
|
|
self._runner = runner or BackgroundTaskRunner()
|
|
|
|
@property
|
|
def runner(self) -> BackgroundTaskRunner:
|
|
"""Compatibility escape hatch for existing tests and eval utilities."""
|
|
|
|
return self._runner
|
|
|
|
async def queue_segment(
|
|
self,
|
|
user_id: str,
|
|
segment_id: str,
|
|
*,
|
|
text_char_count: int = 0,
|
|
trigger: MemoirTrigger = "turn",
|
|
) -> MemoirPhasePlan:
|
|
await self._runner.queue_message(
|
|
user_id,
|
|
segment_id,
|
|
text_char_count=text_char_count,
|
|
)
|
|
return MemoirPhasePlan(
|
|
user_id=user_id,
|
|
segment_ids=(segment_id,),
|
|
trigger=trigger,
|
|
)
|
|
|
|
async def flush_pending(
|
|
self,
|
|
user_id: str,
|
|
*,
|
|
extra_segment_ids: Sequence[str] | None = None,
|
|
trigger: MemoirTrigger = "manual_flush",
|
|
) -> tuple[MemoirPhasePlan, str | None]:
|
|
ids = tuple(str(x) for x in (extra_segment_ids or ()) if str(x).strip())
|
|
task_id = await self._runner.flush_pending(
|
|
user_id,
|
|
extra_segment_ids=list(ids),
|
|
)
|
|
return MemoirPhasePlan(user_id=user_id, segment_ids=ids, trigger=trigger), task_id
|
|
|
|
|
|
__all__ = ["MemoirIngestScheduler", "MemoirPhasePlan", "MemoirTrigger"]
|