diff --git a/src/open_storyline/agent.py b/src/open_storyline/agent.py index 98431ce..8f4954e 100644 --- a/src/open_storyline/agent.py +++ b/src/open_storyline/agent.py @@ -5,6 +5,10 @@ import httpx +from open_storyline.compat.langgraph_runtime import ensure_langgraph_runtime_compat + +ensure_langgraph_runtime_compat() + from langchain.agents import create_agent from langchain_openai import ChatOpenAI @@ -239,4 +243,4 @@ def _norm_url(u: str) -> str: store=store, context_schema=ClientContext, ) - return agent, node_manager \ No newline at end of file + return agent, node_manager diff --git a/src/open_storyline/compat/langgraph_runtime.py b/src/open_storyline/compat/langgraph_runtime.py new file mode 100644 index 0000000..4355a88 --- /dev/null +++ b/src/open_storyline/compat/langgraph_runtime.py @@ -0,0 +1,41 @@ +from __future__ import annotations + +from dataclasses import dataclass + + +def ensure_langgraph_runtime_compat() -> None: + """Backfill runtime symbols expected by newer langgraph-prebuilt. + + Some dependency combinations expose only ``Runtime`` in ``langgraph.runtime``, + while newer ``langgraph-prebuilt`` imports ``ExecutionInfo`` and ``ServerInfo`` + for type annotations. These placeholders are sufficient because the symbols are + not used for runtime behavior in this project path. + """ + + try: + import langgraph.runtime as runtime_mod # type: ignore + except Exception: + return + + if not hasattr(runtime_mod, "ExecutionInfo"): + @dataclass + class ExecutionInfo: # pragma: no cover - compatibility shim + pass + + runtime_mod.ExecutionInfo = ExecutionInfo # type: ignore[attr-defined] + + if not hasattr(runtime_mod, "ServerInfo"): + @dataclass + class ServerInfo: # pragma: no cover - compatibility shim + pass + + runtime_mod.ServerInfo = ServerInfo # type: ignore[attr-defined] + + # Newer langgraph-prebuilt accesses runtime.execution_info/server_info. + # Older langgraph Runtime does not define them, so add class-level fallbacks. + runtime_cls = getattr(runtime_mod, "Runtime", None) + if runtime_cls is not None: + if not hasattr(runtime_cls, "execution_info"): + setattr(runtime_cls, "execution_info", None) + if not hasattr(runtime_cls, "server_info"): + setattr(runtime_cls, "server_info", None) diff --git a/src/open_storyline/skills/skills_io.py b/src/open_storyline/skills/skills_io.py index 4d26b03..7b14fc3 100644 --- a/src/open_storyline/skills/skills_io.py +++ b/src/open_storyline/skills/skills_io.py @@ -1,9 +1,13 @@ - import aiofiles from pathlib import Path from skillkit import SkillManager from skillkit.integrations.langchain import create_langchain_tools + +from open_storyline.compat.langgraph_runtime import ensure_langgraph_runtime_compat + +ensure_langgraph_runtime_compat() + from langchain.agents import create_agent from langchain_openai import ChatOpenAI from langchain.messages import HumanMessage