mirror of
https://github.com/All-Hands-AI/OpenHands.git
synced 2026-04-29 03:00:45 -04:00
* add metrics for total_cost * make lint * refact codeact * change metrics into llm * add costs list, add into state * refactor log completion * refactor and test others * make lint * Update opendevin/core/metrics.py Co-authored-by: Boxuan Li <liboxuan@connect.hku.hk> * Update opendevin/llm/llm.py Co-authored-by: Xingyao Wang <xingyao6@illinois.edu> * refactor * add code --------- Co-authored-by: Boxuan Li <liboxuan@connect.hku.hk> Co-authored-by: Xingyao Wang <xingyao6@illinois.edu>
65 lines
2.3 KiB
Python
65 lines
2.3 KiB
Python
import base64
|
|
import pickle
|
|
from dataclasses import dataclass, field
|
|
|
|
from opendevin.controller.state.task import RootTask
|
|
from opendevin.core.logger import opendevin_logger as logger
|
|
from opendevin.core.metrics import Metrics
|
|
from opendevin.core.schema import AgentState
|
|
from opendevin.events.action import (
|
|
Action,
|
|
MessageAction,
|
|
)
|
|
from opendevin.events.observation import (
|
|
CmdOutputObservation,
|
|
Observation,
|
|
)
|
|
from opendevin.storage import get_file_store
|
|
|
|
|
|
@dataclass
|
|
class State:
|
|
root_task: RootTask = field(default_factory=RootTask)
|
|
iteration: int = 0
|
|
max_iterations: int = 100
|
|
# number of characters we have sent to and received from LLM so far for current task
|
|
num_of_chars: int = 0
|
|
background_commands_obs: list[CmdOutputObservation] = field(default_factory=list)
|
|
history: list[tuple[Action, Observation]] = field(default_factory=list)
|
|
updated_info: list[tuple[Action, Observation]] = field(default_factory=list)
|
|
inputs: dict = field(default_factory=dict)
|
|
outputs: dict = field(default_factory=dict)
|
|
error: str | None = None
|
|
agent_state: AgentState = AgentState.LOADING
|
|
metrics: Metrics = Metrics()
|
|
|
|
def save_to_session(self, sid: str):
|
|
fs = get_file_store()
|
|
pickled = pickle.dumps(self)
|
|
encoded = base64.b64encode(pickled).decode('utf-8')
|
|
try:
|
|
fs.write(f'sessions/{sid}/agent_state.pkl', encoded)
|
|
except Exception as e:
|
|
logger.error(f'Failed to save state to session: {e}')
|
|
raise e
|
|
|
|
@staticmethod
|
|
def restore_from_session(sid: str) -> 'State':
|
|
fs = get_file_store()
|
|
try:
|
|
encoded = fs.read(f'sessions/{sid}/agent_state.pkl')
|
|
pickled = base64.b64decode(encoded)
|
|
state = pickle.loads(pickled)
|
|
except Exception as e:
|
|
logger.error(f'Failed to restore state from session: {e}')
|
|
raise e
|
|
return state
|
|
|
|
def get_current_user_intent(self):
|
|
# TODO: this is used to understand the user's main goal, but it's possible
|
|
# the latest message is an interruption. We should look for a space where
|
|
# the agent goes to FINISHED, and then look for the next user message.
|
|
for action, obs in reversed(self.history):
|
|
if isinstance(action, MessageAction) and action.source == 'user':
|
|
return action.content
|