Source code for kavalai.workflow.state

"""
Copyright 2026 OÜ KAVAL AI (registry code 17393877)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

from typing import Optional, Literal

from pydantic import BaseModel, Field

WorkflowStatus = Literal["pending", "running", "completed", "failed"]


[docs] class WorkflowState(BaseModel): """Serializable runtime state of a single workflow interaction. The state is JSON round-trippable (``to_json`` / ``from_json``) and is checkpointed to the configured :class:`DataStorage` after every node so a run can be inspected or resumed. workflow_name: name of the workflow being executed. status: lifecycle status of the run. current_node: name of the node about to run / last run. trace: ordered list of executed node names. data: the run context data (``RunContext.data``) passed through ``to_plain``. input_data: the original interaction input. output_data: the value of the end node's output variable (when finished). error: error message when ``status == 'failed'``. invocation_id: short id shared by every log line of this run (for scanning). token_usage: aggregate model token counts for the run. run_id / session_id / agent_id: persistence identifiers (string UUIDs). """ workflow_name: str status: WorkflowStatus = "pending" current_node: Optional[str] = None trace: list[str] = Field(default_factory=list) data: dict = Field(default_factory=dict) input_data: dict = Field(default_factory=dict) output_data: Optional[dict] = None error: Optional[str] = None invocation_id: Optional[str] = None token_usage: Optional[dict] = None run_id: Optional[str] = None session_id: Optional[str] = None agent_id: Optional[str] = None
[docs] def to_json(self) -> str: """Serialize the state to a JSON string.""" return self.model_dump_json()
[docs] @classmethod def from_json(cls, data: str) -> "WorkflowState": """Deserialize a :class:`WorkflowState` from a JSON string.""" return cls.model_validate_json(data)