7dfc9968fe
apps/:新增「基于 DeerFlow 的应用」目录,与 backend/、frontend/ 平级, 位于「app 消费 deerflow、不反向依赖」边界的正确侧。含两种集成示例: - examples/http-chat —— HTTP Gateway (REST+SSE),含登录/CSRF/建线程/流式对话 - examples/embedded-chat —— 进程内直接调 DeerFlowClient README 说明边界规则、两种模式、鉴权流程及新建应用约定。 runtime/store:修复 make_store 缺失的 database 段回退。原先 store 工厂只读 legacy 的 checkpointer 段,导致仅配 database:postgres 时,checkpointer 走了 Postgres、但 store 仍回退 InMemoryStore(并打出误导性的「线程列表会丢失」告警, 实际线程在 threads_meta 表里、本就持久)。现对齐 checkpointer 工厂的优先级: checkpointer 段 → database 段 → InMemoryStore;postgres 分支同样剥掉 +asyncpg 方言前缀,使一个 DATABASE_URL 同时满足 SQLAlchemy 与 LangGraph 的 psycopg store。 告警文案也修正为「跨线程 store 数据会丢失」。 tests:新增 test_store_provider.py(3 例,TDD)覆盖 database→postgres 回退、 无配置时的内存回退、以及 checkpointer 段优先级。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
47 lines
1.8 KiB
Python
47 lines
1.8 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
内嵌模式示例:进程内直接把 DeerFlow 当 SDK 调,不起 HTTP。
|
|
|
|
必须在 backend 的 uv 环境里跑(这样才能 import deerflow.*):
|
|
cd backend
|
|
uv run python ../apps/examples/embedded-chat/app.py
|
|
|
|
依赖 config.yaml 里配好至少一个可用模型 + API key(路径解析见根 CLAUDE.md)。
|
|
|
|
API 对照:backend/packages/harness/deerflow/client.py
|
|
"""
|
|
|
|
from deerflow.client import DeerFlowClient
|
|
from deerflow.runtime.checkpointer.provider import get_checkpointer
|
|
|
|
|
|
def main() -> None:
|
|
# checkpointer 提供跨轮状态持久化(sqlite/postgres 由 config.yaml 决定)
|
|
client = DeerFlowClient(
|
|
checkpointer=get_checkpointer(),
|
|
thinking_enabled=True,
|
|
)
|
|
|
|
thread_id = "embedded-demo-1"
|
|
|
|
# ① 流式:stream() 产出 StreamEvent
|
|
print("👤 用一句话介绍你自己,然后心算 17 * 23。\n🤖 ", end="", flush=True)
|
|
for ev in client.stream("用一句话介绍你自己,然后心算 17 * 23。", thread_id=thread_id):
|
|
if ev.type == "messages-tuple" and ev.data.get("type") == "ai":
|
|
print(ev.data.get("content", ""), end="", flush=True) # AI 文本增量
|
|
elif ev.type == "end":
|
|
print(f"\n[usage] {ev.data.get('usage')}")
|
|
|
|
# ② 阻塞式:chat() 直接返回完整 AI 文本(复用 thread_id 即多轮)
|
|
print("\n👤 刚才结果再乘以 2 是多少?")
|
|
answer = client.chat("刚才结果再乘以 2 是多少?", thread_id=thread_id)
|
|
print(f"🤖 {answer}")
|
|
|
|
# 其它能力:list_models() / list_skills() / get_memory() / upload_files() ...
|
|
models = client.list_models().get("models", [])
|
|
print(f"\n[已配置模型] {[m.get('name') for m in models]}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|