mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-09-09 21:49:37 +00:00
fix: support Studio file-based app loading (#4838)
* fix: support Studio file-based app loading * docs: clarify Studio loader invariant
This commit is contained in:
parent
16ecf7b006
commit
a181c3398b
@ -400,6 +400,8 @@ cannot restore server privileges or be discarded by the runtime's startup
|
|||||||
cleanup. Keep the backend dependencies synchronized with `uv sync`; this
|
cleanup. Keep the backend dependencies synchronized with `uv sync`; this
|
||||||
compatibility path requires the declared LangGraph runtime versions and logs a
|
compatibility path requires the declared LangGraph runtime versions and logs a
|
||||||
warning if the persisted-store contract no longer matches its expectations.
|
warning if the persisted-store contract no longer matches its expectations.
|
||||||
|
The documented command uses LangGraph's file-based custom-app loader, which is
|
||||||
|
also covered directly by DeerFlow's regression tests.
|
||||||
|
|
||||||
For workflows that invoke `backend/langgraph.json` through LangGraph Studio or
|
For workflows that invoke `backend/langgraph.json` through LangGraph Studio or
|
||||||
a direct LangGraph Server, DeerFlow consumes the authenticated identity
|
a direct LangGraph Server, DeerFlow consumes the authenticated identity
|
||||||
|
|||||||
@ -298,6 +298,8 @@ reactivate server-only privileges or be discarded by runtime startup cleanup.
|
|||||||
Run `uv sync` after dependency changes; this compatibility path requires the
|
Run `uv sync` after dependency changes; this compatibility path requires the
|
||||||
declared LangGraph runtime versions and warns when the persisted-store contract
|
declared LangGraph runtime versions and warns when the persisted-store contract
|
||||||
does not match its expectations.
|
does not match its expectations.
|
||||||
|
The same file-based custom-app loading path used by this command is covered by
|
||||||
|
the backend regression suite.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@ -23,12 +23,16 @@ genuine system assistant IDs from the CLI-provided graph registry, removes
|
|||||||
their persisted active/version rows so graph registration recreates them, and
|
their persisted active/version rows so graph registration recreates them, and
|
||||||
demotes every other legacy `created_by=system` marker in both active assistants
|
demotes every other legacy `created_by=system` marker in both active assistants
|
||||||
and version history. This must happen before runtime 0.30.0 loads and purges
|
and version history. This must happen before runtime 0.30.0 loads and purges
|
||||||
system-marked rows; a user application lifespan is too late. An empty graph
|
system-marked rows; a user application lifespan is too late. LangGraph executes
|
||||||
registry or absent persistence file is a no-op, while persistence parse/write
|
this file-backed custom app without first registering its module in
|
||||||
errors fail startup closed. The harness requires in-memory runtime 0.30.0 or
|
`sys.modules`; keep its annotations eager so dataclass processing remains
|
||||||
newer, and a persisted store containing no expected registered assistant row
|
compatible with that loader, and preserve the direct file-loader regression
|
||||||
emits a drift warning so changes to LangGraph's internal persistence contract
|
test. An empty graph registry or absent persistence file is a no-op, while
|
||||||
are observable. Because current create/update writes and all legacy
|
persistence parse/write errors fail startup closed. The harness requires
|
||||||
|
in-memory runtime 0.30.0 or newer, and a persisted store containing no
|
||||||
|
expected registered assistant row emits a drift warning so changes to
|
||||||
|
LangGraph's internal persistence contract are observable. Because current
|
||||||
|
create/update writes and all legacy
|
||||||
versions are sanitized, ordinary owner-scoped assistant version selection
|
versions are sanitized, ordinary owner-scoped assistant version selection
|
||||||
remains enabled. Ordinary authenticated users retain owner-scoped assistant
|
remains enabled. Ordinary authenticated users retain owner-scoped assistant
|
||||||
reads/searches.
|
reads/searches.
|
||||||
|
|||||||
@ -3,11 +3,11 @@
|
|||||||
``langgraph dev`` imports this custom application before entering the locked
|
``langgraph dev`` imports this custom application before entering the locked
|
||||||
in-memory runtime lifespan. That ordering is intentional: runtime 0.30.0 loads
|
in-memory runtime lifespan. That ordering is intentional: runtime 0.30.0 loads
|
||||||
and purges persisted ``created_by=system`` assistants before graph registration
|
and purges persisted ``created_by=system`` assistants before graph registration
|
||||||
and before a user application lifespan can run.
|
and before a user application lifespan can run. Keep annotations eager in this
|
||||||
|
module: LangGraph's file loader executes it without first registering the module
|
||||||
|
in ``sys.modules``, which breaks dataclasses with postponed annotations.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|||||||
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import importlib.util
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from uuid import NAMESPACE_DNS, uuid4, uuid5
|
from uuid import NAMESPACE_DNS, uuid4, uuid5
|
||||||
|
|
||||||
@ -198,3 +200,20 @@ def test_langgraph_config_loads_the_pre_runtime_studio_app():
|
|||||||
config = json.loads((Path(__file__).resolve().parents[1] / "langgraph.json").read_text(encoding="utf-8"))
|
config = json.loads((Path(__file__).resolve().parents[1] / "langgraph.json").read_text(encoding="utf-8"))
|
||||||
|
|
||||||
assert config["http"]["app"].endswith("app/gateway/langgraph_studio.py:langgraph_app")
|
assert config["http"]["app"].endswith("app/gateway/langgraph_studio.py:langgraph_app")
|
||||||
|
|
||||||
|
|
||||||
|
def test_studio_app_supports_langgraph_file_loader():
|
||||||
|
"""The CLI executes the custom app without first registering its module."""
|
||||||
|
module_path = Path(__file__).resolve().parents[1] / "app" / "gateway" / "langgraph_studio.py"
|
||||||
|
module_name = f"langgraph_studio_file_loader_{uuid4().hex}"
|
||||||
|
spec = importlib.util.spec_from_file_location(module_name, module_path)
|
||||||
|
|
||||||
|
assert spec is not None
|
||||||
|
assert spec.loader is not None
|
||||||
|
assert module_name not in sys.modules
|
||||||
|
|
||||||
|
module = importlib.util.module_from_spec(spec)
|
||||||
|
spec.loader.exec_module(module)
|
||||||
|
|
||||||
|
assert module_name not in sys.modules
|
||||||
|
assert module.langgraph_app is not None
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user