feat(api): 收敛对话与记忆流程边界,引入 LLM 网关与专用服务

- MemoryService 异步路径委托 MemoryIngestService / MemoryRetrievalService;富化派发经 MemoryEnrichmentScheduler
- WebSocket pipeline 经 ChatTurnService 与显式 DTO 编排单轮对话;回忆录片段入队由 MemoirIngestScheduler 封装
- 新增 LlmGateway(LlmUseCase),各 agent、任务与适配器对齐 ports
- 补充 memory 提示适配、runtime 类型、memory-retrieval 文档、ai-touchpoints 说明与扫描脚本及配套测试

Made-with: Cursor
This commit is contained in:
Kevin
2026-04-30 09:17:01 +08:00
parent eddb2c3078
commit ac436b87a2
37 changed files with 1400 additions and 199 deletions

View File

@@ -52,8 +52,9 @@ class DeepSeekLLMProvider:
*,
temperature: float | None = None,
model: str | None = None,
max_tokens: int | None = None,
) -> str:
llm = self._get_llm(temperature, model)
llm = self._get_llm(temperature, model, max_tokens)
lc_messages = _to_langchain_messages(messages)
result = await llm.ainvoke(lc_messages)
return str(result.content)
@@ -64,21 +65,29 @@ class DeepSeekLLMProvider:
*,
temperature: float | None = None,
model: str | None = None,
max_tokens: int | None = None,
) -> AsyncIterator[str]:
llm = self._get_llm(temperature, model)
llm = self._get_llm(temperature, model, max_tokens)
lc_messages = _to_langchain_messages(messages)
async for chunk in llm.astream(lc_messages):
if chunk.content:
yield str(chunk.content)
def _get_llm(self, temperature: float | None, model: str | None):
if temperature is None and model is None:
def _get_llm(
self,
temperature: float | None,
model: str | None,
max_tokens: int | None = None,
):
if temperature is None and model is None and max_tokens is None:
return self._llm
kwargs: dict = {}
if temperature is not None:
kwargs["temperature"] = temperature
if model is not None:
kwargs["model"] = model
if max_tokens is not None:
kwargs["max_tokens"] = max_tokens
return self._llm.bind(**kwargs) if kwargs else self._llm