| 12 | |
| 13 | @dataclass |
| 14 | class DifyRuntimeState: |
| 15 | conversation: dict[str, Any] = field(default_factory=dict) |
| 16 | env: dict[str, Any] = field(default_factory=dict) |
| 17 | sys: dict[str, Any] = field(default_factory=dict) |
| 18 | node_outputs: dict[str, dict[str, Any]] = field(default_factory=dict) |
| 19 | workflow_result: dict[str, Any] | None = None |
| 20 | iteration_item: Any = None |
| 21 | loop_index: int | None = None |
| 22 | |
| 23 | @classmethod |
| 24 | def from_store(cls, store: dict[str, Any]) -> DifyRuntimeState: |
| 25 | raw = store.get(STATE_KEY) |
| 26 | if isinstance(raw, DifyRuntimeState): |
| 27 | return raw |
| 28 | if isinstance(raw, dict): |
| 29 | state = cls( |
| 30 | conversation=dict(raw.get("conversation") or {}), |
| 31 | env=dict(raw.get("env") or {}), |
| 32 | sys=dict(raw.get("sys") or {}), |
| 33 | node_outputs={ |
| 34 | str(k): dict(v) if isinstance(v, dict) else {} |
| 35 | for k, v in (raw.get("node_outputs") or {}).items() |
| 36 | }, |
| 37 | workflow_result=dict(raw["workflow_result"]) |
| 38 | if isinstance(raw.get("workflow_result"), dict) |
| 39 | else None, |
| 40 | ) |
| 41 | store[STATE_KEY] = state |
| 42 | return state |
| 43 | state = cls() |
| 44 | store[STATE_KEY] = state |
| 45 | return state |
| 46 | |
| 47 | def attach(self, store: dict[str, Any]) -> None: |
| 48 | store[STATE_KEY] = self |
| 49 | |
| 50 | def set_node_output(self, node_id: str, output: dict[str, Any]) -> None: |
| 51 | self.node_outputs[str(node_id)] = dict(output) |
| 52 | |
| 53 | def get_node_output(self, node_id: str) -> dict[str, Any]: |
| 54 | return dict(self.node_outputs.get(str(node_id), {})) |
| 55 | |
| 56 | def resolve_selector(self, selector: list[Any] | tuple[Any, ...]) -> Any: |
| 57 | if not selector: |
| 58 | return None |
| 59 | head = str(selector[0]) |
| 60 | tail = selector[1:] |
| 61 | |
| 62 | if head == "conversation": |
| 63 | cur: Any = self.conversation |
| 64 | for part in tail: |
| 65 | if not isinstance(cur, dict): |
| 66 | return None |
| 67 | cur = cur.get(str(part)) |
| 68 | return cur |
| 69 | |
| 70 | if head == "env": |
| 71 | cur = self.env |