mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
Rename Conversation to ServerConversation and AppConfig to OpenHandsConfig (#8754)
Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
parent
c76809a766
commit
205f0234e8
@ -17,7 +17,7 @@ from evaluation.utils.shared import (
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
get_parser,
|
||||
)
|
||||
@ -59,10 +59,10 @@ AGENT_CLS_TO_INST_SUFFIX = {
|
||||
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = 'python:3.12-bookworm'
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime='docker',
|
||||
|
||||
@ -25,7 +25,7 @@ from evaluation.utils.shared import (
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
parse_arguments,
|
||||
)
|
||||
@ -39,11 +39,11 @@ from openhands.utils.async_utils import call_async_from_sync
|
||||
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = 'python:3.12-slim'
|
||||
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime=os.environ.get('RUNTIME', 'docker'),
|
||||
|
||||
@ -24,7 +24,7 @@ from evaluation.utils.shared import (
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
load_from_toml,
|
||||
parse_arguments,
|
||||
@ -46,10 +46,10 @@ SKIP_NUM = (
|
||||
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = 'python:3.11-bookworm'
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime=os.environ.get('RUNTIME', 'docker'),
|
||||
|
||||
@ -22,7 +22,7 @@ from evaluation.utils.shared import (
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
parse_arguments,
|
||||
)
|
||||
@ -55,12 +55,12 @@ FILE_EXT_MAP = {
|
||||
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
BIOCODER_BENCH_CONTAINER_IMAGE = 'public.ecr.aws/i5g0m1f6/eval_biocoder:v1.0'
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = BIOCODER_BENCH_CONTAINER_IMAGE
|
||||
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime='docker',
|
||||
|
||||
@ -25,7 +25,7 @@ from evaluation.utils.shared import (
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
parse_arguments,
|
||||
)
|
||||
@ -70,11 +70,11 @@ AGENT_CLS_TO_INST_SUFFIX = {
|
||||
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = 'python:3.12-bookworm'
|
||||
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime='docker',
|
||||
|
||||
@ -18,7 +18,7 @@ from evaluation.utils.shared import (
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
parse_arguments,
|
||||
)
|
||||
@ -33,13 +33,13 @@ SUPPORTED_AGENT_CLS = {'CodeActAgent'}
|
||||
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
assert metadata.max_iterations == 1, (
|
||||
'max_iterations must be 1 for browsing delegation evaluation.'
|
||||
)
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = 'python:3.12-bookworm'
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime='docker',
|
||||
|
||||
@ -25,7 +25,7 @@ from evaluation.utils.shared import (
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AgentConfig,
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
get_parser,
|
||||
)
|
||||
@ -101,7 +101,7 @@ def get_instance_docker_image(repo_name: str) -> str:
|
||||
def get_config(
|
||||
instance: pd.Series,
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
repo_name = instance['repo'].split('/')[1]
|
||||
base_container_image = get_instance_docker_image(repo_name)
|
||||
logger.info(
|
||||
@ -113,7 +113,7 @@ def get_config(
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = base_container_image
|
||||
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
max_iterations=metadata.max_iterations,
|
||||
|
||||
@ -25,7 +25,7 @@ from evaluation.utils.shared import (
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AgentConfig,
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
parse_arguments,
|
||||
)
|
||||
@ -61,10 +61,10 @@ AGENT_CLS_TO_INST_SUFFIX = {
|
||||
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = 'python:3.12-bookworm'
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime='docker',
|
||||
|
||||
@ -21,7 +21,7 @@ from evaluation.utils.shared import (
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
get_parser,
|
||||
)
|
||||
@ -47,10 +47,10 @@ AGENT_CLS_TO_INST_SUFFIX = {
|
||||
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = 'python:3.12-bookworm'
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime='docker',
|
||||
|
||||
@ -19,7 +19,7 @@ from evaluation.utils.shared import (
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
get_parser,
|
||||
)
|
||||
@ -39,10 +39,10 @@ AGENT_CLS_TO_INST_SUFFIX = {
|
||||
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = 'python:3.12-bookworm'
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime='docker',
|
||||
|
||||
@ -37,7 +37,7 @@ from evaluation.utils.shared import (
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
get_parser,
|
||||
)
|
||||
@ -60,10 +60,10 @@ ACTION_FORMAT = """
|
||||
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = 'python:3.12-bookworm'
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime='docker',
|
||||
|
||||
@ -30,7 +30,7 @@ from evaluation.utils.shared import (
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
parse_arguments,
|
||||
)
|
||||
@ -81,10 +81,10 @@ AGENT_CLS_TO_INST_SUFFIX = {
|
||||
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = 'python:3.12-bookworm'
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime='docker',
|
||||
|
||||
@ -19,10 +19,10 @@ from evaluation.utils.shared import (
|
||||
make_metadata,
|
||||
)
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
LLMConfig,
|
||||
OpenHandsConfig,
|
||||
get_parser,
|
||||
load_app_config,
|
||||
load_openhands_config,
|
||||
)
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.core.main import create_runtime
|
||||
@ -34,10 +34,10 @@ from openhands.utils.async_utils import call_async_from_sync
|
||||
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = 'python:3.12-bookworm'
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime='docker',
|
||||
@ -53,7 +53,7 @@ def get_config(
|
||||
return config
|
||||
|
||||
|
||||
config = load_app_config()
|
||||
config = load_openhands_config()
|
||||
|
||||
|
||||
def load_bench_config():
|
||||
|
||||
@ -29,10 +29,10 @@ from evaluation.utils.shared import (
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
get_parser,
|
||||
load_app_config,
|
||||
load_openhands_config,
|
||||
)
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.core.main import create_runtime, run_controller
|
||||
@ -44,10 +44,10 @@ from openhands.utils.async_utils import call_async_from_sync
|
||||
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = 'python:3.12-bookworm'
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime='docker',
|
||||
@ -63,7 +63,7 @@ def get_config(
|
||||
return config
|
||||
|
||||
|
||||
config = load_app_config()
|
||||
config = load_openhands_config()
|
||||
|
||||
|
||||
def load_bench_config():
|
||||
|
||||
@ -17,7 +17,7 @@ from evaluation.utils.shared import (
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
get_parser,
|
||||
)
|
||||
@ -44,14 +44,14 @@ AGENT_CLS_TO_INST_SUFFIX = {
|
||||
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = 'xingyaoww/od-eval-logic-reasoning:v1.0'
|
||||
sandbox_config.runtime_extra_deps = (
|
||||
'$OH_INTERPRETER_PATH -m pip install scitools-pyke'
|
||||
)
|
||||
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime='docker',
|
||||
|
||||
@ -21,7 +21,7 @@ from evaluation.utils.shared import (
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
parse_arguments,
|
||||
)
|
||||
@ -54,10 +54,10 @@ AGENT_CLS_TO_FAKE_USER_RESPONSE_FN = {
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
env_id: str,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = 'xingyaoww/od-eval-miniwob:v1.0'
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime=os.environ.get('RUNTIME', 'docker'),
|
||||
|
||||
@ -22,7 +22,7 @@ from evaluation.utils.shared import (
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
get_parser,
|
||||
)
|
||||
@ -102,14 +102,14 @@ def load_incontext_example(task_name: str, with_tool: bool = True):
|
||||
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = 'xingyaoww/od-eval-mint:v1.0'
|
||||
sandbox_config.runtime_extra_deps = (
|
||||
f'$OH_INTERPRETER_PATH -m pip install {" ".join(MINT_DEPENDENCIES)}'
|
||||
)
|
||||
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime='docker',
|
||||
|
||||
@ -4,11 +4,11 @@ import pprint
|
||||
|
||||
import tqdm
|
||||
|
||||
from openhands.core.config import get_llm_config_arg, get_parser, load_app_config
|
||||
from openhands.core.config import get_llm_config_arg, get_parser, load_openhands_config
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.llm.llm import LLM
|
||||
|
||||
config = load_app_config()
|
||||
config = load_openhands_config()
|
||||
|
||||
|
||||
def extract_test_results(res_file_path: str) -> tuple[list[str], list[str]]:
|
||||
|
||||
@ -33,10 +33,10 @@ from evaluation.utils.shared import (
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
get_parser,
|
||||
load_app_config,
|
||||
load_openhands_config,
|
||||
)
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.core.main import create_runtime, run_controller
|
||||
@ -45,7 +45,7 @@ from openhands.events.observation import CmdOutputObservation
|
||||
from openhands.runtime.base import Runtime
|
||||
from openhands.utils.async_utils import call_async_from_sync
|
||||
|
||||
config = load_app_config()
|
||||
config = load_openhands_config()
|
||||
|
||||
AGENT_CLS_TO_FAKE_USER_RESPONSE_FN = {
|
||||
'CodeActAgent': codeact_user_response,
|
||||
@ -76,10 +76,10 @@ ID2CONDA = {
|
||||
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = 'public.ecr.aws/i5g0m1f6/ml-bench'
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime='docker',
|
||||
|
||||
@ -28,8 +28,8 @@ from evaluation.utils.shared import (
|
||||
run_evaluation,
|
||||
)
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
LLMConfig,
|
||||
OpenHandsConfig,
|
||||
get_parser,
|
||||
)
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
@ -73,7 +73,7 @@ def process_git_patch(patch):
|
||||
return patch
|
||||
|
||||
|
||||
def get_config(metadata: EvalMetadata, instance: pd.Series) -> AppConfig:
|
||||
def get_config(metadata: EvalMetadata, instance: pd.Series) -> OpenHandsConfig:
|
||||
# We use a different instance image for the each instance of swe-bench eval
|
||||
base_container_image = get_instance_docker_image(instance['instance_id'])
|
||||
logger.info(
|
||||
@ -87,7 +87,7 @@ def get_config(metadata: EvalMetadata, instance: pd.Series) -> AppConfig:
|
||||
dataset_name=metadata.dataset,
|
||||
instance_id=instance['instance_id'],
|
||||
)
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
run_as_openhands=False,
|
||||
runtime=os.environ.get('RUNTIME', 'docker'),
|
||||
sandbox=sandbox_config,
|
||||
|
||||
@ -30,7 +30,7 @@ from evaluation.utils.shared import (
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AgentConfig,
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
get_parser,
|
||||
)
|
||||
@ -314,7 +314,7 @@ def get_instance_docker_image(instance: pd.Series):
|
||||
def get_config(
|
||||
instance: pd.Series,
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
SWE_BENCH_CONTAINER_IMAGE = 'ghcr.io/opendevin/eval-swe-bench:full-v1.2.1'
|
||||
if USE_INSTANCE_IMAGE:
|
||||
# We use a different instance image for the each instance of swe-bench eval
|
||||
@ -340,7 +340,7 @@ def get_config(
|
||||
instance_id=instance['instance_id'],
|
||||
)
|
||||
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
max_iterations=metadata.max_iterations,
|
||||
|
||||
@ -20,7 +20,7 @@ from evaluation.utils.shared import (
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
get_parser,
|
||||
)
|
||||
@ -58,12 +58,12 @@ def format_task_dict(example, use_knowledge):
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
instance_id: str,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = (
|
||||
'docker.io/xingyaoww/openhands-eval-scienceagentbench'
|
||||
)
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime=os.environ.get('RUNTIME', 'docker'),
|
||||
|
||||
@ -24,8 +24,8 @@ from evaluation.utils.shared import (
|
||||
run_evaluation,
|
||||
)
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
LLMConfig,
|
||||
OpenHandsConfig,
|
||||
get_parser,
|
||||
)
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
@ -69,7 +69,7 @@ def process_git_patch(patch):
|
||||
return patch
|
||||
|
||||
|
||||
def get_config(metadata: EvalMetadata, instance: pd.Series) -> AppConfig:
|
||||
def get_config(metadata: EvalMetadata, instance: pd.Series) -> OpenHandsConfig:
|
||||
# We use a different instance image for the each instance of swe-bench eval
|
||||
base_container_image = get_instance_docker_image(instance['instance_id'])
|
||||
logger.info(
|
||||
@ -83,7 +83,7 @@ def get_config(metadata: EvalMetadata, instance: pd.Series) -> AppConfig:
|
||||
dataset_name=metadata.dataset,
|
||||
instance_id=instance['instance_id'],
|
||||
)
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
run_as_openhands=False,
|
||||
runtime=os.environ.get('RUNTIME', 'docker'),
|
||||
sandbox=sandbox_config,
|
||||
|
||||
@ -40,12 +40,12 @@ from evaluation.utils.shared import (
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AgentConfig,
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
get_parser,
|
||||
)
|
||||
from openhands.core.config.utils import get_condenser_config_arg
|
||||
from openhands.core.config.condenser_config import NoOpCondenserConfig
|
||||
from openhands.core.config.utils import get_condenser_config_arg
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.core.main import create_runtime, run_controller
|
||||
from openhands.critic import AgentFinishedCritic
|
||||
@ -220,7 +220,7 @@ def get_instance_docker_image(
|
||||
def get_config(
|
||||
instance: pd.Series,
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
# We use a different instance image for the each instance of swe-bench eval
|
||||
use_swebench_official_image = 'swe-gym' not in metadata.dataset.lower()
|
||||
base_container_image = get_instance_docker_image(
|
||||
@ -244,7 +244,7 @@ def get_config(
|
||||
instance_id=instance['instance_id'],
|
||||
)
|
||||
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
max_iterations=metadata.max_iterations,
|
||||
@ -721,15 +721,16 @@ def filter_dataset(dataset: pd.DataFrame, filter_column: str) -> pd.DataFrame:
|
||||
# repos for the swe-bench instances:
|
||||
# ['astropy/astropy', 'django/django', 'matplotlib/matplotlib', 'mwaskom/seaborn', 'pallets/flask', 'psf/requests', 'pydata/xarray', 'pylint-dev/pylint', 'pytest-dev/pytest', 'scikit-learn/scikit-learn', 'sphinx-doc/sphinx', 'sympy/sympy']
|
||||
selected_repos = data['selected_repos']
|
||||
if isinstance(selected_repos, str): selected_repos = [selected_repos]
|
||||
if isinstance(selected_repos, str):
|
||||
selected_repos = [selected_repos]
|
||||
assert isinstance(selected_repos, list)
|
||||
logger.info(
|
||||
f'Filtering {selected_repos} tasks from "selected_repos"...'
|
||||
)
|
||||
subset = dataset[dataset["repo"].isin(selected_repos)]
|
||||
subset = dataset[dataset['repo'].isin(selected_repos)]
|
||||
logger.info(f'Retained {subset.shape[0]} tasks after filtering')
|
||||
return subset
|
||||
|
||||
|
||||
skip_ids = os.environ.get('SKIP_IDS', '').split(',')
|
||||
if len(skip_ids) > 0:
|
||||
logger.info(f'Filtering {len(skip_ids)} tasks from "SKIP_IDS"...')
|
||||
@ -806,7 +807,9 @@ if __name__ == '__main__':
|
||||
else:
|
||||
# If no specific condenser config is provided via env var, default to NoOpCondenser
|
||||
condenser_config = NoOpCondenserConfig()
|
||||
logger.debug('No Condenser config provided via EVAL_CONDENSER, using NoOpCondenser.')
|
||||
logger.debug(
|
||||
'No Condenser config provided via EVAL_CONDENSER, using NoOpCondenser.'
|
||||
)
|
||||
|
||||
details = {'mode': args.mode}
|
||||
_agent_cls = openhands.agenthub.Agent.get_cls(args.agent_cls)
|
||||
|
||||
@ -30,7 +30,7 @@ from evaluation.utils.shared import (
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AgentConfig,
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
get_parser,
|
||||
)
|
||||
@ -58,7 +58,7 @@ def _get_swebench_workspace_dir_name(instance: pd.Series) -> str:
|
||||
|
||||
|
||||
def get_instruction(instance: pd.Series, metadata: EvalMetadata):
|
||||
workspace_dir_name = _get_swebench_workspace_dir_name(instance)
|
||||
_get_swebench_workspace_dir_name(instance)
|
||||
instruction = f"""
|
||||
Consider the following issue description:
|
||||
|
||||
@ -168,7 +168,7 @@ def get_instance_docker_image(instance_id: str, official_image: bool = False) ->
|
||||
def get_config(
|
||||
instance: pd.Series,
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
# We use a different instance image for the each instance of swe-bench eval
|
||||
use_official_image = bool(
|
||||
'verified' in metadata.dataset.lower() or 'lite' in metadata.dataset.lower()
|
||||
@ -197,7 +197,7 @@ def get_config(
|
||||
'REPO_PATH': f'/workspace/{workspace_dir_name}/',
|
||||
}
|
||||
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
max_iterations=metadata.max_iterations,
|
||||
@ -348,13 +348,13 @@ def initialize_runtime(
|
||||
|
||||
# Check if an existing graph index file is available
|
||||
graph_index_file_path = os.path.join(
|
||||
INDEX_BASE_DIR, 'graph_index_v2.3', f"{instance['instance_id']}.pkl"
|
||||
INDEX_BASE_DIR, 'graph_index_v2.3', f'{instance["instance_id"]}.pkl'
|
||||
)
|
||||
if INDEX_BASE_DIR and os.path.exists(graph_index_file_path):
|
||||
logger.info(
|
||||
f"Copying graph index from {graph_index_file_path} to /workspace/{workspace_dir_name}/_index_data/graph_index_v2.3"
|
||||
f'Copying graph index from {graph_index_file_path} to /workspace/{workspace_dir_name}/_index_data/graph_index_v2.3'
|
||||
)
|
||||
|
||||
|
||||
runtime.copy_to(
|
||||
graph_index_file_path,
|
||||
f'/workspace/{workspace_dir_name}/_index_data/graph_index_v2.3',
|
||||
@ -364,9 +364,13 @@ def initialize_runtime(
|
||||
)
|
||||
obs = runtime.run_action(action)
|
||||
|
||||
bm25_index_dir = os.path.join(INDEX_BASE_DIR, 'BM25_index', instance['instance_id'])
|
||||
bm25_index_dir = os.path.join(
|
||||
INDEX_BASE_DIR, 'BM25_index', instance['instance_id']
|
||||
)
|
||||
runtime.copy_to(
|
||||
bm25_index_dir, f'/workspace/{workspace_dir_name}/_index_data', recursive=True
|
||||
bm25_index_dir,
|
||||
f'/workspace/{workspace_dir_name}/_index_data',
|
||||
recursive=True,
|
||||
)
|
||||
action = CmdRunAction(
|
||||
command=f'mv _index_data/{instance["instance_id"]} _index_data/bm25_index'
|
||||
|
||||
@ -41,7 +41,7 @@ from evaluation.utils.shared import (
|
||||
reset_logger_for_multiprocessing,
|
||||
run_evaluation,
|
||||
)
|
||||
from openhands.core.config import AppConfig, SandboxConfig, get_parser
|
||||
from openhands.core.config import OpenHandsConfig, SandboxConfig, get_parser
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.core.main import create_runtime
|
||||
from openhands.events.action import CmdRunAction
|
||||
@ -52,13 +52,13 @@ DOCKER_IMAGE_PREFIX = os.environ.get('EVAL_DOCKER_IMAGE_PREFIX', 'docker.io/kdja
|
||||
logger.info(f'Using docker image prefix: {DOCKER_IMAGE_PREFIX}')
|
||||
|
||||
|
||||
def get_config(instance: pd.Series) -> AppConfig:
|
||||
def get_config(instance: pd.Series) -> OpenHandsConfig:
|
||||
base_container_image = get_instance_docker_image(instance['instance_id_swebench'])
|
||||
assert base_container_image, (
|
||||
f'Invalid container image for instance {instance["instance_id_swebench"]}.'
|
||||
)
|
||||
logger.info(f'Using instance container image: {base_container_image}.')
|
||||
return AppConfig(
|
||||
return OpenHandsConfig(
|
||||
run_as_openhands=False,
|
||||
runtime=os.environ.get('RUNTIME', 'eventstream'),
|
||||
sandbox=SandboxConfig(
|
||||
|
||||
@ -35,7 +35,7 @@ from evaluation.utils.shared import (
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AgentConfig,
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
SandboxConfig,
|
||||
get_llm_config_arg,
|
||||
get_parser,
|
||||
@ -117,7 +117,7 @@ def get_instance_docker_image(instance_id: str) -> str:
|
||||
def get_config(
|
||||
instance: pd.Series,
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
# We use a different instance image for the each instance of TestGenEval
|
||||
base_container_image = get_instance_docker_image(instance['instance_id_swebench'])
|
||||
logger.info(
|
||||
@ -126,7 +126,7 @@ def get_config(
|
||||
f'Submit an issue on https://github.com/All-Hands-AI/OpenHands if you run into any issues.'
|
||||
)
|
||||
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
max_iterations=metadata.max_iterations,
|
||||
|
||||
@ -15,8 +15,8 @@ from browsing import pre_login
|
||||
from evaluation.utils.shared import get_default_sandbox_config_for_eval
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
LLMConfig,
|
||||
OpenHandsConfig,
|
||||
get_agent_config_arg,
|
||||
get_llm_config_arg,
|
||||
get_parser,
|
||||
@ -36,13 +36,13 @@ def get_config(
|
||||
mount_path_on_host: str,
|
||||
llm_config: LLMConfig,
|
||||
agent_config: AgentConfig | None,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = base_container_image
|
||||
sandbox_config.enable_auto_lint = True
|
||||
# If the web services are running on the host machine, this must be set to True
|
||||
sandbox_config.use_host_network = True
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
run_as_openhands=False,
|
||||
max_budget_per_task=4,
|
||||
max_iterations=100,
|
||||
@ -126,7 +126,7 @@ def codeact_user_response(state: State) -> str:
|
||||
def run_solver(
|
||||
runtime: Runtime,
|
||||
task_name: str,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
dependencies: list[str],
|
||||
save_final_state: bool,
|
||||
state_dir: str,
|
||||
@ -274,7 +274,7 @@ if __name__ == '__main__':
|
||||
temp_dir = os.path.abspath(os.getenv('TMPDIR'))
|
||||
else:
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
config: AppConfig = get_config(
|
||||
config: OpenHandsConfig = get_config(
|
||||
args.task_image_name, task_short_name, temp_dir, agent_llm_config, agent_config
|
||||
)
|
||||
runtime: Runtime = create_runtime(config)
|
||||
|
||||
@ -18,7 +18,7 @@ from evaluation.utils.shared import (
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
get_parser,
|
||||
)
|
||||
@ -40,10 +40,10 @@ AGENT_CLS_TO_INST_SUFFIX = {
|
||||
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.base_container_image = 'python:3.12-bookworm'
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime='docker',
|
||||
|
||||
@ -30,7 +30,7 @@ from evaluation.utils.shared import (
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AgentConfig,
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
get_parser,
|
||||
)
|
||||
@ -135,7 +135,7 @@ def get_instance_docker_image(instance_id: str, official_image: bool = False) ->
|
||||
def get_config(
|
||||
instance: pd.Series,
|
||||
metadata: EvalMetadata,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
# We use a different instance image for the each instance of swe-bench eval
|
||||
use_official_image = bool(
|
||||
'verified' in metadata.dataset.lower() or 'lite' in metadata.dataset.lower()
|
||||
@ -160,7 +160,7 @@ def get_config(
|
||||
instance_id=instance['instance_id'],
|
||||
)
|
||||
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
max_iterations=metadata.max_iterations,
|
||||
|
||||
@ -20,7 +20,7 @@ from evaluation.utils.shared import (
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
parse_arguments,
|
||||
)
|
||||
@ -48,7 +48,7 @@ AGENT_CLS_TO_FAKE_USER_RESPONSE_FN = {
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
env_id: str,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
base_url = os.environ.get('VISUALWEBARENA_BASE_URL', None)
|
||||
openai_api_key = os.environ.get('OPENAI_API_KEY', None)
|
||||
openai_base_url = os.environ.get('OPENAI_BASE_URL', None)
|
||||
@ -72,7 +72,7 @@ def get_config(
|
||||
'VWA_WIKIPEDIA': f'{base_url}:8888',
|
||||
'VWA_HOMEPAGE': f'{base_url}:4399',
|
||||
}
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime='docker',
|
||||
|
||||
@ -19,7 +19,7 @@ from evaluation.utils.shared import (
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
parse_arguments,
|
||||
)
|
||||
@ -44,7 +44,7 @@ SUPPORTED_AGENT_CLS = {'BrowsingAgent'}
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
env_id: str,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
base_url = os.environ.get('WEBARENA_BASE_URL', None)
|
||||
openai_api_key = os.environ.get('OPENAI_API_KEY', None)
|
||||
assert base_url is not None, 'WEBARENA_BASE_URL must be set'
|
||||
@ -64,7 +64,7 @@ def get_config(
|
||||
'MAP': f'{base_url}:3000',
|
||||
'HOMEPAGE': f'{base_url}:4399',
|
||||
}
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime='docker',
|
||||
|
||||
@ -21,7 +21,7 @@ from evaluation.utils.shared import (
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AgentConfig,
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
get_llm_config_arg,
|
||||
parse_arguments,
|
||||
)
|
||||
@ -41,10 +41,10 @@ FAKE_RESPONSES = {
|
||||
def get_config(
|
||||
metadata: EvalMetadata,
|
||||
instance_id: str,
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
sandbox_config = get_default_sandbox_config_for_eval()
|
||||
sandbox_config.platform = 'linux/amd64'
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
run_as_openhands=False,
|
||||
runtime=os.environ.get('RUNTIME', 'docker'),
|
||||
|
||||
@ -2,9 +2,9 @@ import argparse
|
||||
|
||||
import pytest
|
||||
|
||||
from openhands.config import load_app_config
|
||||
from openhands.config import load_openhands_config
|
||||
|
||||
config = load_app_config()
|
||||
config = load_openhands_config()
|
||||
|
||||
if __name__ == '__main__':
|
||||
"""Main entry point of the script.
|
||||
|
||||
@ -25,7 +25,7 @@ from openhands.cli.utils import (
|
||||
write_to_file,
|
||||
)
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
)
|
||||
from openhands.core.schema import AgentState
|
||||
from openhands.events import EventSource
|
||||
@ -42,7 +42,7 @@ async def handle_commands(
|
||||
event_stream: EventStream,
|
||||
usage_metrics: UsageMetrics,
|
||||
sid: str,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
current_dir: str,
|
||||
settings_store: FileSettingsStore,
|
||||
) -> tuple[bool, bool, bool]:
|
||||
@ -105,7 +105,7 @@ def handle_help_command() -> None:
|
||||
|
||||
|
||||
async def handle_init_command(
|
||||
config: AppConfig, event_stream: EventStream, current_dir: str
|
||||
config: OpenHandsConfig, event_stream: EventStream, current_dir: str
|
||||
) -> tuple[bool, bool]:
|
||||
REPO_MD_CREATE_PROMPT = """
|
||||
Please explore this repository. Create the file .openhands/microagents/repo.md with:
|
||||
@ -166,7 +166,7 @@ def handle_new_command(
|
||||
|
||||
|
||||
async def handle_settings_command(
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
settings_store: FileSettingsStore,
|
||||
) -> None:
|
||||
display_settings(config)
|
||||
@ -264,7 +264,7 @@ async def init_repository(current_dir: str) -> bool:
|
||||
return init_repo
|
||||
|
||||
|
||||
def check_folder_security_agreement(config: AppConfig, current_dir: str) -> bool:
|
||||
def check_folder_security_agreement(config: OpenHandsConfig, current_dir: str) -> bool:
|
||||
# Directories trusted by user for the CLI to use as workspace
|
||||
# Config from ~/.openhands/config.toml overrides the app config
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ from openhands.cli.utils import (
|
||||
from openhands.controller import AgentController
|
||||
from openhands.controller.agent import Agent
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
parse_arguments,
|
||||
setup_config_from_args,
|
||||
)
|
||||
@ -103,7 +103,7 @@ async def cleanup_session(
|
||||
|
||||
async def run_session(
|
||||
loop: asyncio.AbstractEventLoop,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
settings_store: FileSettingsStore,
|
||||
current_dir: str,
|
||||
task_content: str | None = None,
|
||||
@ -334,7 +334,7 @@ async def main(loop: asyncio.AbstractEventLoop) -> None:
|
||||
logger.setLevel(logging.WARNING)
|
||||
|
||||
# Load config from toml and override with command line arguments
|
||||
config: AppConfig = setup_config_from_args(args)
|
||||
config: OpenHandsConfig = setup_config_from_args(args)
|
||||
|
||||
# Load settings from Settings Store
|
||||
# TODO: Make this generic?
|
||||
|
||||
@ -18,7 +18,7 @@ from openhands.cli.utils import (
|
||||
organize_models_and_providers,
|
||||
)
|
||||
from openhands.controller.agent import Agent
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.core.config.condenser_config import NoOpCondenserConfig
|
||||
from openhands.core.config.utils import OH_DEFAULT_AGENT
|
||||
from openhands.memory.condenser.impl.llm_summarizing_condenser import (
|
||||
@ -29,7 +29,7 @@ from openhands.storage.settings.file_settings_store import FileSettingsStore
|
||||
from openhands.utils.llm import get_supported_llm_models
|
||||
|
||||
|
||||
def display_settings(config: AppConfig) -> None:
|
||||
def display_settings(config: OpenHandsConfig) -> None:
|
||||
llm_config = config.get_llm_config()
|
||||
advanced_llm_settings = True if llm_config.base_url else False
|
||||
|
||||
@ -145,7 +145,7 @@ def save_settings_confirmation() -> bool:
|
||||
|
||||
|
||||
async def modify_llm_settings_basic(
|
||||
config: AppConfig, settings_store: FileSettingsStore
|
||||
config: OpenHandsConfig, settings_store: FileSettingsStore
|
||||
) -> None:
|
||||
model_list = get_supported_llm_models(config)
|
||||
organized_models = organize_models_and_providers(model_list)
|
||||
@ -243,7 +243,7 @@ async def modify_llm_settings_basic(
|
||||
|
||||
|
||||
async def modify_llm_settings_advanced(
|
||||
config: AppConfig, settings_store: FileSettingsStore
|
||||
config: OpenHandsConfig, settings_store: FileSettingsStore
|
||||
) -> None:
|
||||
session = PromptSession(key_bindings=kb_cancel())
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ from prompt_toolkit.styles import Style
|
||||
from prompt_toolkit.widgets import Frame, TextArea
|
||||
|
||||
from openhands import __version__
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.core.schema import AgentState
|
||||
from openhands.events import EventSource, EventStream
|
||||
from openhands.events.action import (
|
||||
@ -180,7 +180,7 @@ def display_initial_user_prompt(prompt: str) -> None:
|
||||
|
||||
|
||||
# Prompt output display functions
|
||||
def display_event(event: Event, config: AppConfig) -> None:
|
||||
def display_event(event: Event, config: OpenHandsConfig) -> None:
|
||||
global streaming_output_text_area
|
||||
with print_lock:
|
||||
if isinstance(event, Action):
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
from openhands.core.config.agent_config import AgentConfig
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config.config_utils import (
|
||||
OH_DEFAULT_AGENT,
|
||||
OH_MAX_ITERATIONS,
|
||||
@ -8,6 +7,7 @@ from openhands.core.config.config_utils import (
|
||||
from openhands.core.config.extended_config import ExtendedConfig
|
||||
from openhands.core.config.llm_config import LLMConfig
|
||||
from openhands.core.config.mcp_config import MCPConfig
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
from openhands.core.config.sandbox_config import SandboxConfig
|
||||
from openhands.core.config.security_config import SecurityConfig
|
||||
from openhands.core.config.utils import (
|
||||
@ -15,9 +15,9 @@ from openhands.core.config.utils import (
|
||||
get_agent_config_arg,
|
||||
get_llm_config_arg,
|
||||
get_parser,
|
||||
load_app_config,
|
||||
load_from_env,
|
||||
load_from_toml,
|
||||
load_openhands_config,
|
||||
parse_arguments,
|
||||
setup_config_from_args,
|
||||
)
|
||||
@ -26,13 +26,13 @@ __all__ = [
|
||||
'OH_DEFAULT_AGENT',
|
||||
'OH_MAX_ITERATIONS',
|
||||
'AgentConfig',
|
||||
'AppConfig',
|
||||
'OpenHandsConfig',
|
||||
'MCPConfig',
|
||||
'LLMConfig',
|
||||
'SandboxConfig',
|
||||
'SecurityConfig',
|
||||
'ExtendedConfig',
|
||||
'load_app_config',
|
||||
'load_openhands_config',
|
||||
'load_from_env',
|
||||
'load_from_toml',
|
||||
'finalize_config',
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import os
|
||||
from urllib.parse import urlparse
|
||||
from typing import TYPE_CHECKING
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from pydantic import BaseModel, Field, ValidationError, model_validator
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.utils.import_utils import get_impl
|
||||
@ -147,7 +148,7 @@ class MCPConfig(BaseModel):
|
||||
|
||||
class OpenHandsMCPConfig:
|
||||
@staticmethod
|
||||
def add_search_engine(app_config: "AppConfig") -> MCPStdioServerConfig | None:
|
||||
def add_search_engine(app_config: 'OpenHandsConfig') -> MCPStdioServerConfig | None:
|
||||
"""Add search engine to the MCP config"""
|
||||
if (
|
||||
app_config.search_api_key
|
||||
@ -165,17 +166,16 @@ class OpenHandsMCPConfig:
|
||||
# Do not add search engine to MCP config in SaaS mode since it will be added by the OpenHands server
|
||||
return None
|
||||
|
||||
|
||||
@staticmethod
|
||||
def create_default_mcp_server_config(
|
||||
host: str, config: "AppConfig", user_id: str | None = None
|
||||
host: str, config: 'OpenHandsConfig', user_id: str | None = None
|
||||
) -> tuple[MCPSSEServerConfig, list[MCPStdioServerConfig]]:
|
||||
"""
|
||||
Create a default MCP server configuration.
|
||||
|
||||
Args:
|
||||
host: Host string
|
||||
config: AppConfig
|
||||
config: OpenHandsConfig
|
||||
Returns:
|
||||
tuple[MCPSSEServerConfig, list[MCPStdioServerConfig]]: A tuple containing the default SSE server configuration and a list of MCP stdio server configurations
|
||||
"""
|
||||
|
||||
@ -16,7 +16,7 @@ from openhands.core.config.sandbox_config import SandboxConfig
|
||||
from openhands.core.config.security_config import SecurityConfig
|
||||
|
||||
|
||||
class AppConfig(BaseModel):
|
||||
class OpenHandsConfig(BaseModel):
|
||||
"""Configuration for the app.
|
||||
|
||||
Attributes:
|
||||
@ -65,7 +65,10 @@ class AppConfig(BaseModel):
|
||||
save_trajectory_path: str | None = Field(default=None)
|
||||
save_screenshots_in_trajectory: bool = Field(default=False)
|
||||
replay_trajectory_path: str | None = Field(default=None)
|
||||
search_api_key: SecretStr | None = Field(default=None, description="API key for Tavily search engine (https://tavily.com/). Required for search functionality.")
|
||||
search_api_key: SecretStr | None = Field(
|
||||
default=None,
|
||||
description='API key for Tavily search engine (https://tavily.com/). Required for search functionality.',
|
||||
)
|
||||
|
||||
# Deprecated parameters - will be removed in a future version
|
||||
workspace_base: str | None = Field(default=None, deprecated=True)
|
||||
@ -73,7 +76,7 @@ class AppConfig(BaseModel):
|
||||
workspace_mount_path_in_sandbox: str = Field(default='/workspace', deprecated=True)
|
||||
workspace_mount_rewrite: str | None = Field(default=None, deprecated=True)
|
||||
# End of deprecated parameters
|
||||
|
||||
|
||||
cache_dir: str = Field(default='/tmp/cache')
|
||||
run_as_openhands: bool = Field(default=True)
|
||||
max_iterations: int = Field(default=OH_MAX_ITERATIONS)
|
||||
@ -148,5 +151,5 @@ class AppConfig(BaseModel):
|
||||
"""Post-initialization hook, called when the instance is created with only default values."""
|
||||
super().model_post_init(__context)
|
||||
|
||||
if not AppConfig.defaults_dict: # Only set defaults_dict if it's empty
|
||||
AppConfig.defaults_dict = model_defaults_to_dict(self)
|
||||
if not OpenHandsConfig.defaults_dict: # Only set defaults_dict if it's empty
|
||||
OpenHandsConfig.defaults_dict = model_defaults_to_dict(self)
|
||||
@ -15,7 +15,6 @@ from pydantic import BaseModel, SecretStr, ValidationError
|
||||
from openhands import __version__
|
||||
from openhands.core import logger
|
||||
from openhands.core.config.agent_config import AgentConfig
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config.condenser_config import (
|
||||
CondenserConfig,
|
||||
condenser_config_from_toml_section,
|
||||
@ -28,6 +27,7 @@ from openhands.core.config.config_utils import (
|
||||
from openhands.core.config.extended_config import ExtendedConfig
|
||||
from openhands.core.config.llm_config import LLMConfig
|
||||
from openhands.core.config.mcp_config import MCPConfig
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
from openhands.core.config.sandbox_config import SandboxConfig
|
||||
from openhands.core.config.security_config import SecurityConfig
|
||||
from openhands.storage import get_file_store
|
||||
@ -39,7 +39,7 @@ load_dotenv()
|
||||
|
||||
|
||||
def load_from_env(
|
||||
cfg: AppConfig, env_or_toml_dict: dict | MutableMapping[str, str]
|
||||
cfg: OpenHandsConfig, env_or_toml_dict: dict | MutableMapping[str, str]
|
||||
) -> None:
|
||||
"""Sets config attributes from environment variables or TOML dictionary.
|
||||
|
||||
@ -48,7 +48,7 @@ def load_from_env(
|
||||
(e.g., AGENT_MEMORY_ENABLED), sandbox settings (e.g., SANDBOX_TIMEOUT), and more.
|
||||
|
||||
Args:
|
||||
cfg: The AppConfig object to set attributes on.
|
||||
cfg: The OpenHandsConfig object to set attributes on.
|
||||
env_or_toml_dict: The environment variables or a config.toml dict.
|
||||
"""
|
||||
|
||||
@ -121,11 +121,11 @@ def load_from_env(
|
||||
set_attr_from_env(default_agent_config, 'AGENT_')
|
||||
|
||||
|
||||
def load_from_toml(cfg: AppConfig, toml_file: str = 'config.toml') -> None:
|
||||
def load_from_toml(cfg: OpenHandsConfig, toml_file: str = 'config.toml') -> None:
|
||||
"""Load the config from the toml file. Supports both styles of config vars.
|
||||
|
||||
Args:
|
||||
cfg: The AppConfig object to update attributes of.
|
||||
cfg: The OpenHandsConfig object to update attributes of.
|
||||
toml_file: The path to the toml file. Defaults to 'config.toml'.
|
||||
|
||||
See Also:
|
||||
@ -302,7 +302,7 @@ def get_or_create_jwt_secret(file_store: FileStore) -> str:
|
||||
return new_secret
|
||||
|
||||
|
||||
def finalize_config(cfg: AppConfig) -> None:
|
||||
def finalize_config(cfg: OpenHandsConfig) -> None:
|
||||
"""More tweaks to the config after it's been loaded."""
|
||||
# Handle the sandbox.volumes parameter
|
||||
if cfg.workspace_base is not None or cfg.workspace_mount_path is not None:
|
||||
@ -759,7 +759,7 @@ def parse_arguments() -> argparse.Namespace:
|
||||
return args
|
||||
|
||||
|
||||
def register_custom_agents(config: AppConfig) -> None:
|
||||
def register_custom_agents(config: OpenHandsConfig) -> None:
|
||||
"""Register custom agents from configuration.
|
||||
|
||||
This function is called after configuration is loaded to ensure all custom agents
|
||||
@ -782,16 +782,16 @@ def register_custom_agents(config: AppConfig) -> None:
|
||||
)
|
||||
|
||||
|
||||
def load_app_config(
|
||||
def load_openhands_config(
|
||||
set_logging_levels: bool = True, config_file: str = 'config.toml'
|
||||
) -> AppConfig:
|
||||
) -> OpenHandsConfig:
|
||||
"""Load the configuration from the specified config file and environment variables.
|
||||
|
||||
Args:
|
||||
set_logging_levels: Whether to set the global variables for logging levels.
|
||||
config_file: Path to the config file. Defaults to 'config.toml' in the current directory.
|
||||
"""
|
||||
config = AppConfig()
|
||||
config = OpenHandsConfig()
|
||||
load_from_toml(config, config_file)
|
||||
load_from_env(config, os.environ)
|
||||
finalize_config(config)
|
||||
@ -802,13 +802,13 @@ def load_app_config(
|
||||
return config
|
||||
|
||||
|
||||
def setup_config_from_args(args: argparse.Namespace) -> AppConfig:
|
||||
def setup_config_from_args(args: argparse.Namespace) -> OpenHandsConfig:
|
||||
"""Load config from toml and override with command line arguments.
|
||||
|
||||
Common setup used by both CLI and main.py entry points.
|
||||
"""
|
||||
# Load base config from toml and env vars
|
||||
config = load_app_config(config_file=args.config_file)
|
||||
config = load_openhands_config(config_file=args.config_file)
|
||||
|
||||
# Override with command line arguments if provided
|
||||
if args.llm_config:
|
||||
|
||||
@ -9,7 +9,7 @@ from openhands.controller.agent import Agent
|
||||
from openhands.controller.replay import ReplayManager
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
parse_arguments,
|
||||
setup_config_from_args,
|
||||
)
|
||||
@ -47,7 +47,7 @@ class FakeUserResponseFunc(Protocol):
|
||||
|
||||
|
||||
async def run_controller(
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
initial_user_action: Action,
|
||||
sid: str | None = None,
|
||||
runtime: Runtime | None = None,
|
||||
@ -90,7 +90,7 @@ async def run_controller(
|
||||
config.max_budget_per_task.
|
||||
|
||||
Example:
|
||||
>>> config = load_app_config()
|
||||
>>> config = load_openhands_config()
|
||||
>>> action = MessageAction(content="Write a hello world program")
|
||||
>>> state = await run_controller(config=config, initial_user_action=action)
|
||||
"""
|
||||
@ -279,7 +279,7 @@ def load_replay_log(trajectory_path: str) -> tuple[list[Event] | None, Action]:
|
||||
if __name__ == '__main__':
|
||||
args = parse_arguments()
|
||||
|
||||
config: AppConfig = setup_config_from_args(args)
|
||||
config: OpenHandsConfig = setup_config_from_args(args)
|
||||
|
||||
# Read task from file, CLI args, or stdin
|
||||
task_str = read_task(args, config.cli_multiline_input)
|
||||
|
||||
@ -10,7 +10,7 @@ from openhands.controller import AgentController
|
||||
from openhands.controller.agent import Agent
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
OpenHandsConfig,
|
||||
)
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.events import EventStream
|
||||
@ -28,7 +28,7 @@ from openhands.utils.async_utils import GENERAL_TIMEOUT, call_async_from_sync
|
||||
|
||||
|
||||
def create_runtime(
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
sid: str | None = None,
|
||||
headless_mode: bool = True,
|
||||
agent: Agent | None = None,
|
||||
@ -172,7 +172,7 @@ def create_memory(
|
||||
return memory
|
||||
|
||||
|
||||
def create_agent(config: AppConfig) -> Agent:
|
||||
def create_agent(config: OpenHandsConfig) -> Agent:
|
||||
agent_cls: type[Agent] = Agent.get_cls(config.default_agent)
|
||||
agent_config = config.get_agent_config(config.default_agent)
|
||||
llm_config = config.get_llm_config_from_agent(config.default_agent)
|
||||
@ -188,7 +188,7 @@ def create_agent(config: AppConfig) -> Agent:
|
||||
def create_controller(
|
||||
agent: Agent,
|
||||
runtime: Runtime,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
headless_mode: bool = True,
|
||||
replay_events: list[Event] | None = None,
|
||||
) -> tuple[AgentController, State | None]:
|
||||
@ -218,7 +218,7 @@ def create_controller(
|
||||
return (controller, initial_state)
|
||||
|
||||
|
||||
def generate_sid(config: AppConfig, session_name: str | None = None) -> str:
|
||||
def generate_sid(config: OpenHandsConfig, session_name: str | None = None) -> str:
|
||||
"""Generate a session id based on the session name and the jwt secret."""
|
||||
session_name = session_name or str(uuid.uuid4())
|
||||
jwt_secret = config.jwt_secret
|
||||
|
||||
@ -4,11 +4,11 @@ from typing import TYPE_CHECKING
|
||||
if TYPE_CHECKING:
|
||||
from openhands.controller.agent import Agent
|
||||
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config.mcp_config import (
|
||||
MCPConfig,
|
||||
MCPSSEServerConfig,
|
||||
)
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.events.action.mcp import MCPAction
|
||||
from openhands.events.observation.mcp import MCPObservation
|
||||
@ -162,7 +162,7 @@ async def call_tool_mcp(mcp_clients: list[MCPClient], action: MCPAction) -> Obse
|
||||
|
||||
|
||||
async def add_mcp_tools_to_agent(
|
||||
agent: 'Agent', runtime: Runtime, memory: 'Memory', app_config: AppConfig
|
||||
agent: 'Agent', runtime: Runtime, memory: 'Memory', app_config: OpenHandsConfig
|
||||
):
|
||||
"""
|
||||
Add MCP tools to an agent.
|
||||
|
||||
@ -16,7 +16,7 @@ from termcolor import colored
|
||||
|
||||
import openhands
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import AgentConfig, AppConfig, LLMConfig, SandboxConfig
|
||||
from openhands.core.config import AgentConfig, LLMConfig, OpenHandsConfig, SandboxConfig
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.core.main import create_runtime, run_controller
|
||||
from openhands.events.action import CmdRunAction, MessageAction
|
||||
@ -377,7 +377,7 @@ class IssueResolver:
|
||||
shutil.rmtree(workspace_base)
|
||||
shutil.copytree(os.path.join(self.output_dir, 'repo'), workspace_base)
|
||||
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
default_agent='CodeActAgent',
|
||||
runtime='docker',
|
||||
max_budget_per_task=4,
|
||||
|
||||
@ -15,7 +15,7 @@ from zipfile import ZipFile
|
||||
|
||||
import httpx
|
||||
|
||||
from openhands.core.config import AppConfig, SandboxConfig
|
||||
from openhands.core.config import OpenHandsConfig, SandboxConfig
|
||||
from openhands.core.config.mcp_config import MCPConfig, MCPStdioServerConfig
|
||||
from openhands.core.exceptions import AgentRuntimeDisconnectedError
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
@ -97,7 +97,7 @@ class Runtime(FileEditRuntimeMixin):
|
||||
"""
|
||||
|
||||
sid: str
|
||||
config: AppConfig
|
||||
config: OpenHandsConfig
|
||||
initial_env_vars: dict[str, str]
|
||||
attach_to_existing: bool
|
||||
status_callback: Callable[[str, str, str], None] | None
|
||||
@ -105,7 +105,7 @@ class Runtime(FileEditRuntimeMixin):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
event_stream: EventStream,
|
||||
sid: str = 'default',
|
||||
plugins: list[PluginRequirement] | None = None,
|
||||
|
||||
@ -9,7 +9,7 @@ import httpcore
|
||||
import httpx
|
||||
from tenacity import retry, retry_if_exception, stop_after_attempt, wait_exponential
|
||||
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.core.config.mcp_config import (
|
||||
MCPConfig,
|
||||
MCPSSEServerConfig,
|
||||
@ -65,7 +65,7 @@ class ActionExecutionClient(Runtime):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
event_stream: EventStream,
|
||||
sid: str = 'default',
|
||||
plugins: list[PluginRequirement] | None = None,
|
||||
@ -409,7 +409,7 @@ class ActionExecutionClient(Runtime):
|
||||
'warning',
|
||||
f'Some MCP servers failed to be added: {result["router_error_log"]}',
|
||||
)
|
||||
|
||||
|
||||
# Update our cached list with combined servers after successful update
|
||||
self._last_updated_mcp_stdio_servers = combined_servers.copy()
|
||||
self.log(
|
||||
|
||||
@ -22,7 +22,7 @@ from openhands_aci.editor.results import ToolResult
|
||||
from openhands_aci.utils.diff import get_diff
|
||||
from pydantic import SecretStr
|
||||
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.core.config.mcp_config import MCPConfig, MCPStdioServerConfig
|
||||
from openhands.core.exceptions import LLMMalformedActionError
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
@ -57,7 +57,7 @@ class CLIRuntime(Runtime):
|
||||
file operations using Python's standard library. It does not implement browser functionality.
|
||||
|
||||
Args:
|
||||
config (AppConfig): The application configuration.
|
||||
config (OpenHandsConfig): The application configuration.
|
||||
event_stream (EventStream): The event stream to subscribe to.
|
||||
sid (str, optional): The session ID. Defaults to 'default'.
|
||||
plugins (list[PluginRequirement] | None, optional): List of plugin requirements. Defaults to None.
|
||||
@ -71,7 +71,7 @@ class CLIRuntime(Runtime):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
event_stream: EventStream,
|
||||
sid: str = 'default',
|
||||
plugins: list[PluginRequirement] | None = None,
|
||||
|
||||
@ -11,7 +11,7 @@ from daytona_sdk import (
|
||||
Workspace,
|
||||
)
|
||||
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
from openhands.events.stream import EventStream
|
||||
from openhands.runtime.impl.action_execution.action_execution_client import (
|
||||
ActionExecutionClient,
|
||||
@ -33,7 +33,7 @@ class DaytonaRuntime(ActionExecutionClient):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
event_stream: EventStream,
|
||||
sid: str = 'default',
|
||||
plugins: list[PluginRequirement] | None = None,
|
||||
|
||||
@ -8,7 +8,7 @@ import httpx
|
||||
import tenacity
|
||||
from docker.models.containers import Container
|
||||
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.core.exceptions import (
|
||||
AgentRuntimeDisconnectedError,
|
||||
AgentRuntimeNotFoundError,
|
||||
@ -23,7 +23,10 @@ from openhands.runtime.impl.action_execution.action_execution_client import (
|
||||
from openhands.runtime.impl.docker.containers import stop_all_containers
|
||||
from openhands.runtime.plugins import PluginRequirement
|
||||
from openhands.runtime.utils import find_available_tcp_port
|
||||
from openhands.runtime.utils.command import DEFAULT_MAIN_MODULE, get_action_execution_server_startup_command
|
||||
from openhands.runtime.utils.command import (
|
||||
DEFAULT_MAIN_MODULE,
|
||||
get_action_execution_server_startup_command,
|
||||
)
|
||||
from openhands.runtime.utils.log_streamer import LogStreamer
|
||||
from openhands.runtime.utils.runtime_build import build_runtime_image
|
||||
from openhands.utils.async_utils import call_sync_from_async
|
||||
@ -62,7 +65,7 @@ class DockerRuntime(ActionExecutionClient):
|
||||
When receive an event, it will send the event to runtime-client which run inside the docker environment.
|
||||
|
||||
Args:
|
||||
config (AppConfig): The application configuration.
|
||||
config (OpenHandsConfig): The application configuration.
|
||||
event_stream (EventStream): The event stream to subscribe to.
|
||||
sid (str, optional): The session ID. Defaults to 'default'.
|
||||
plugins (list[PluginRequirement] | None, optional): List of plugin requirements. Defaults to None.
|
||||
@ -73,7 +76,7 @@ class DockerRuntime(ActionExecutionClient):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
event_stream: EventStream,
|
||||
sid: str = 'default',
|
||||
plugins: list[PluginRequirement] | None = None,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
from typing import Callable
|
||||
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.events.action import (
|
||||
FileReadAction,
|
||||
FileWriteAction,
|
||||
@ -22,7 +22,7 @@ from openhands.runtime.utils.files import insert_lines, read_lines
|
||||
class E2BRuntime(Runtime):
|
||||
def __init__(
|
||||
self,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
event_stream: EventStream,
|
||||
sid: str = 'default',
|
||||
plugins: list[PluginRequirement] | None = None,
|
||||
|
||||
@ -12,7 +12,7 @@ import httpx
|
||||
import tenacity
|
||||
|
||||
import openhands
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.core.exceptions import AgentRuntimeDisconnectedError
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.events import EventStream
|
||||
@ -107,7 +107,7 @@ class LocalRuntime(ActionExecutionClient):
|
||||
When receiving an event, it will send the event to the server via HTTP.
|
||||
|
||||
Args:
|
||||
config (AppConfig): The application configuration.
|
||||
config (OpenHandsConfig): The application configuration.
|
||||
event_stream (EventStream): The event stream to subscribe to.
|
||||
sid (str, optional): The session ID. Defaults to 'default'.
|
||||
plugins (list[PluginRequirement] | None, optional): list of plugin requirements. Defaults to None.
|
||||
@ -116,7 +116,7 @@ class LocalRuntime(ActionExecutionClient):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
event_stream: EventStream,
|
||||
sid: str = 'default',
|
||||
plugins: list[PluginRequirement] | None = None,
|
||||
|
||||
@ -7,7 +7,7 @@ import httpx
|
||||
import modal
|
||||
import tenacity
|
||||
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.events import EventStream
|
||||
from openhands.runtime.impl.action_execution.action_execution_client import (
|
||||
ActionExecutionClient,
|
||||
@ -31,7 +31,7 @@ class ModalRuntime(ActionExecutionClient):
|
||||
When receive an event, it will send the event to runtime-client which run inside the Modal sandbox environment.
|
||||
|
||||
Args:
|
||||
config (AppConfig): The application configuration.
|
||||
config (OpenHandsConfig): The application configuration.
|
||||
event_stream (EventStream): The event stream to subscribe to.
|
||||
sid (str, optional): The session ID. Defaults to 'default'.
|
||||
plugins (list[PluginRequirement] | None, optional): List of plugin requirements. Defaults to None.
|
||||
@ -44,7 +44,7 @@ class ModalRuntime(ActionExecutionClient):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
event_stream: EventStream,
|
||||
sid: str = 'default',
|
||||
plugins: list[PluginRequirement] | None = None,
|
||||
|
||||
@ -8,7 +8,7 @@ import httpx
|
||||
import tenacity
|
||||
from tenacity import RetryCallState
|
||||
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.core.exceptions import (
|
||||
AgentRuntimeDisconnectedError,
|
||||
AgentRuntimeError,
|
||||
@ -24,7 +24,10 @@ from openhands.runtime.impl.action_execution.action_execution_client import (
|
||||
ActionExecutionClient,
|
||||
)
|
||||
from openhands.runtime.plugins import PluginRequirement
|
||||
from openhands.runtime.utils.command import DEFAULT_MAIN_MODULE, get_action_execution_server_startup_command
|
||||
from openhands.runtime.utils.command import (
|
||||
DEFAULT_MAIN_MODULE,
|
||||
get_action_execution_server_startup_command,
|
||||
)
|
||||
from openhands.runtime.utils.request import send_request
|
||||
from openhands.runtime.utils.runtime_build import build_runtime_image
|
||||
from openhands.utils.async_utils import call_sync_from_async
|
||||
@ -45,7 +48,7 @@ class RemoteRuntime(ActionExecutionClient):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
event_stream: EventStream,
|
||||
sid: str = 'default',
|
||||
plugins: list[PluginRequirement] | None = None,
|
||||
|
||||
@ -6,7 +6,7 @@ from runloop_api_client import Runloop
|
||||
from runloop_api_client.types import DevboxView
|
||||
from runloop_api_client.types.shared_params import LaunchParameters
|
||||
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.events import EventStream
|
||||
from openhands.runtime.impl.action_execution.action_execution_client import (
|
||||
@ -27,7 +27,7 @@ class RunloopRuntime(ActionExecutionClient):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
event_stream: EventStream,
|
||||
sid: str = 'default',
|
||||
plugins: list[PluginRequirement] | None = None,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.runtime.plugins import PluginRequirement
|
||||
|
||||
DEFAULT_PYTHON_PREFIX = [
|
||||
@ -15,7 +15,7 @@ DEFAULT_MAIN_MODULE = 'openhands.runtime.action_execution_server'
|
||||
def get_action_execution_server_startup_command(
|
||||
server_port: int,
|
||||
plugins: list[PluginRequirement],
|
||||
app_config: AppConfig,
|
||||
app_config: OpenHandsConfig,
|
||||
python_prefix: list[str] = DEFAULT_PYTHON_PREFIX,
|
||||
override_user_id: int | None = None,
|
||||
override_username: str | None = None,
|
||||
|
||||
@ -6,7 +6,7 @@ from typing import Any
|
||||
|
||||
from openhands_aci.utils.diff import get_diff
|
||||
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.events.action import (
|
||||
FileEditAction,
|
||||
@ -83,7 +83,7 @@ def get_new_file_contents(
|
||||
|
||||
|
||||
class FileEditRuntimeInterface(ABC):
|
||||
config: AppConfig
|
||||
config: OpenHandsConfig
|
||||
|
||||
@abstractmethod
|
||||
def read(self, action: FileReadAction) -> Observation:
|
||||
|
||||
@ -4,14 +4,12 @@ from abc import ABC, abstractmethod
|
||||
|
||||
import socketio
|
||||
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.events.action import MessageAction
|
||||
from openhands.events.event_store import EventStore
|
||||
from openhands.server.config.server_config import ServerConfig
|
||||
from openhands.server.data_models.agent_loop_info import AgentLoopInfo
|
||||
from openhands.server.data_models.conversation_info import ConversationInfo
|
||||
from openhands.server.monitoring import MonitoringListener
|
||||
from openhands.server.session.conversation import Conversation
|
||||
from openhands.server.session.conversation import ServerConversation
|
||||
from openhands.storage.conversation.conversation_store import ConversationStore
|
||||
from openhands.storage.data_models.settings import Settings
|
||||
from openhands.storage.files import FileStore
|
||||
@ -26,7 +24,7 @@ class ConversationManager(ABC):
|
||||
"""
|
||||
|
||||
sio: socketio.AsyncServer
|
||||
config: AppConfig
|
||||
config: OpenHandsConfig
|
||||
file_store: FileStore
|
||||
conversation_store: ConversationStore
|
||||
|
||||
@ -41,11 +39,11 @@ class ConversationManager(ABC):
|
||||
@abstractmethod
|
||||
async def attach_to_conversation(
|
||||
self, sid: str, user_id: str | None = None
|
||||
) -> Conversation | None:
|
||||
) -> ServerConversation | None:
|
||||
"""Attach to an existing conversation or create a new one."""
|
||||
|
||||
@abstractmethod
|
||||
async def detach_from_conversation(self, conversation: Conversation):
|
||||
async def detach_from_conversation(self, conversation: ServerConversation):
|
||||
"""Detach from a conversation."""
|
||||
|
||||
@abstractmethod
|
||||
@ -109,7 +107,7 @@ class ConversationManager(ABC):
|
||||
def get_instance(
|
||||
cls,
|
||||
sio: socketio.AsyncServer,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
file_store: FileStore,
|
||||
server_config: ServerConfig,
|
||||
monitoring_listener: MonitoringListener,
|
||||
|
||||
@ -15,7 +15,7 @@ from docker.models.containers import Container
|
||||
from fastapi import status
|
||||
|
||||
from openhands.controller.agent import Agent
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.events.action import MessageAction
|
||||
from openhands.events.nested_event_store import NestedEventStore
|
||||
@ -30,7 +30,7 @@ from openhands.server.conversation_manager.conversation_manager import (
|
||||
)
|
||||
from openhands.server.data_models.agent_loop_info import AgentLoopInfo
|
||||
from openhands.server.monitoring import MonitoringListener
|
||||
from openhands.server.session.conversation import Conversation
|
||||
from openhands.server.session.conversation import ServerConversation
|
||||
from openhands.server.session.conversation_init_data import ConversationInitData
|
||||
from openhands.server.session.session import ROOM_KEY, Session
|
||||
from openhands.storage.conversation.conversation_store import ConversationStore
|
||||
@ -45,10 +45,10 @@ from openhands.utils.import_utils import get_impl
|
||||
|
||||
@dataclass
|
||||
class DockerNestedConversationManager(ConversationManager):
|
||||
"""Conversation manager where the agent loops exist inside the docker containers."""
|
||||
"""ServerConversation manager where the agent loops exist inside the docker containers."""
|
||||
|
||||
sio: socketio.AsyncServer
|
||||
config: AppConfig
|
||||
config: OpenHandsConfig
|
||||
server_config: ServerConfig
|
||||
file_store: FileStore
|
||||
docker_client: docker.DockerClient = field(default_factory=docker.from_env)
|
||||
@ -65,11 +65,11 @@ class DockerNestedConversationManager(ConversationManager):
|
||||
|
||||
async def attach_to_conversation(
|
||||
self, sid: str, user_id: str | None = None
|
||||
) -> Conversation | None:
|
||||
) -> ServerConversation | None:
|
||||
# Not supported - clients should connect directly to the nested server!
|
||||
raise ValueError('unsupported_operation')
|
||||
|
||||
async def detach_from_conversation(self, conversation: Conversation):
|
||||
async def detach_from_conversation(self, conversation: ServerConversation):
|
||||
# Not supported - clients should connect directly to the nested server!
|
||||
raise ValueError('unsupported_operation')
|
||||
|
||||
@ -309,7 +309,7 @@ class DockerNestedConversationManager(ConversationManager):
|
||||
def get_instance(
|
||||
cls,
|
||||
sio: socketio.AsyncServer,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
file_store: FileStore,
|
||||
server_config: ServerConfig,
|
||||
monitoring_listener: MonitoringListener,
|
||||
@ -433,7 +433,7 @@ class DockerNestedConversationManager(ConversationManager):
|
||||
volumes = [v.strip() for v in config.sandbox.volumes.split(',')]
|
||||
conversation_dir = get_conversation_dir(sid, user_id)
|
||||
volumes.append(
|
||||
f'{config.file_store_path}/{conversation_dir}:{AppConfig.model_fields["file_store_path"].default}/{conversation_dir}:rw'
|
||||
f'{config.file_store_path}/{conversation_dir}:{OpenHandsConfig.model_fields["file_store_path"].default}/{conversation_dir}:rw'
|
||||
)
|
||||
config.sandbox.volumes = ','.join(volumes)
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ from typing import Callable, Iterable
|
||||
|
||||
import socketio
|
||||
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
from openhands.core.exceptions import AgentRuntimeUnavailableError
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.core.schema.agent import AgentState
|
||||
@ -16,7 +16,7 @@ from openhands.server.config.server_config import ServerConfig
|
||||
from openhands.server.data_models.agent_loop_info import AgentLoopInfo
|
||||
from openhands.server.monitoring import MonitoringListener
|
||||
from openhands.server.session.agent_session import WAIT_TIME_BEFORE_CLOSE
|
||||
from openhands.server.session.conversation import Conversation
|
||||
from openhands.server.session.conversation import ServerConversation
|
||||
from openhands.server.session.session import ROOM_KEY, Session
|
||||
from openhands.storage.conversation.conversation_store import ConversationStore
|
||||
from openhands.storage.data_models.conversation_metadata import ConversationMetadata
|
||||
@ -41,17 +41,17 @@ class StandaloneConversationManager(ConversationManager):
|
||||
"""Manages conversations in standalone mode (single server instance)."""
|
||||
|
||||
sio: socketio.AsyncServer
|
||||
config: AppConfig
|
||||
config: OpenHandsConfig
|
||||
file_store: FileStore
|
||||
server_config: ServerConfig
|
||||
# Defaulting monitoring_listener for temp backward compatibility.
|
||||
monitoring_listener: MonitoringListener = MonitoringListener()
|
||||
_local_agent_loops_by_sid: dict[str, Session] = field(default_factory=dict)
|
||||
_local_connection_id_to_session_id: dict[str, str] = field(default_factory=dict)
|
||||
_active_conversations: dict[str, tuple[Conversation, int]] = field(
|
||||
_active_conversations: dict[str, tuple[ServerConversation, int]] = field(
|
||||
default_factory=dict
|
||||
)
|
||||
_detached_conversations: dict[str, tuple[Conversation, float]] = field(
|
||||
_detached_conversations: dict[str, tuple[ServerConversation, float]] = field(
|
||||
default_factory=dict
|
||||
)
|
||||
_conversations_lock: asyncio.Lock = field(default_factory=asyncio.Lock)
|
||||
@ -69,7 +69,7 @@ class StandaloneConversationManager(ConversationManager):
|
||||
|
||||
async def attach_to_conversation(
|
||||
self, sid: str, user_id: str | None = None
|
||||
) -> Conversation | None:
|
||||
) -> ServerConversation | None:
|
||||
start_time = time.time()
|
||||
if not await session_exists(sid, self.file_store, user_id=user_id):
|
||||
return None
|
||||
@ -94,7 +94,7 @@ class StandaloneConversationManager(ConversationManager):
|
||||
return conversation
|
||||
|
||||
# Create new conversation if none exists
|
||||
c = Conversation(
|
||||
c = ServerConversation(
|
||||
sid, file_store=self.file_store, config=self.config, user_id=user_id
|
||||
)
|
||||
try:
|
||||
@ -108,7 +108,7 @@ class StandaloneConversationManager(ConversationManager):
|
||||
return None
|
||||
end_time = time.time()
|
||||
logger.info(
|
||||
f'Conversation {c.sid} connected in {end_time - start_time} seconds'
|
||||
f'ServerConversation {c.sid} connected in {end_time - start_time} seconds'
|
||||
)
|
||||
self._active_conversations[sid] = (c, 1)
|
||||
return c
|
||||
@ -129,7 +129,7 @@ class StandaloneConversationManager(ConversationManager):
|
||||
agent_loop_info = await self.maybe_start_agent_loop(sid, settings, user_id)
|
||||
return agent_loop_info
|
||||
|
||||
async def detach_from_conversation(self, conversation: Conversation):
|
||||
async def detach_from_conversation(self, conversation: ServerConversation):
|
||||
sid = conversation.sid
|
||||
async with self._conversations_lock:
|
||||
if sid in self._active_conversations:
|
||||
@ -377,7 +377,7 @@ class StandaloneConversationManager(ConversationManager):
|
||||
def get_instance(
|
||||
cls,
|
||||
sio: socketio.AsyncServer,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
file_store: FileStore,
|
||||
server_config: ServerConfig,
|
||||
monitoring_listener: MonitoringListener | None,
|
||||
@ -475,7 +475,7 @@ class StandaloneConversationManager(ConversationManager):
|
||||
continue
|
||||
results.append(self._agent_loop_info_from_session(session))
|
||||
return results
|
||||
|
||||
|
||||
def _agent_loop_info_from_session(self, session: Session):
|
||||
return AgentLoopInfo(
|
||||
conversation_id=session.sid,
|
||||
@ -485,7 +485,7 @@ class StandaloneConversationManager(ConversationManager):
|
||||
)
|
||||
|
||||
def _get_conversation_url(self, conversation_id: str):
|
||||
return f"/api/conversations/{conversation_id}"
|
||||
return f'/api/conversations/{conversation_id}'
|
||||
|
||||
|
||||
def _last_updated_at_key(conversation: ConversationMetadata) -> float:
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import os
|
||||
import re
|
||||
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.server.shared import config as shared_config
|
||||
|
||||
@ -30,7 +30,7 @@ def sanitize_filename(filename: str) -> str:
|
||||
|
||||
|
||||
def load_file_upload_config(
|
||||
config: AppConfig = shared_config,
|
||||
config: OpenHandsConfig = shared_config,
|
||||
) -> tuple[int, bool, list[str]]:
|
||||
"""Load file upload configuration from the config object.
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
from openhands.events.event import Event
|
||||
|
||||
|
||||
@ -33,6 +33,6 @@ class MonitoringListener:
|
||||
@classmethod
|
||||
def get_instance(
|
||||
cls,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
) -> 'MonitoringListener':
|
||||
return cls()
|
||||
|
||||
@ -103,7 +103,7 @@ async def search_events(
|
||||
end_id: int | None = None,
|
||||
reverse: bool = False,
|
||||
filter: EventFilter | None = None,
|
||||
limit: int = 20
|
||||
limit: int = 20,
|
||||
):
|
||||
"""Search through the event stream with filtering and pagination.
|
||||
Args:
|
||||
@ -123,22 +123,24 @@ async def search_events(
|
||||
"""
|
||||
if not request.state.conversation:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail='Conversation not found'
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail='ServerConversation not found'
|
||||
)
|
||||
if limit < 0 or limit > 100:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST, detail='Invalid limit'
|
||||
)
|
||||
|
||||
|
||||
# Get matching events from the stream
|
||||
event_stream = request.state.conversation.event_stream
|
||||
events = list(event_stream.search_events(
|
||||
start_id=start_id,
|
||||
end_id=end_id,
|
||||
reverse=reverse,
|
||||
filter=filter,
|
||||
limit=limit + 1,
|
||||
))
|
||||
events = list(
|
||||
event_stream.search_events(
|
||||
start_id=start_id,
|
||||
end_id=end_id,
|
||||
reverse=reverse,
|
||||
filter=filter,
|
||||
limit=limit + 1,
|
||||
)
|
||||
)
|
||||
|
||||
# Check if there are more events
|
||||
has_more = len(events) > limit
|
||||
@ -156,4 +158,4 @@ async def search_events(
|
||||
async def add_event(request: Request):
|
||||
data = request.json()
|
||||
conversation_manager.send_to_event_stream(request.state.sid, data)
|
||||
return JSONResponse({"success": True})
|
||||
return JSONResponse({'success': True})
|
||||
|
||||
@ -1,27 +1,36 @@
|
||||
import re
|
||||
from typing import Annotated
|
||||
from pydantic import Field
|
||||
|
||||
from fastmcp import FastMCP
|
||||
from fastmcp.server.dependencies import get_http_request
|
||||
from pydantic import Field
|
||||
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.integrations.github.github_service import GithubServiceImpl
|
||||
from openhands.integrations.gitlab.gitlab_service import GitLabServiceImpl
|
||||
from openhands.integrations.provider import ProviderToken
|
||||
from openhands.integrations.service_types import ProviderType
|
||||
from openhands.server.shared import ConversationStoreImpl, config
|
||||
from openhands.server.user_auth import get_access_token, get_provider_tokens, get_user_id
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.server.user_auth import (
|
||||
get_access_token,
|
||||
get_provider_tokens,
|
||||
get_user_id,
|
||||
)
|
||||
from openhands.storage.data_models.conversation_metadata import ConversationMetadata
|
||||
|
||||
mcp_server = FastMCP('mcp')
|
||||
|
||||
|
||||
async def save_pr_metadata(user_id: str, conversation_id: str, tool_result: str) -> None:
|
||||
async def save_pr_metadata(
|
||||
user_id: str, conversation_id: str, tool_result: str
|
||||
) -> None:
|
||||
conversation_store = await ConversationStoreImpl.get_instance(config, user_id)
|
||||
conversation: ConversationMetadata = await conversation_store.get_metadata(conversation_id)
|
||||
conversation: ConversationMetadata = await conversation_store.get_metadata(
|
||||
conversation_id
|
||||
)
|
||||
|
||||
|
||||
pull_pattern = r"pull/(\d+)"
|
||||
merge_request_pattern = r"merge_requests/(\d+)"
|
||||
pull_pattern = r'pull/(\d+)'
|
||||
merge_request_pattern = r'merge_requests/(\d+)'
|
||||
|
||||
# Check if the tool_result contains the PR number
|
||||
pr_number = None
|
||||
@ -33,11 +42,11 @@ async def save_pr_metadata(user_id: str, conversation_id: str, tool_result: str)
|
||||
elif match_merge_request:
|
||||
pr_number = int(match_merge_request.group(1))
|
||||
|
||||
|
||||
if pr_number:
|
||||
conversation.pr_number.append(pr_number)
|
||||
await conversation_store.save_metadata(conversation)
|
||||
|
||||
|
||||
@mcp_server.tool()
|
||||
async def create_pr(
|
||||
repo_name: Annotated[
|
||||
@ -46,7 +55,7 @@ async def create_pr(
|
||||
source_branch: Annotated[str, Field(description='Source branch on repo')],
|
||||
target_branch: Annotated[str, Field(description='Target branch on repo')],
|
||||
title: Annotated[str, Field(description='PR Title')],
|
||||
body: Annotated[str | None, Field(description='PR body')]
|
||||
body: Annotated[str | None, Field(description='PR body')],
|
||||
) -> str:
|
||||
"""Open a draft PR in GitHub"""
|
||||
|
||||
@ -54,20 +63,24 @@ async def create_pr(
|
||||
|
||||
request = get_http_request()
|
||||
headers = request.headers
|
||||
conversation_id = headers.get('X-OpenHands-Conversation-ID', None)
|
||||
conversation_id = headers.get('X-OpenHands-ServerConversation-ID', None)
|
||||
|
||||
provider_tokens = await get_provider_tokens(request)
|
||||
access_token = await get_access_token(request)
|
||||
user_id = await get_user_id(request)
|
||||
|
||||
github_token = provider_tokens.get(ProviderType.GITHUB, ProviderToken()) if provider_tokens else ProviderToken()
|
||||
github_token = (
|
||||
provider_tokens.get(ProviderType.GITHUB, ProviderToken())
|
||||
if provider_tokens
|
||||
else ProviderToken()
|
||||
)
|
||||
|
||||
github_service = GithubServiceImpl(
|
||||
user_id=github_token.user_id,
|
||||
external_auth_id=user_id,
|
||||
external_auth_token=access_token,
|
||||
token=github_token.token,
|
||||
base_domain=github_token.host
|
||||
base_domain=github_token.host,
|
||||
)
|
||||
|
||||
try:
|
||||
@ -76,7 +89,7 @@ async def create_pr(
|
||||
source_branch=source_branch,
|
||||
target_branch=target_branch,
|
||||
title=title,
|
||||
body=body
|
||||
body=body,
|
||||
)
|
||||
|
||||
if conversation_id and user_id:
|
||||
@ -88,37 +101,41 @@ async def create_pr(
|
||||
return response
|
||||
|
||||
|
||||
|
||||
@mcp_server.tool()
|
||||
async def create_mr(
|
||||
id: Annotated[
|
||||
int | str, Field(description='GitLab repository (ID or URL-encoded path of the project)')
|
||||
int | str,
|
||||
Field(description='GitLab repository (ID or URL-encoded path of the project)'),
|
||||
],
|
||||
source_branch: Annotated[str, Field(description='Source branch on repo')],
|
||||
target_branch: Annotated[str, Field(description='Target branch on repo')],
|
||||
title: Annotated[str, Field(description='MR Title')],
|
||||
description: Annotated[str | None, Field(description='MR description')]
|
||||
description: Annotated[str | None, Field(description='MR description')],
|
||||
) -> str:
|
||||
"""Open a draft MR in GitLab"""
|
||||
|
||||
|
||||
logger.info('Calling OpenHands MCP create_mr')
|
||||
|
||||
request = get_http_request()
|
||||
headers = request.headers
|
||||
conversation_id = headers.get('X-OpenHands-Conversation-ID', None)
|
||||
conversation_id = headers.get('X-OpenHands-ServerConversation-ID', None)
|
||||
|
||||
provider_tokens = await get_provider_tokens(request)
|
||||
access_token = await get_access_token(request)
|
||||
user_id = await get_user_id(request)
|
||||
|
||||
github_token = provider_tokens.get(ProviderType.GITLAB, ProviderToken()) if provider_tokens else ProviderToken()
|
||||
github_token = (
|
||||
provider_tokens.get(ProviderType.GITLAB, ProviderToken())
|
||||
if provider_tokens
|
||||
else ProviderToken()
|
||||
)
|
||||
|
||||
github_service = GitLabServiceImpl(
|
||||
user_id=github_token.user_id,
|
||||
external_auth_id=user_id,
|
||||
external_auth_token=access_token,
|
||||
token=github_token.token,
|
||||
base_domain=github_token.host
|
||||
base_domain=github_token.host,
|
||||
)
|
||||
|
||||
try:
|
||||
@ -137,5 +154,3 @@ async def create_mr(
|
||||
response = str(e)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
|
||||
@ -1,16 +1,26 @@
|
||||
|
||||
|
||||
from typing import Any
|
||||
import uuid
|
||||
from typing import Any
|
||||
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.events.action.message import MessageAction
|
||||
from openhands.integrations.provider import CUSTOM_SECRETS_TYPE_WITH_JSON_SCHEMA, PROVIDER_TOKEN_TYPE
|
||||
from openhands.integrations.provider import (
|
||||
CUSTOM_SECRETS_TYPE_WITH_JSON_SCHEMA,
|
||||
PROVIDER_TOKEN_TYPE,
|
||||
)
|
||||
from openhands.integrations.service_types import ProviderType
|
||||
from openhands.server.data_models.agent_loop_info import AgentLoopInfo
|
||||
from openhands.server.session.conversation_init_data import ConversationInitData
|
||||
from openhands.server.shared import ConversationStoreImpl, SettingsStoreImpl, config, conversation_manager
|
||||
from openhands.server.shared import (
|
||||
ConversationStoreImpl,
|
||||
SettingsStoreImpl,
|
||||
config,
|
||||
conversation_manager,
|
||||
)
|
||||
from openhands.server.types import LLMAuthenticationError, MissingSettingsError
|
||||
from openhands.storage.data_models.conversation_metadata import ConversationMetadata, ConversationTrigger
|
||||
from openhands.storage.data_models.conversation_metadata import (
|
||||
ConversationMetadata,
|
||||
ConversationTrigger,
|
||||
)
|
||||
from openhands.utils.conversation_summary import get_default_conversation_title
|
||||
|
||||
|
||||
@ -69,7 +79,7 @@ async def create_new_conversation(
|
||||
conversation_init_data = ConversationInitData(**session_init_args)
|
||||
logger.info('Loading conversation store')
|
||||
conversation_store = await ConversationStoreImpl.get_instance(config, user_id)
|
||||
logger.info('Conversation store loaded')
|
||||
logger.info('ServerConversation store loaded')
|
||||
|
||||
# For nested runtimes, we allow a single conversation id, passed in on container creation
|
||||
if conversation_id is None:
|
||||
@ -101,7 +111,7 @@ async def create_new_conversation(
|
||||
extra={'user_id': user_id, 'session_id': conversation_id},
|
||||
)
|
||||
initial_message_action = None
|
||||
if initial_user_msg or image_urls:
|
||||
if initial_user_msg or image_urls:
|
||||
initial_message_action = MessageAction(
|
||||
content=initial_user_msg or '',
|
||||
image_urls=image_urls or [],
|
||||
@ -109,7 +119,7 @@ async def create_new_conversation(
|
||||
|
||||
if attach_convo_id and conversation_instructions:
|
||||
conversation_instructions = conversation_instructions.format(conversation_id)
|
||||
|
||||
|
||||
agent_loop_info = await conversation_manager.maybe_start_agent_loop(
|
||||
conversation_id,
|
||||
conversation_init_data,
|
||||
|
||||
@ -9,15 +9,18 @@ from openhands.controller import AgentController
|
||||
from openhands.controller.agent import Agent
|
||||
from openhands.controller.replay import ReplayManager
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import AgentConfig, AppConfig, LLMConfig
|
||||
from openhands.core.config import AgentConfig, LLMConfig, OpenHandsConfig
|
||||
from openhands.core.exceptions import AgentRuntimeUnavailableError
|
||||
from openhands.core.logger import OpenHandsLoggerAdapter
|
||||
from openhands.core.schema.agent import AgentState
|
||||
from openhands.events.action import ChangeAgentStateAction, MessageAction
|
||||
from openhands.events.event import Event, EventSource
|
||||
from openhands.events.stream import EventStream
|
||||
from openhands.integrations.provider import CUSTOM_SECRETS_TYPE, PROVIDER_TOKEN_TYPE, ProviderHandler
|
||||
from openhands.integrations.service_types import ProviderType
|
||||
from openhands.integrations.provider import (
|
||||
CUSTOM_SECRETS_TYPE,
|
||||
PROVIDER_TOKEN_TYPE,
|
||||
ProviderHandler,
|
||||
)
|
||||
from openhands.mcp import add_mcp_tools_to_agent
|
||||
from openhands.memory.memory import Memory
|
||||
from openhands.microagent.microagent import BaseMicroagent
|
||||
@ -80,7 +83,7 @@ class AgentSession:
|
||||
async def start(
|
||||
self,
|
||||
runtime_name: str,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
agent: Agent,
|
||||
max_iterations: int,
|
||||
git_provider_tokens: PROVIDER_TOKEN_TYPE | None = None,
|
||||
@ -118,7 +121,9 @@ class AgentSession:
|
||||
finished = False # For monitoring
|
||||
runtime_connected = False
|
||||
|
||||
custom_secrets_handler = UserSecrets(custom_secrets=custom_secrets if custom_secrets else {})
|
||||
custom_secrets_handler = UserSecrets(
|
||||
custom_secrets=custom_secrets if custom_secrets else {}
|
||||
)
|
||||
|
||||
try:
|
||||
self._create_security_analyzer(config.security.security_analyzer)
|
||||
@ -147,7 +152,7 @@ class AgentSession:
|
||||
selected_repository=selected_repository,
|
||||
repo_directory=repo_directory,
|
||||
conversation_instructions=conversation_instructions,
|
||||
custom_secrets_descriptions=custom_secrets_handler.get_custom_secrets_descriptions()
|
||||
custom_secrets_descriptions=custom_secrets_handler.get_custom_secrets_descriptions(),
|
||||
)
|
||||
|
||||
# NOTE: this needs to happen before controller is created
|
||||
@ -232,7 +237,7 @@ class AgentSession:
|
||||
initial_message: MessageAction | None,
|
||||
replay_json: str,
|
||||
agent: Agent,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
max_iterations: int,
|
||||
max_budget_per_task: float | None,
|
||||
agent_to_llm_config: dict[str, LLMConfig] | None,
|
||||
@ -271,11 +276,10 @@ class AgentSession:
|
||||
security_analyzer, SecurityAnalyzer
|
||||
)(self.event_stream)
|
||||
|
||||
|
||||
def override_provider_tokens_with_custom_secret(
|
||||
self,
|
||||
git_provider_tokens: PROVIDER_TOKEN_TYPE | None,
|
||||
custom_secrets: CUSTOM_SECRETS_TYPE | None
|
||||
custom_secrets: CUSTOM_SECRETS_TYPE | None,
|
||||
):
|
||||
if git_provider_tokens and custom_secrets:
|
||||
tokens = dict(git_provider_tokens)
|
||||
@ -283,15 +287,14 @@ class AgentSession:
|
||||
token_name = ProviderHandler.get_provider_env_key(provider)
|
||||
if token_name in custom_secrets or token_name.upper() in custom_secrets:
|
||||
del tokens[provider]
|
||||
|
||||
|
||||
return MappingProxyType(tokens)
|
||||
return git_provider_tokens
|
||||
|
||||
|
||||
async def _create_runtime(
|
||||
self,
|
||||
runtime_name: str,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
agent: Agent,
|
||||
git_provider_tokens: PROVIDER_TOKEN_TYPE | None = None,
|
||||
custom_secrets: CUSTOM_SECRETS_TYPE | None = None,
|
||||
@ -317,10 +320,14 @@ class AgentSession:
|
||||
|
||||
self.logger.debug(f'Initializing runtime `{runtime_name}` now...')
|
||||
runtime_cls = get_runtime_cls(runtime_name)
|
||||
if runtime_cls == RemoteRuntime:
|
||||
if runtime_cls == RemoteRuntime:
|
||||
# If provider tokens is passed in custom secrets, then remove provider from provider tokens
|
||||
# We prioritize provider tokens set in custom secrets
|
||||
provider_tokens_without_gitlab = self.override_provider_tokens_with_custom_secret(git_provider_tokens, custom_secrets)
|
||||
provider_tokens_without_gitlab = (
|
||||
self.override_provider_tokens_with_custom_secret(
|
||||
git_provider_tokens, custom_secrets
|
||||
)
|
||||
)
|
||||
|
||||
self.runtime = runtime_cls(
|
||||
config=config,
|
||||
@ -339,7 +346,7 @@ class AgentSession:
|
||||
provider_tokens=git_provider_tokens
|
||||
or cast(PROVIDER_TOKEN_TYPE, MappingProxyType({}))
|
||||
)
|
||||
|
||||
|
||||
# Merge git provider tokens with custom secrets before passing over to runtime
|
||||
env_vars.update(await provider_handler.get_env_vars(expose_secrets=True))
|
||||
self.runtime = runtime_cls(
|
||||
@ -436,11 +443,11 @@ class AgentSession:
|
||||
return controller
|
||||
|
||||
async def _create_memory(
|
||||
self,
|
||||
selected_repository: str | None,
|
||||
repo_directory: str | None,
|
||||
self,
|
||||
selected_repository: str | None,
|
||||
repo_directory: str | None,
|
||||
conversation_instructions: str | None,
|
||||
custom_secrets_descriptions: dict[str, str]
|
||||
custom_secrets_descriptions: dict[str, str],
|
||||
) -> Memory:
|
||||
memory = Memory(
|
||||
event_stream=self.event_stream,
|
||||
@ -461,10 +468,7 @@ class AgentSession:
|
||||
memory.load_user_workspace_microagents(microagents)
|
||||
|
||||
if selected_repository and repo_directory:
|
||||
memory.set_repository_info(
|
||||
selected_repository,
|
||||
repo_directory
|
||||
)
|
||||
memory.set_repository_info(selected_repository, repo_directory)
|
||||
return memory
|
||||
|
||||
def _maybe_restore_state(self) -> State | None:
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import asyncio
|
||||
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.events.stream import EventStream
|
||||
from openhands.runtime import get_runtime_cls
|
||||
from openhands.runtime.base import Runtime
|
||||
@ -9,7 +9,7 @@ from openhands.storage.files import FileStore
|
||||
from openhands.utils.async_utils import call_sync_from_async
|
||||
|
||||
|
||||
class Conversation:
|
||||
class ServerConversation:
|
||||
sid: str
|
||||
file_store: FileStore
|
||||
event_stream: EventStream
|
||||
@ -17,7 +17,11 @@ class Conversation:
|
||||
user_id: str | None
|
||||
|
||||
def __init__(
|
||||
self, sid: str, file_store: FileStore, config: AppConfig, user_id: str | None
|
||||
self,
|
||||
sid: str,
|
||||
file_store: FileStore,
|
||||
config: OpenHandsConfig,
|
||||
user_id: str | None,
|
||||
):
|
||||
self.sid = sid
|
||||
self.config = config
|
||||
|
||||
@ -6,7 +6,7 @@ from logging import LoggerAdapter
|
||||
import socketio
|
||||
|
||||
from openhands.controller.agent import Agent
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.core.config.condenser_config import (
|
||||
BrowserOutputCondenserConfig,
|
||||
CondenserPipelineConfig,
|
||||
@ -43,7 +43,7 @@ class Session:
|
||||
is_alive: bool = True
|
||||
agent_session: AgentSession
|
||||
loop: asyncio.AbstractEventLoop
|
||||
config: AppConfig
|
||||
config: OpenHandsConfig
|
||||
file_store: FileStore
|
||||
user_id: str | None
|
||||
logger: LoggerAdapter
|
||||
@ -51,7 +51,7 @@ class Session:
|
||||
def __init__(
|
||||
self,
|
||||
sid: str,
|
||||
config: AppConfig,
|
||||
config: OpenHandsConfig,
|
||||
file_store: FileStore,
|
||||
sio: socketio.AsyncServer | None,
|
||||
user_id: str | None = None,
|
||||
@ -128,9 +128,15 @@ class Session:
|
||||
self.config.search_api_key = settings.search_api_key
|
||||
|
||||
# NOTE: this need to happen AFTER the config is updated with the search_api_key
|
||||
self.config.mcp = settings.mcp_config or MCPConfig(sse_servers=[], stdio_servers=[])
|
||||
self.config.mcp = settings.mcp_config or MCPConfig(
|
||||
sse_servers=[], stdio_servers=[]
|
||||
)
|
||||
# Add OpenHands' MCP server by default
|
||||
openhands_mcp_server, openhands_mcp_stdio_servers = OpenHandsMCPConfigImpl.create_default_mcp_server_config(self.config.mcp_host, self.config, self.user_id)
|
||||
openhands_mcp_server, openhands_mcp_stdio_servers = (
|
||||
OpenHandsMCPConfigImpl.create_default_mcp_server_config(
|
||||
self.config.mcp_host, self.config, self.user_id
|
||||
)
|
||||
)
|
||||
if openhands_mcp_server:
|
||||
self.config.mcp.sse_servers.append(openhands_mcp_server)
|
||||
self.config.mcp.stdio_servers.extend(openhands_mcp_stdio_servers)
|
||||
@ -154,7 +160,7 @@ class Session:
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
self.logger.info(
|
||||
f'Enabling pipeline condenser with:'
|
||||
f' browser_output_masking(attention_window=2), '
|
||||
|
||||
@ -3,8 +3,8 @@ import os
|
||||
import socketio
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from openhands.core.config import load_app_config
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config import load_openhands_config
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
from openhands.server.config.server_config import ServerConfig, load_server_config
|
||||
from openhands.server.conversation_manager.conversation_manager import (
|
||||
ConversationManager,
|
||||
@ -20,7 +20,7 @@ from openhands.utils.import_utils import get_impl
|
||||
|
||||
load_dotenv()
|
||||
|
||||
config: AppConfig = load_app_config()
|
||||
config: OpenHandsConfig = load_openhands_config()
|
||||
server_config_interface: ServerConfigInterface = load_server_config()
|
||||
assert isinstance(server_config_interface, ServerConfig), (
|
||||
'Loaded server config interface is not a ServerConfig, despite this being assumed'
|
||||
|
||||
@ -3,7 +3,7 @@ from __future__ import annotations
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Iterable
|
||||
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
from openhands.storage.data_models.conversation_metadata import ConversationMetadata
|
||||
from openhands.storage.data_models.conversation_metadata_result_set import (
|
||||
ConversationMetadataResultSet,
|
||||
@ -22,9 +22,7 @@ class ConversationStore(ABC):
|
||||
async def get_metadata(self, conversation_id: str) -> ConversationMetadata:
|
||||
"""Load conversation metadata."""
|
||||
|
||||
async def validate_metadata(
|
||||
self, conversation_id: str, user_id: str
|
||||
) -> bool:
|
||||
async def validate_metadata(self, conversation_id: str, user_id: str) -> bool:
|
||||
"""Validate that conversation belongs to the current user."""
|
||||
metadata = await self.get_metadata(conversation_id)
|
||||
if not metadata.user_id or metadata.user_id != user_id:
|
||||
@ -57,6 +55,6 @@ class ConversationStore(ABC):
|
||||
@classmethod
|
||||
@abstractmethod
|
||||
async def get_instance(
|
||||
cls, config: AppConfig, user_id: str | None
|
||||
cls, config: OpenHandsConfig, user_id: str | None
|
||||
) -> ConversationStore:
|
||||
"""Get a store for the user represented by the token given."""
|
||||
|
||||
@ -6,7 +6,7 @@ from pathlib import Path
|
||||
|
||||
from pydantic import TypeAdapter
|
||||
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.storage import get_file_store
|
||||
from openhands.storage.conversation.conversation_store import ConversationStore
|
||||
@ -42,7 +42,7 @@ class FileConversationStore(ConversationStore):
|
||||
json_obj = json.loads(json_str)
|
||||
if 'created_at' not in json_obj:
|
||||
raise FileNotFoundError(path)
|
||||
|
||||
|
||||
# Remove github_user_id if it exists
|
||||
if 'github_user_id' in json_obj:
|
||||
json_obj.pop('github_user_id')
|
||||
@ -103,7 +103,7 @@ class FileConversationStore(ConversationStore):
|
||||
|
||||
@classmethod
|
||||
async def get_instance(
|
||||
cls, config: AppConfig, user_id: str | None
|
||||
cls, config: OpenHandsConfig, user_id: str | None
|
||||
) -> FileConversationStore:
|
||||
file_store = get_file_store(config.file_store, config.file_store_path)
|
||||
return FileConversationStore(file_store)
|
||||
|
||||
@ -12,7 +12,7 @@ from pydantic.json import pydantic_encoder
|
||||
|
||||
from openhands.core.config.llm_config import LLMConfig
|
||||
from openhands.core.config.mcp_config import MCPConfig
|
||||
from openhands.core.config.utils import load_app_config
|
||||
from openhands.core.config.utils import load_openhands_config
|
||||
from openhands.storage.data_models.user_secrets import UserSecrets
|
||||
|
||||
|
||||
@ -41,7 +41,6 @@ class Settings(BaseModel):
|
||||
mcp_config: MCPConfig | None = None
|
||||
search_api_key: SecretStr | None = None
|
||||
|
||||
|
||||
model_config = {
|
||||
'validate_assignment': True,
|
||||
}
|
||||
@ -54,7 +53,7 @@ class Settings(BaseModel):
|
||||
"""
|
||||
if api_key is None:
|
||||
return None
|
||||
|
||||
|
||||
context = info.context
|
||||
if context and context.get('expose_secrets', False):
|
||||
return api_key.get_secret_value()
|
||||
@ -106,7 +105,7 @@ class Settings(BaseModel):
|
||||
|
||||
@staticmethod
|
||||
def from_config() -> Settings | None:
|
||||
app_config = load_app_config()
|
||||
app_config = load_openhands_config()
|
||||
llm_config: LLMConfig = app_config.get_llm_config()
|
||||
if llm_config.api_key is None:
|
||||
# If no api key has been set, we take this to mean that there is no reasonable default
|
||||
|
||||
@ -3,7 +3,7 @@ from __future__ import annotations
|
||||
import json
|
||||
from dataclasses import dataclass
|
||||
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
from openhands.storage import get_file_store
|
||||
from openhands.storage.data_models.user_secrets import UserSecrets
|
||||
from openhands.storage.files import FileStore
|
||||
@ -37,7 +37,7 @@ class FileSecretsStore(SecretsStore):
|
||||
|
||||
@classmethod
|
||||
async def get_instance(
|
||||
cls, config: AppConfig, user_id: str | None
|
||||
cls, config: OpenHandsConfig, user_id: str | None
|
||||
) -> FileSecretsStore:
|
||||
file_store = get_file_store(config.file_store, config.file_store_path)
|
||||
return FileSecretsStore(file_store)
|
||||
|
||||
@ -2,7 +2,7 @@ from __future__ import annotations
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
from openhands.storage.data_models.user_secrets import UserSecrets
|
||||
|
||||
|
||||
@ -19,5 +19,7 @@ class SecretsStore(ABC):
|
||||
|
||||
@classmethod
|
||||
@abstractmethod
|
||||
async def get_instance(cls, config: AppConfig, user_id: str | None) -> SecretsStore:
|
||||
async def get_instance(
|
||||
cls, config: OpenHandsConfig, user_id: str | None
|
||||
) -> SecretsStore:
|
||||
"""Get a store for the user represented by the token given."""
|
||||
|
||||
@ -3,7 +3,7 @@ from __future__ import annotations
|
||||
import json
|
||||
from dataclasses import dataclass
|
||||
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
from openhands.storage import get_file_store
|
||||
from openhands.storage.data_models.settings import Settings
|
||||
from openhands.storage.files import FileStore
|
||||
@ -31,7 +31,7 @@ class FileSettingsStore(SettingsStore):
|
||||
|
||||
@classmethod
|
||||
async def get_instance(
|
||||
cls, config: AppConfig, user_id: str | None
|
||||
cls, config: OpenHandsConfig, user_id: str | None
|
||||
) -> FileSettingsStore:
|
||||
file_store = get_file_store(config.file_store, config.file_store_path)
|
||||
return FileSettingsStore(file_store)
|
||||
|
||||
@ -2,7 +2,7 @@ from __future__ import annotations
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
from openhands.storage.data_models.settings import Settings
|
||||
|
||||
|
||||
@ -20,6 +20,6 @@ class SettingsStore(ABC):
|
||||
@classmethod
|
||||
@abstractmethod
|
||||
async def get_instance(
|
||||
cls, config: AppConfig, user_id: str | None
|
||||
cls, config: OpenHandsConfig, user_id: str | None
|
||||
) -> SettingsStore:
|
||||
"""Get a store for the user represented by the token given."""
|
||||
|
||||
@ -6,12 +6,12 @@ with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore')
|
||||
import litellm
|
||||
|
||||
from openhands.core.config import AppConfig, LLMConfig
|
||||
from openhands.core.config import LLMConfig, OpenHandsConfig
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.llm import bedrock
|
||||
|
||||
|
||||
def get_supported_llm_models(config: AppConfig) -> list[str]:
|
||||
def get_supported_llm_models(config: OpenHandsConfig) -> list[str]:
|
||||
"""Get all models supported by LiteLLM.
|
||||
|
||||
This function combines models from litellm and Bedrock, removing any
|
||||
|
||||
@ -7,7 +7,7 @@ import time
|
||||
import pytest
|
||||
from pytest import TempPathFactory
|
||||
|
||||
from openhands.core.config import AppConfig, MCPConfig, load_app_config
|
||||
from openhands.core.config import MCPConfig, OpenHandsConfig, load_openhands_config
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.events import EventStream
|
||||
from openhands.runtime.base import Runtime
|
||||
@ -218,14 +218,14 @@ def _load_runtime(
|
||||
runtime_startup_env_vars: dict[str, str] | None = None,
|
||||
docker_runtime_kwargs: dict[str, str] | None = None,
|
||||
override_mcp_config: MCPConfig | None = None,
|
||||
) -> tuple[Runtime, AppConfig]:
|
||||
) -> tuple[Runtime, OpenHandsConfig]:
|
||||
sid = 'rt_' + str(random.randint(100000, 999999))
|
||||
|
||||
# AgentSkills need to be initialized **before** Jupyter
|
||||
# otherwise Jupyter will not access the proper dependencies installed by AgentSkills
|
||||
plugins = [AgentSkillsRequirement(), JupyterRequirement()]
|
||||
|
||||
config = load_app_config()
|
||||
config = load_openhands_config()
|
||||
config.run_as_openhands = run_as_openhands
|
||||
config.sandbox.force_rebuild_runtime = force_rebuild_runtime
|
||||
config.sandbox.keep_runtime_alive = False
|
||||
|
||||
@ -208,7 +208,7 @@ async def test_add_mcp_tools_from_microagents():
|
||||
"""Test that add_mcp_tools_to_agent adds tools from microagents."""
|
||||
# Import ActionExecutionClient for mocking
|
||||
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
from openhands.runtime.impl.action_execution.action_execution_client import (
|
||||
ActionExecutionClient,
|
||||
)
|
||||
@ -219,8 +219,8 @@ async def test_add_mcp_tools_from_microagents():
|
||||
mock_memory = MagicMock()
|
||||
mock_mcp_config = MCPConfig()
|
||||
|
||||
# Create a mock AppConfig with the MCP config
|
||||
mock_app_config = AppConfig(mcp=mock_mcp_config, search_api_key=None)
|
||||
# Create a mock OpenHandsConfig with the MCP config
|
||||
mock_app_config = OpenHandsConfig(mcp=mock_mcp_config, search_api_key=None)
|
||||
|
||||
# Configure the mock memory to return a microagent MCP config
|
||||
mock_stdio_server = MCPStdioServerConfig(
|
||||
@ -247,7 +247,7 @@ async def test_add_mcp_tools_from_microagents():
|
||||
'openhands.mcp.utils.fetch_mcp_tools_from_config',
|
||||
new=AsyncMock(return_value=[mock_tool]),
|
||||
):
|
||||
# Call the function with the AppConfig instead of MCPConfig
|
||||
# Call the function with the OpenHandsConfig instead of MCPConfig
|
||||
await add_mcp_tools_to_agent(
|
||||
mock_agent, mock_runtime, mock_memory, mock_app_config
|
||||
)
|
||||
|
||||
@ -6,8 +6,8 @@ from pathlib import Path
|
||||
from conftest import _close_test_runtime, _load_runtime
|
||||
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config.config_utils import OH_DEFAULT_AGENT
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
from openhands.core.main import run_controller
|
||||
from openhands.core.schema.agent import AgentState
|
||||
from openhands.events.action.empty import NullAction
|
||||
@ -17,7 +17,7 @@ from openhands.events.observation.commands import CmdOutputObservation
|
||||
|
||||
|
||||
def _get_config(trajectory_name: str, agent: str = OH_DEFAULT_AGENT):
|
||||
return AppConfig(
|
||||
return OpenHandsConfig(
|
||||
default_agent=agent,
|
||||
run_as_openhands=False,
|
||||
# do not mount workspace
|
||||
|
||||
@ -37,8 +37,8 @@ from openhands.agenthub import Agent
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AgentConfig,
|
||||
AppConfig,
|
||||
LLMConfig,
|
||||
OpenHandsConfig,
|
||||
SandboxConfig,
|
||||
)
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
@ -60,8 +60,8 @@ AGENT_CLS_TO_FAKE_USER_RESPONSE_FN = {
|
||||
}
|
||||
|
||||
|
||||
def get_config() -> AppConfig:
|
||||
config = AppConfig(
|
||||
def get_config() -> OpenHandsConfig:
|
||||
config = OpenHandsConfig(
|
||||
run_as_openhands=False,
|
||||
runtime=os.environ.get('RUNTIME', 'remote'),
|
||||
sandbox=SandboxConfig(
|
||||
|
||||
@ -1,135 +1,168 @@
|
||||
import pytest
|
||||
|
||||
from openhands.core.config.agent_config import AgentConfig
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config.utils import finalize_config, load_from_env, load_from_toml
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
from openhands.core.config.utils import finalize_config
|
||||
|
||||
# Define a dummy agent name often used in tests or as a default
|
||||
DEFAULT_AGENT_NAME = 'CodeActAgent'
|
||||
|
||||
|
||||
def test_finalize_config_cli_disables_jupyter_and_browsing_when_true():
|
||||
"""
|
||||
Test that finalize_config sets enable_jupyter and enable_browsing to False
|
||||
when runtime is 'cli' and they were initially True.
|
||||
"""
|
||||
app_config = AppConfig()
|
||||
app_config = OpenHandsConfig()
|
||||
app_config.runtime = 'cli'
|
||||
|
||||
|
||||
agent_config = AgentConfig(enable_jupyter=True, enable_browsing=True)
|
||||
app_config.agents[DEFAULT_AGENT_NAME] = agent_config
|
||||
|
||||
|
||||
finalize_config(app_config)
|
||||
|
||||
assert not app_config.agents[DEFAULT_AGENT_NAME].enable_jupyter, \
|
||||
|
||||
assert not app_config.agents[DEFAULT_AGENT_NAME].enable_jupyter, (
|
||||
"enable_jupyter should be False when runtime is 'cli'"
|
||||
assert not app_config.agents[DEFAULT_AGENT_NAME].enable_browsing, \
|
||||
)
|
||||
assert not app_config.agents[DEFAULT_AGENT_NAME].enable_browsing, (
|
||||
"enable_browsing should be False when runtime is 'cli'"
|
||||
)
|
||||
|
||||
|
||||
def test_finalize_config_cli_keeps_jupyter_and_browsing_false_when_false():
|
||||
"""
|
||||
Test that finalize_config keeps enable_jupyter and enable_browsing as False
|
||||
when runtime is 'cli' and they were initially False.
|
||||
"""
|
||||
app_config = AppConfig()
|
||||
app_config = OpenHandsConfig()
|
||||
app_config.runtime = 'cli'
|
||||
|
||||
|
||||
agent_config = AgentConfig(enable_jupyter=False, enable_browsing=False)
|
||||
app_config.agents[DEFAULT_AGENT_NAME] = agent_config
|
||||
|
||||
|
||||
finalize_config(app_config)
|
||||
|
||||
assert not app_config.agents[DEFAULT_AGENT_NAME].enable_jupyter, \
|
||||
|
||||
assert not app_config.agents[DEFAULT_AGENT_NAME].enable_jupyter, (
|
||||
"enable_jupyter should remain False when runtime is 'cli' and initially False"
|
||||
assert not app_config.agents[DEFAULT_AGENT_NAME].enable_browsing, \
|
||||
)
|
||||
assert not app_config.agents[DEFAULT_AGENT_NAME].enable_browsing, (
|
||||
"enable_browsing should remain False when runtime is 'cli' and initially False"
|
||||
)
|
||||
|
||||
|
||||
def test_finalize_config_other_runtime_keeps_jupyter_and_browsing_true_by_default():
|
||||
"""
|
||||
Test that finalize_config keeps enable_jupyter and enable_browsing as True (default)
|
||||
when runtime is not 'cli'.
|
||||
"""
|
||||
app_config = AppConfig()
|
||||
app_config = OpenHandsConfig()
|
||||
app_config.runtime = 'docker' # A non-cli runtime
|
||||
|
||||
|
||||
# AgentConfig defaults enable_jupyter and enable_browsing to True
|
||||
agent_config = AgentConfig()
|
||||
app_config.agents[DEFAULT_AGENT_NAME] = agent_config
|
||||
|
||||
|
||||
finalize_config(app_config)
|
||||
|
||||
assert app_config.agents[DEFAULT_AGENT_NAME].enable_jupyter, \
|
||||
"enable_jupyter should remain True by default for non-cli runtimes"
|
||||
assert app_config.agents[DEFAULT_AGENT_NAME].enable_browsing, \
|
||||
"enable_browsing should remain True by default for non-cli runtimes"
|
||||
|
||||
assert app_config.agents[DEFAULT_AGENT_NAME].enable_jupyter, (
|
||||
'enable_jupyter should remain True by default for non-cli runtimes'
|
||||
)
|
||||
assert app_config.agents[DEFAULT_AGENT_NAME].enable_browsing, (
|
||||
'enable_browsing should remain True by default for non-cli runtimes'
|
||||
)
|
||||
|
||||
|
||||
def test_finalize_config_other_runtime_keeps_jupyter_and_browsing_false_if_set():
|
||||
"""
|
||||
Test that finalize_config keeps enable_jupyter and enable_browsing as False
|
||||
when runtime is not 'cli' but they were explicitly set to False.
|
||||
"""
|
||||
app_config = AppConfig()
|
||||
app_config = OpenHandsConfig()
|
||||
app_config.runtime = 'docker' # A non-cli runtime
|
||||
|
||||
|
||||
agent_config = AgentConfig(enable_jupyter=False, enable_browsing=False)
|
||||
app_config.agents[DEFAULT_AGENT_NAME] = agent_config
|
||||
|
||||
|
||||
finalize_config(app_config)
|
||||
|
||||
assert not app_config.agents[DEFAULT_AGENT_NAME].enable_jupyter, \
|
||||
"enable_jupyter should remain False for non-cli runtimes if explicitly set to False"
|
||||
assert not app_config.agents[DEFAULT_AGENT_NAME].enable_browsing, \
|
||||
"enable_browsing should remain False for non-cli runtimes if explicitly set to False"
|
||||
|
||||
assert not app_config.agents[DEFAULT_AGENT_NAME].enable_jupyter, (
|
||||
'enable_jupyter should remain False for non-cli runtimes if explicitly set to False'
|
||||
)
|
||||
assert not app_config.agents[DEFAULT_AGENT_NAME].enable_browsing, (
|
||||
'enable_browsing should remain False for non-cli runtimes if explicitly set to False'
|
||||
)
|
||||
|
||||
|
||||
def test_finalize_config_no_agents_defined():
|
||||
"""
|
||||
Test that finalize_config runs without error if no agents are defined in the config,
|
||||
even when runtime is 'cli'.
|
||||
"""
|
||||
app_config = AppConfig()
|
||||
app_config = OpenHandsConfig()
|
||||
app_config.runtime = 'cli'
|
||||
# No agents are added to app_config.agents
|
||||
|
||||
|
||||
try:
|
||||
finalize_config(app_config)
|
||||
except Exception as e:
|
||||
pytest.fail(f"finalize_config raised an exception with no agents defined: {e}")
|
||||
pytest.fail(f'finalize_config raised an exception with no agents defined: {e}')
|
||||
|
||||
|
||||
def test_finalize_config_multiple_agents_cli_runtime():
|
||||
"""
|
||||
Test that finalize_config correctly disables jupyter and browsing for multiple agents
|
||||
when runtime is 'cli'.
|
||||
"""
|
||||
app_config = AppConfig()
|
||||
app_config = OpenHandsConfig()
|
||||
app_config.runtime = 'cli'
|
||||
|
||||
|
||||
agent_config1 = AgentConfig(enable_jupyter=True, enable_browsing=True)
|
||||
agent_config2 = AgentConfig(enable_jupyter=True, enable_browsing=True)
|
||||
app_config.agents['Agent1'] = agent_config1
|
||||
app_config.agents['Agent2'] = agent_config2
|
||||
|
||||
|
||||
finalize_config(app_config)
|
||||
|
||||
assert not app_config.agents['Agent1'].enable_jupyter, "Jupyter should be disabled for Agent1"
|
||||
assert not app_config.agents['Agent1'].enable_browsing, "Browsing should be disabled for Agent1"
|
||||
assert not app_config.agents['Agent2'].enable_jupyter, "Jupyter should be disabled for Agent2"
|
||||
assert not app_config.agents['Agent2'].enable_browsing, "Browsing should be disabled for Agent2"
|
||||
|
||||
assert not app_config.agents['Agent1'].enable_jupyter, (
|
||||
'Jupyter should be disabled for Agent1'
|
||||
)
|
||||
assert not app_config.agents['Agent1'].enable_browsing, (
|
||||
'Browsing should be disabled for Agent1'
|
||||
)
|
||||
assert not app_config.agents['Agent2'].enable_jupyter, (
|
||||
'Jupyter should be disabled for Agent2'
|
||||
)
|
||||
assert not app_config.agents['Agent2'].enable_browsing, (
|
||||
'Browsing should be disabled for Agent2'
|
||||
)
|
||||
|
||||
|
||||
def test_finalize_config_multiple_agents_other_runtime():
|
||||
"""
|
||||
Test that finalize_config correctly keeps jupyter and browsing enabled (or as set)
|
||||
for multiple agents when runtime is not 'cli'.
|
||||
"""
|
||||
app_config = AppConfig()
|
||||
app_config = OpenHandsConfig()
|
||||
app_config.runtime = 'docker'
|
||||
|
||||
agent_config1 = AgentConfig(enable_jupyter=True, enable_browsing=True) # Defaults
|
||||
agent_config2 = AgentConfig(enable_jupyter=False, enable_browsing=False) # Explicitly false
|
||||
|
||||
agent_config1 = AgentConfig(enable_jupyter=True, enable_browsing=True) # Defaults
|
||||
agent_config2 = AgentConfig(
|
||||
enable_jupyter=False, enable_browsing=False
|
||||
) # Explicitly false
|
||||
app_config.agents['Agent1'] = agent_config1
|
||||
app_config.agents['Agent2'] = agent_config2
|
||||
|
||||
|
||||
finalize_config(app_config)
|
||||
|
||||
assert app_config.agents['Agent1'].enable_jupyter, "Jupyter should be True for Agent1"
|
||||
assert app_config.agents['Agent1'].enable_browsing, "Browsing should be True for Agent1"
|
||||
assert not app_config.agents['Agent2'].enable_jupyter, "Jupyter should be False for Agent2"
|
||||
assert not app_config.agents['Agent2'].enable_browsing, "Browsing should be False for Agent2"
|
||||
|
||||
assert app_config.agents['Agent1'].enable_jupyter, (
|
||||
'Jupyter should be True for Agent1'
|
||||
)
|
||||
assert app_config.agents['Agent1'].enable_browsing, (
|
||||
'Browsing should be True for Agent1'
|
||||
)
|
||||
assert not app_config.agents['Agent2'].enable_jupyter, (
|
||||
'Jupyter should be False for Agent2'
|
||||
)
|
||||
assert not app_config.agents['Agent2'].enable_browsing, (
|
||||
'Browsing should be False for Agent2'
|
||||
)
|
||||
|
||||
@ -525,7 +525,10 @@ async def test_process_issue(
|
||||
patch(
|
||||
'openhands.resolver.issue_resolver.SandboxConfig', return_value=MagicMock()
|
||||
),
|
||||
patch('openhands.resolver.issue_resolver.AppConfig', return_value=MagicMock()),
|
||||
patch(
|
||||
'openhands.resolver.issue_resolver.OpenHandsConfig',
|
||||
return_value=MagicMock(),
|
||||
),
|
||||
):
|
||||
# Call the process_issue method
|
||||
result = await resolver.process_issue(issue, base_commit, handler_instance)
|
||||
|
||||
@ -4,13 +4,13 @@ from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from openhands.core.config import load_app_config
|
||||
from openhands.core.config import load_openhands_config
|
||||
from openhands.core.exceptions import UserCancelledError
|
||||
from openhands.llm.async_llm import AsyncLLM
|
||||
from openhands.llm.llm import LLM
|
||||
from openhands.llm.streaming_llm import StreamingLLM
|
||||
|
||||
config = load_app_config()
|
||||
config = load_openhands_config()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
||||
@ -12,7 +12,7 @@ from litellm import (
|
||||
from openhands.controller.agent import Agent
|
||||
from openhands.controller.agent_controller import AgentController
|
||||
from openhands.controller.state.state import State, TrafficControlState
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.core.config.agent_config import AgentConfig
|
||||
from openhands.core.main import run_controller
|
||||
from openhands.core.schema import AgentState
|
||||
@ -55,7 +55,7 @@ def mock_agent():
|
||||
agent = MagicMock(spec=Agent)
|
||||
agent.llm = MagicMock(spec=LLM)
|
||||
agent.llm.metrics = Metrics()
|
||||
agent.llm.config = AppConfig().get_llm_config()
|
||||
agent.llm.config = OpenHandsConfig().get_llm_config()
|
||||
|
||||
# Add config with enable_mcp attribute
|
||||
agent.config = MagicMock(spec=AgentConfig)
|
||||
@ -235,7 +235,7 @@ async def test_react_to_content_policy_violation(
|
||||
async def test_run_controller_with_fatal_error(
|
||||
test_event_stream, mock_memory, mock_agent
|
||||
):
|
||||
config = AppConfig()
|
||||
config = OpenHandsConfig()
|
||||
|
||||
def agent_step_fn(state):
|
||||
print(f'agent_step_fn received state: {state}')
|
||||
@ -300,7 +300,7 @@ async def test_run_controller_with_fatal_error(
|
||||
async def test_run_controller_stop_with_stuck(
|
||||
test_event_stream, mock_memory, mock_agent
|
||||
):
|
||||
config = AppConfig()
|
||||
config = OpenHandsConfig()
|
||||
|
||||
def agent_step_fn(state):
|
||||
print(f'agent_step_fn received state: {state}')
|
||||
@ -653,7 +653,7 @@ async def test_reset_with_pending_action_no_metadata(
|
||||
async def test_run_controller_max_iterations_has_metrics(
|
||||
test_event_stream, mock_memory, mock_agent
|
||||
):
|
||||
config = AppConfig(
|
||||
config = OpenHandsConfig(
|
||||
max_iterations=3,
|
||||
)
|
||||
event_stream = test_event_stream
|
||||
@ -805,7 +805,7 @@ async def test_context_window_exceeded_error_handling(
|
||||
# handles the truncation correctly.
|
||||
final_state = await asyncio.wait_for(
|
||||
run_controller(
|
||||
config=AppConfig(max_iterations=max_iterations),
|
||||
config=OpenHandsConfig(max_iterations=max_iterations),
|
||||
initial_user_action=MessageAction(content='INITIAL'),
|
||||
runtime=mock_runtime,
|
||||
sid='test',
|
||||
@ -943,7 +943,7 @@ async def test_run_controller_with_context_window_exceeded_with_truncation(
|
||||
try:
|
||||
state = await asyncio.wait_for(
|
||||
run_controller(
|
||||
config=AppConfig(max_iterations=5),
|
||||
config=OpenHandsConfig(max_iterations=5),
|
||||
initial_user_action=MessageAction(content='INITIAL'),
|
||||
runtime=mock_runtime,
|
||||
sid='test',
|
||||
@ -1019,7 +1019,7 @@ async def test_run_controller_with_context_window_exceeded_without_truncation(
|
||||
try:
|
||||
state = await asyncio.wait_for(
|
||||
run_controller(
|
||||
config=AppConfig(max_iterations=3),
|
||||
config=OpenHandsConfig(max_iterations=3),
|
||||
initial_user_action=MessageAction(content='INITIAL'),
|
||||
runtime=mock_runtime,
|
||||
sid='test',
|
||||
@ -1063,7 +1063,7 @@ async def test_run_controller_with_context_window_exceeded_without_truncation(
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_run_controller_with_memory_error(test_event_stream, mock_agent):
|
||||
config = AppConfig()
|
||||
config = OpenHandsConfig()
|
||||
event_stream = test_event_stream
|
||||
|
||||
# Create a proper agent that returns an action without an ID
|
||||
@ -1330,7 +1330,7 @@ async def test_first_user_message_with_identical_content(test_event_stream, mock
|
||||
# Create an agent controller
|
||||
mock_agent.llm = MagicMock(spec=LLM)
|
||||
mock_agent.llm.metrics = Metrics()
|
||||
mock_agent.llm.config = AppConfig().get_llm_config()
|
||||
mock_agent.llm.config = OpenHandsConfig().get_llm_config()
|
||||
|
||||
controller = AgentController(
|
||||
agent=mock_agent,
|
||||
@ -1397,7 +1397,7 @@ async def test_agent_controller_processes_null_observation_with_cause():
|
||||
mock_agent = MagicMock(spec=Agent)
|
||||
mock_agent.llm = MagicMock(spec=LLM)
|
||||
mock_agent.llm.metrics = Metrics()
|
||||
mock_agent.llm.config = AppConfig().get_llm_config()
|
||||
mock_agent.llm.config = OpenHandsConfig().get_llm_config()
|
||||
|
||||
# Create a controller with the mock agent
|
||||
controller = AgentController(
|
||||
|
||||
@ -5,7 +5,7 @@ import pytest
|
||||
from openhands.controller.agent import Agent
|
||||
from openhands.controller.agent_controller import AgentController
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.events import EventSource
|
||||
from openhands.events.action import CmdRunAction, MessageAction, RecallAction
|
||||
from openhands.events.action.message import SystemMessageAction
|
||||
@ -90,8 +90,8 @@ def controller_fixture():
|
||||
mock_agent = MagicMock(spec=Agent)
|
||||
mock_agent.llm = MagicMock(spec=LLM)
|
||||
mock_agent.llm.metrics = Metrics()
|
||||
mock_agent.llm.config = AppConfig().get_llm_config()
|
||||
mock_agent.config = AppConfig().get_agent_config('CodeActAgent')
|
||||
mock_agent.llm.config = OpenHandsConfig().get_llm_config()
|
||||
mock_agent.config = OpenHandsConfig().get_agent_config('CodeActAgent')
|
||||
|
||||
mock_event_stream = MagicMock(spec=EventStream)
|
||||
mock_event_stream.sid = 'test_sid'
|
||||
|
||||
@ -5,7 +5,7 @@ import pytest
|
||||
from openhands.controller.agent import Agent
|
||||
from openhands.controller.agent_controller import AgentController
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import AppConfig, LLMConfig
|
||||
from openhands.core.config import LLMConfig, OpenHandsConfig
|
||||
from openhands.core.config.agent_config import AgentConfig
|
||||
from openhands.events import EventStream, EventStreamSubscriber
|
||||
from openhands.llm import LLM
|
||||
@ -110,7 +110,7 @@ async def test_agent_session_start_with_no_state(mock_agent):
|
||||
):
|
||||
await session.start(
|
||||
runtime_name='test-runtime',
|
||||
config=AppConfig(),
|
||||
config=OpenHandsConfig(),
|
||||
agent=mock_agent,
|
||||
max_iterations=10,
|
||||
)
|
||||
@ -203,7 +203,7 @@ async def test_agent_session_start_with_restored_state(mock_agent):
|
||||
):
|
||||
await session.start(
|
||||
runtime_name='test-runtime',
|
||||
config=AppConfig(),
|
||||
config=OpenHandsConfig(),
|
||||
agent=mock_agent,
|
||||
max_iterations=10,
|
||||
)
|
||||
|
||||
@ -5,8 +5,8 @@ from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config.llm_config import LLMConfig
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
from openhands.events.action import MessageAction
|
||||
from openhands.events.event import EventSource
|
||||
from openhands.events.stream import EventStream
|
||||
@ -207,7 +207,7 @@ async def test_update_conversation_with_title():
|
||||
# Create the conversation manager
|
||||
manager = StandaloneConversationManager(
|
||||
sio=sio,
|
||||
config=AppConfig(),
|
||||
config=OpenHandsConfig(),
|
||||
file_store=file_store,
|
||||
server_config=server_config,
|
||||
monitoring_listener=MonitoringListener(),
|
||||
|
||||
@ -13,7 +13,7 @@ from openhands.cli.commands import (
|
||||
handle_status_command,
|
||||
)
|
||||
from openhands.cli.tui import UsageMetrics
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.core.schema import AgentState
|
||||
from openhands.events import EventSource
|
||||
from openhands.events.action import ChangeAgentStateAction, MessageAction
|
||||
@ -27,7 +27,7 @@ class TestHandleCommands:
|
||||
event_stream = MagicMock(spec=EventStream)
|
||||
usage_metrics = MagicMock(spec=UsageMetrics)
|
||||
sid = 'test-session-id'
|
||||
config = MagicMock(spec=AppConfig)
|
||||
config = MagicMock(spec=OpenHandsConfig)
|
||||
current_dir = '/test/dir'
|
||||
settings_store = MagicMock(spec=FileSettingsStore)
|
||||
|
||||
@ -278,7 +278,7 @@ class TestHandleInitCommand:
|
||||
@pytest.mark.asyncio
|
||||
@patch('openhands.cli.commands.init_repository')
|
||||
async def test_init_local_runtime_successful(self, mock_init_repository):
|
||||
config = MagicMock(spec=AppConfig)
|
||||
config = MagicMock(spec=OpenHandsConfig)
|
||||
config.runtime = 'local'
|
||||
event_stream = MagicMock(spec=EventStream)
|
||||
current_dir = '/test/dir'
|
||||
@ -306,7 +306,7 @@ class TestHandleInitCommand:
|
||||
@pytest.mark.asyncio
|
||||
@patch('openhands.cli.commands.init_repository')
|
||||
async def test_init_local_runtime_unsuccessful(self, mock_init_repository):
|
||||
config = MagicMock(spec=AppConfig)
|
||||
config = MagicMock(spec=OpenHandsConfig)
|
||||
config.runtime = 'local'
|
||||
event_stream = MagicMock(spec=EventStream)
|
||||
current_dir = '/test/dir'
|
||||
@ -330,7 +330,7 @@ class TestHandleInitCommand:
|
||||
@patch('openhands.cli.commands.print_formatted_text')
|
||||
@patch('openhands.cli.commands.init_repository')
|
||||
async def test_init_non_local_runtime(self, mock_init_repository, mock_print):
|
||||
config = MagicMock(spec=AppConfig)
|
||||
config = MagicMock(spec=OpenHandsConfig)
|
||||
config.runtime = 'remote' # Not local
|
||||
event_stream = MagicMock(spec=EventStream)
|
||||
current_dir = '/test/dir'
|
||||
@ -360,7 +360,7 @@ class TestHandleSettingsCommand:
|
||||
mock_cli_confirm,
|
||||
mock_display_settings,
|
||||
):
|
||||
config = MagicMock(spec=AppConfig)
|
||||
config = MagicMock(spec=OpenHandsConfig)
|
||||
settings_store = MagicMock(spec=FileSettingsStore)
|
||||
|
||||
# Mock user selecting "Basic" settings
|
||||
@ -384,7 +384,7 @@ class TestHandleSettingsCommand:
|
||||
mock_cli_confirm,
|
||||
mock_display_settings,
|
||||
):
|
||||
config = MagicMock(spec=AppConfig)
|
||||
config = MagicMock(spec=OpenHandsConfig)
|
||||
settings_store = MagicMock(spec=FileSettingsStore)
|
||||
|
||||
# Mock user selecting "Basic" settings
|
||||
@ -408,7 +408,7 @@ class TestHandleSettingsCommand:
|
||||
mock_cli_confirm,
|
||||
mock_display_settings,
|
||||
):
|
||||
config = MagicMock(spec=AppConfig)
|
||||
config = MagicMock(spec=OpenHandsConfig)
|
||||
settings_store = MagicMock(spec=FileSettingsStore)
|
||||
|
||||
# Mock user selecting "Advanced" settings
|
||||
@ -432,7 +432,7 @@ class TestHandleSettingsCommand:
|
||||
mock_cli_confirm,
|
||||
mock_display_settings,
|
||||
):
|
||||
config = MagicMock(spec=AppConfig)
|
||||
config = MagicMock(spec=OpenHandsConfig)
|
||||
settings_store = MagicMock(spec=FileSettingsStore)
|
||||
|
||||
# Mock user selecting "Advanced" settings
|
||||
@ -450,7 +450,7 @@ class TestHandleSettingsCommand:
|
||||
@patch('openhands.cli.commands.display_settings')
|
||||
@patch('openhands.cli.commands.cli_confirm')
|
||||
async def test_settings_go_back(self, mock_cli_confirm, mock_display_settings):
|
||||
config = MagicMock(spec=AppConfig)
|
||||
config = MagicMock(spec=OpenHandsConfig)
|
||||
settings_store = MagicMock(spec=FileSettingsStore)
|
||||
|
||||
# Mock user selecting "Go back"
|
||||
|
||||
@ -10,7 +10,7 @@ from openhands.cli.settings import (
|
||||
modify_llm_settings_basic,
|
||||
)
|
||||
from openhands.cli.tui import UserCancelledError
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.storage.data_models.settings import Settings
|
||||
from openhands.storage.settings.file_settings_store import FileSettingsStore
|
||||
|
||||
@ -30,7 +30,7 @@ class MockNoOpCondenserConfig:
|
||||
class TestDisplaySettings:
|
||||
@pytest.fixture
|
||||
def app_config(self):
|
||||
config = MagicMock(spec=AppConfig)
|
||||
config = MagicMock(spec=OpenHandsConfig)
|
||||
llm_config = MagicMock()
|
||||
llm_config.base_url = None
|
||||
llm_config.model = 'openai/gpt-4'
|
||||
@ -48,7 +48,7 @@ class TestDisplaySettings:
|
||||
|
||||
@pytest.fixture
|
||||
def advanced_app_config(self):
|
||||
config = MagicMock(spec=AppConfig)
|
||||
config = MagicMock(spec=OpenHandsConfig)
|
||||
llm_config = MagicMock()
|
||||
llm_config.base_url = 'https://custom-api.com'
|
||||
llm_config.model = 'custom-model'
|
||||
@ -114,7 +114,7 @@ class TestDisplaySettings:
|
||||
class TestModifyLLMSettingsBasic:
|
||||
@pytest.fixture
|
||||
def app_config(self):
|
||||
config = MagicMock(spec=AppConfig)
|
||||
config = MagicMock(spec=OpenHandsConfig)
|
||||
llm_config = MagicMock()
|
||||
llm_config.model = 'openai/gpt-4'
|
||||
llm_config.api_key = SecretStr('test-api-key')
|
||||
@ -313,7 +313,7 @@ class TestModifyLLMSettingsBasic:
|
||||
class TestModifyLLMSettingsAdvanced:
|
||||
@pytest.fixture
|
||||
def app_config(self):
|
||||
config = MagicMock(spec=AppConfig)
|
||||
config = MagicMock(spec=OpenHandsConfig)
|
||||
llm_config = MagicMock()
|
||||
llm_config.model = 'custom-model'
|
||||
llm_config.api_key = SecretStr('test-api-key')
|
||||
|
||||
@ -18,7 +18,7 @@ from openhands.cli.tui import (
|
||||
get_session_duration,
|
||||
read_confirmation_input,
|
||||
)
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.events import EventSource
|
||||
from openhands.events.action import (
|
||||
Action,
|
||||
@ -74,7 +74,7 @@ class TestDisplayFunctions:
|
||||
|
||||
@patch('openhands.cli.tui.display_message')
|
||||
def test_display_event_message_action(self, mock_display_message):
|
||||
config = MagicMock(spec=AppConfig)
|
||||
config = MagicMock(spec=OpenHandsConfig)
|
||||
message = MessageAction(content='Test message')
|
||||
message._source = EventSource.AGENT
|
||||
|
||||
@ -84,7 +84,7 @@ class TestDisplayFunctions:
|
||||
|
||||
@patch('openhands.cli.tui.display_command')
|
||||
def test_display_event_cmd_action(self, mock_display_command):
|
||||
config = MagicMock(spec=AppConfig)
|
||||
config = MagicMock(spec=OpenHandsConfig)
|
||||
cmd_action = CmdRunAction(command='echo test')
|
||||
|
||||
display_event(cmd_action, config)
|
||||
@ -93,7 +93,7 @@ class TestDisplayFunctions:
|
||||
|
||||
@patch('openhands.cli.tui.display_command_output')
|
||||
def test_display_event_cmd_output(self, mock_display_output):
|
||||
config = MagicMock(spec=AppConfig)
|
||||
config = MagicMock(spec=OpenHandsConfig)
|
||||
cmd_output = CmdOutputObservation(content='Test output', command='echo test')
|
||||
|
||||
display_event(cmd_output, config)
|
||||
@ -102,7 +102,7 @@ class TestDisplayFunctions:
|
||||
|
||||
@patch('openhands.cli.tui.display_file_edit')
|
||||
def test_display_event_file_edit_observation(self, mock_display_file_edit):
|
||||
config = MagicMock(spec=AppConfig)
|
||||
config = MagicMock(spec=OpenHandsConfig)
|
||||
file_edit_obs = FileEditObservation(path='test.py', content="print('hello')")
|
||||
|
||||
display_event(file_edit_obs, config)
|
||||
@ -111,7 +111,7 @@ class TestDisplayFunctions:
|
||||
|
||||
@patch('openhands.cli.tui.display_file_read')
|
||||
def test_display_event_file_read(self, mock_display_file_read):
|
||||
config = MagicMock(spec=AppConfig)
|
||||
config = MagicMock(spec=OpenHandsConfig)
|
||||
file_read = FileReadObservation(path='test.py', content="print('hello')")
|
||||
|
||||
display_event(file_read, config)
|
||||
@ -120,7 +120,7 @@ class TestDisplayFunctions:
|
||||
|
||||
@patch('openhands.cli.tui.display_message')
|
||||
def test_display_event_thought(self, mock_display_message):
|
||||
config = MagicMock(spec=AppConfig)
|
||||
config = MagicMock(spec=OpenHandsConfig)
|
||||
action = Action()
|
||||
action.thought = 'Thinking about this...'
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ import tempfile
|
||||
|
||||
import pytest
|
||||
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.core.exceptions import LLMMalformedActionError
|
||||
from openhands.events import EventStream
|
||||
from openhands.runtime.impl.cli.cli_runtime import CLIRuntime
|
||||
@ -24,7 +24,7 @@ def cli_runtime(temp_dir):
|
||||
"""Create a CLIRuntime instance for testing."""
|
||||
file_store = get_file_store('local', temp_dir)
|
||||
event_stream = EventStream('test', file_store)
|
||||
config = AppConfig()
|
||||
config = OpenHandsConfig()
|
||||
config.workspace_base = temp_dir
|
||||
runtime = CLIRuntime(config, event_stream)
|
||||
runtime._runtime_initialized = True # Skip initialization
|
||||
|
||||
@ -6,14 +6,14 @@ import pytest
|
||||
|
||||
from openhands.core.config import (
|
||||
AgentConfig,
|
||||
AppConfig,
|
||||
LLMConfig,
|
||||
OpenHandsConfig,
|
||||
finalize_config,
|
||||
get_agent_config_arg,
|
||||
get_llm_config_arg,
|
||||
load_app_config,
|
||||
load_from_env,
|
||||
load_from_toml,
|
||||
load_openhands_config,
|
||||
)
|
||||
from openhands.core.config.condenser_config import (
|
||||
LLMSummarizingCondenserConfig,
|
||||
@ -48,8 +48,8 @@ def temp_toml_file(tmp_path):
|
||||
|
||||
@pytest.fixture
|
||||
def default_config(monkeypatch):
|
||||
# Fixture to provide a default AppConfig instance
|
||||
yield AppConfig()
|
||||
# Fixture to provide a default OpenHandsConfig instance
|
||||
yield OpenHandsConfig()
|
||||
|
||||
|
||||
def test_compat_env_to_config(monkeypatch, setup_env):
|
||||
@ -60,7 +60,7 @@ def test_compat_env_to_config(monkeypatch, setup_env):
|
||||
monkeypatch.setenv('DEFAULT_AGENT', 'CodeActAgent')
|
||||
monkeypatch.setenv('SANDBOX_TIMEOUT', '10')
|
||||
|
||||
config = AppConfig()
|
||||
config = OpenHandsConfig()
|
||||
load_from_env(config, os.environ)
|
||||
finalize_config(config)
|
||||
|
||||
@ -413,7 +413,7 @@ def test_defaults_dict_after_updates(default_config):
|
||||
assert initial_defaults['workspace_mount_path']['default'] is None
|
||||
assert initial_defaults['default_agent']['default'] == 'CodeActAgent'
|
||||
|
||||
updated_config = AppConfig()
|
||||
updated_config = OpenHandsConfig()
|
||||
updated_config.get_llm_config().api_key = 'updated-api-key'
|
||||
updated_config.get_llm_config('llm').api_key = 'updated-api-key'
|
||||
updated_config.get_llm_config_from_agent('agent').api_key = 'updated-api-key'
|
||||
@ -678,7 +678,7 @@ def test_sandbox_volumes_with_workspace_not_first(default_config):
|
||||
|
||||
def test_agent_config_condenser_with_no_enabled():
|
||||
"""Test default agent condenser with enable_default_condenser=False."""
|
||||
config = AppConfig(enable_default_condenser=False)
|
||||
config = OpenHandsConfig(enable_default_condenser=False)
|
||||
agent_config = config.get_agent_config()
|
||||
assert isinstance(agent_config.condenser, NoOpCondenserConfig)
|
||||
|
||||
@ -986,8 +986,8 @@ def test_api_keys_repr_str():
|
||||
f"Unexpected attribute '{attr_name}' contains 'token' in AgentConfig"
|
||||
)
|
||||
|
||||
# Test AppConfig
|
||||
app_config = AppConfig(
|
||||
# Test OpenHandsConfig
|
||||
app_config = OpenHandsConfig(
|
||||
llms={'llm': llm_config},
|
||||
agents={'agent': agent_config},
|
||||
e2b_api_key='my_e2b_api_key',
|
||||
@ -1010,7 +1010,7 @@ def test_api_keys_repr_str():
|
||||
assert 'my_daytona_api_key' not in repr(app_config)
|
||||
assert 'my_daytona_api_key' not in str(app_config)
|
||||
|
||||
# Check that no other attrs in AppConfig have 'key' or 'token' in their name
|
||||
# Check that no other attrs in OpenHandsConfig have 'key' or 'token' in their name
|
||||
# This will fail when new attrs are added, and attract attention
|
||||
known_key_token_attrs_app = [
|
||||
'e2b_api_key',
|
||||
@ -1020,16 +1020,16 @@ def test_api_keys_repr_str():
|
||||
'daytona_api_key',
|
||||
'search_api_key',
|
||||
]
|
||||
for attr_name in AppConfig.model_fields.keys():
|
||||
for attr_name in OpenHandsConfig.model_fields.keys():
|
||||
if (
|
||||
not attr_name.startswith('__')
|
||||
and attr_name not in known_key_token_attrs_app
|
||||
):
|
||||
assert 'key' not in attr_name.lower(), (
|
||||
f"Unexpected attribute '{attr_name}' contains 'key' in AppConfig"
|
||||
f"Unexpected attribute '{attr_name}' contains 'key' in OpenHandsConfig"
|
||||
)
|
||||
assert 'token' not in attr_name.lower() or 'tokens' in attr_name.lower(), (
|
||||
f"Unexpected attribute '{attr_name}' contains 'token' in AppConfig"
|
||||
f"Unexpected attribute '{attr_name}' contains 'token' in OpenHandsConfig"
|
||||
)
|
||||
|
||||
|
||||
@ -1040,7 +1040,7 @@ max_iterations = 42
|
||||
max_budget_per_task = 4.7
|
||||
"""
|
||||
|
||||
config = AppConfig()
|
||||
config = OpenHandsConfig()
|
||||
with open(temp_toml_file, 'w') as f:
|
||||
f.write(temp_toml)
|
||||
|
||||
@ -1138,7 +1138,7 @@ enable_prompt_extensions = false
|
||||
f.write(temp_toml)
|
||||
|
||||
# just a sanity check that load app config wouldn't fail
|
||||
app_config = load_app_config(config_file=temp_toml_file)
|
||||
app_config = load_openhands_config(config_file=temp_toml_file)
|
||||
assert app_config.max_iterations == 99
|
||||
|
||||
# run_infer in evaluation can use `get_agent_config_arg` to load custom
|
||||
|
||||
@ -2,7 +2,7 @@ import os
|
||||
|
||||
import pytest
|
||||
|
||||
from openhands.core.config import AppConfig, load_from_env
|
||||
from openhands.core.config import OpenHandsConfig, load_from_env
|
||||
|
||||
|
||||
def test_load_from_env_with_dict(monkeypatch, default_config):
|
||||
@ -35,5 +35,5 @@ def test_load_from_env_with_dict(monkeypatch, default_config):
|
||||
|
||||
@pytest.fixture
|
||||
def default_config():
|
||||
# Fixture to provide a default AppConfig instance
|
||||
yield AppConfig()
|
||||
# Fixture to provide a default OpenHandsConfig instance
|
||||
yield OpenHandsConfig()
|
||||
|
||||
@ -2,8 +2,8 @@ import os
|
||||
|
||||
import pytest
|
||||
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config.extended_config import ExtendedConfig
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
from openhands.core.config.utils import load_from_toml
|
||||
|
||||
|
||||
@ -83,7 +83,7 @@ def test_extended_config_invalid_key():
|
||||
def test_app_config_extended_from_toml(tmp_path: os.PathLike) -> None:
|
||||
"""Test that the [extended] section in a TOML file is correctly loaded.
|
||||
|
||||
This test verifies that the [extended] section is loaded into AppConfig.extended
|
||||
This test verifies that the [extended] section is loaded into OpenHandsConfig.extended
|
||||
and that it accepts arbitrary keys.
|
||||
"""
|
||||
# Create a temporary TOML file with multiple sections including [extended]
|
||||
@ -106,8 +106,8 @@ enable_prompt_extensions = true
|
||||
config_file = tmp_path / 'config.toml'
|
||||
config_file.write_text(config_content)
|
||||
|
||||
# Load the TOML into the AppConfig instance
|
||||
config = AppConfig()
|
||||
# Load the TOML into the OpenHandsConfig instance
|
||||
config = OpenHandsConfig()
|
||||
load_from_toml(config, str(config_file))
|
||||
|
||||
# Verify that extended section is applied
|
||||
@ -121,7 +121,7 @@ def test_app_config_extended_default(tmp_path: os.PathLike) -> None:
|
||||
"""Test default behavior when no [extended] section exists.
|
||||
|
||||
This test verifies that if there is no [extended] section in the TOML file,
|
||||
AppConfig.extended remains its default (empty) ExtendedConfig.
|
||||
OpenHandsConfig.extended remains its default (empty) ExtendedConfig.
|
||||
"""
|
||||
config_content = """
|
||||
[core]
|
||||
@ -137,7 +137,7 @@ enable_prompt_extensions = true
|
||||
config_file = tmp_path / 'config.toml'
|
||||
config_file.write_text(config_content)
|
||||
|
||||
config = AppConfig()
|
||||
config = OpenHandsConfig()
|
||||
load_from_toml(config, str(config_file))
|
||||
|
||||
# Extended config should be empty
|
||||
@ -161,7 +161,7 @@ another_key = 3.14
|
||||
config_file = tmp_path / 'config.toml'
|
||||
config_file.write_text(config_content)
|
||||
|
||||
config = AppConfig()
|
||||
config = OpenHandsConfig()
|
||||
load_from_toml(config, str(config_file))
|
||||
|
||||
# Verify that extended config holds the arbitrary keys with correct values.
|
||||
|
||||
@ -46,7 +46,7 @@ def _patch_store():
|
||||
get_conversation_metadata_filename('some_conversation_id'),
|
||||
json.dumps(
|
||||
{
|
||||
'title': 'Some Conversation',
|
||||
'title': 'Some ServerConversation',
|
||||
'selected_repository': 'foobar',
|
||||
'conversation_id': 'some_conversation_id',
|
||||
'user_id': '12345',
|
||||
@ -140,7 +140,7 @@ async def test_search_conversations():
|
||||
results=[
|
||||
ConversationMetadata(
|
||||
conversation_id='some_conversation_id',
|
||||
title='Some Conversation',
|
||||
title='Some ServerConversation',
|
||||
created_at=datetime.fromisoformat(
|
||||
'2025-01-01T00:00:00+00:00'
|
||||
),
|
||||
@ -164,7 +164,7 @@ async def test_search_conversations():
|
||||
results=[
|
||||
ConversationInfo(
|
||||
conversation_id='some_conversation_id',
|
||||
title='Some Conversation',
|
||||
title='Some ServerConversation',
|
||||
created_at=datetime.fromisoformat(
|
||||
'2025-01-01T00:00:00+00:00'
|
||||
),
|
||||
@ -189,7 +189,7 @@ async def test_get_conversation():
|
||||
mock_store.get_metadata = AsyncMock(
|
||||
return_value=ConversationMetadata(
|
||||
conversation_id='some_conversation_id',
|
||||
title='Some Conversation',
|
||||
title='Some ServerConversation',
|
||||
created_at=datetime.fromisoformat('2025-01-01T00:00:00+00:00'),
|
||||
last_updated_at=datetime.fromisoformat('2025-01-01T00:01:00+00:00'),
|
||||
selected_repository='foobar',
|
||||
@ -211,7 +211,7 @@ async def test_get_conversation():
|
||||
|
||||
expected = ConversationInfo(
|
||||
conversation_id='some_conversation_id',
|
||||
title='Some Conversation',
|
||||
title='Some ServerConversation',
|
||||
created_at=datetime.fromisoformat('2025-01-01T00:00:00+00:00'),
|
||||
last_updated_at=datetime.fromisoformat('2025-01-01T00:01:00+00:00'),
|
||||
status=ConversationStatus.STOPPED,
|
||||
@ -418,7 +418,7 @@ async def test_delete_conversation():
|
||||
mock_store.get_metadata = AsyncMock(
|
||||
return_value=ConversationMetadata(
|
||||
conversation_id='some_conversation_id',
|
||||
title='Some Conversation',
|
||||
title='Some ServerConversation',
|
||||
created_at=datetime.fromisoformat('2025-01-01T00:00:00+00:00'),
|
||||
last_updated_at=datetime.fromisoformat('2025-01-01T00:01:00+00:00'),
|
||||
selected_repository='foobar',
|
||||
|
||||
@ -2,7 +2,7 @@ from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from openhands.core.config import AppConfig
|
||||
from openhands.core.config import OpenHandsConfig
|
||||
from openhands.events import EventStream
|
||||
from openhands.runtime.impl.docker.docker_runtime import DockerRuntime
|
||||
|
||||
@ -30,7 +30,7 @@ def mock_docker_client():
|
||||
|
||||
@pytest.fixture
|
||||
def config():
|
||||
config = AppConfig()
|
||||
config = OpenHandsConfig()
|
||||
config.sandbox.keep_runtime_alive = False
|
||||
return config
|
||||
|
||||
|
||||
@ -108,7 +108,7 @@ async def test_search_pagination():
|
||||
'conversation_id': f'conv{i}',
|
||||
'user_id': '123',
|
||||
'selected_repository': 'repo1',
|
||||
'title': f'Conversation {i}',
|
||||
'title': f'ServerConversation {i}',
|
||||
'created_at': f'2025-01-{15 + i}T19:51:04Z',
|
||||
}
|
||||
)
|
||||
|
||||
@ -2,7 +2,7 @@ from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from openhands.core.config.app_config import AppConfig
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
from openhands.storage.data_models.settings import Settings
|
||||
from openhands.storage.files import FileStore
|
||||
from openhands.storage.settings.file_settings_store import FileSettingsStore
|
||||
@ -21,8 +21,8 @@ def file_settings_store(mock_file_store):
|
||||
@pytest.mark.asyncio
|
||||
async def test_load_nonexistent_data(file_settings_store):
|
||||
with patch(
|
||||
'openhands.storage.data_models.settings.load_app_config',
|
||||
MagicMock(return_value=AppConfig()),
|
||||
'openhands.storage.data_models.settings.load_openhands_config',
|
||||
MagicMock(return_value=OpenHandsConfig()),
|
||||
):
|
||||
file_settings_store.file_store.read.side_effect = FileNotFoundError()
|
||||
assert await file_settings_store.load() is None
|
||||
@ -74,7 +74,7 @@ async def test_store_and_load_data(file_settings_store):
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_instance():
|
||||
config = AppConfig(file_store='local', file_store_path='/test/path')
|
||||
config = OpenHandsConfig(file_store='local', file_store_path='/test/path')
|
||||
|
||||
with patch(
|
||||
'openhands.storage.settings.file_settings_store.get_file_store'
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user