mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-10-07 15:48:00 +08:00
chore: bump SDK packages to v1.31.2 (#15156)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
co-authored by
github-actions[bot]
openhands
parent
ef3323afd9
commit
cc80397ecd
@@ -57,8 +57,8 @@ repos:
|
||||
types-Markdown,
|
||||
pydantic,
|
||||
lxml,
|
||||
"openhands-sdk==1.31.1",
|
||||
"openhands-tools==1.31.1",
|
||||
"openhands-sdk==1.31.2",
|
||||
"openhands-tools==1.31.2",
|
||||
"sqlalchemy>=2.0",
|
||||
]
|
||||
# To see gaps add `--html-report mypy-report/`
|
||||
|
||||
@@ -50,8 +50,8 @@ repos:
|
||||
- ./
|
||||
- stripe==11.5.0
|
||||
- pygithub==2.6.1
|
||||
- openhands-sdk==1.25.0
|
||||
- openhands-tools==1.25.0
|
||||
- openhands-sdk==1.31.2
|
||||
- openhands-tools==1.31.2
|
||||
- sqlalchemy>=2.0
|
||||
# Use -p (package) to avoid dual module name conflict when using MYPYPATH
|
||||
# MYPYPATH=enterprise allows resolving bare imports like "from integrations.xxx"
|
||||
|
||||
Generated
+13
-13
@@ -5776,14 +5776,14 @@ numpy = {version = ">=2", markers = "python_version >= \"3.9\""}
|
||||
|
||||
[[package]]
|
||||
name = "openhands-agent-server"
|
||||
version = "1.31.1"
|
||||
version = "1.31.2"
|
||||
description = "OpenHands Agent Server - REST/WebSocket interface for OpenHands AI Agent"
|
||||
optional = false
|
||||
python-versions = ">=3.12"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "openhands_agent_server-1.31.1-py3-none-any.whl", hash = "sha256:baf654114bbd128b92753015c378c250c0017c15f4a72d02f3a5020776d71afb"},
|
||||
{file = "openhands_agent_server-1.31.1.tar.gz", hash = "sha256:ec066cdaf5edc35d23a5fc5b1d883cb91e40a23fc7c231cb6280f8480b6c5a50"},
|
||||
{file = "openhands_agent_server-1.31.2-py3-none-any.whl", hash = "sha256:df954eeabc973f99dcd18f2f679de074588333eb1e76bc85f4e5c143a88d52c6"},
|
||||
{file = "openhands_agent_server-1.31.2.tar.gz", hash = "sha256:ad787420c1da0f8b32f1a5714e66f923a8f22d83e7bebaa1e52eb43996fa7eab"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -5801,7 +5801,7 @@ wsproto = ">=1.2.0"
|
||||
|
||||
[[package]]
|
||||
name = "openhands-ai"
|
||||
version = "1.8.0"
|
||||
version = "1.9.0"
|
||||
description = "OpenHands: Code Less, Make More"
|
||||
optional = false
|
||||
python-versions = "^3.12,<3.14"
|
||||
@@ -5847,9 +5847,9 @@ mcp = ">=1.25"
|
||||
memory-profiler = "0.61.0"
|
||||
numpy = "2.4.4"
|
||||
openai = "2.33.0"
|
||||
openhands-agent-server = "1.31.1"
|
||||
openhands-sdk = "1.31.1"
|
||||
openhands-tools = "1.31.1"
|
||||
openhands-agent-server = "1.31.2"
|
||||
openhands-sdk = "1.31.2"
|
||||
openhands-tools = "1.31.2"
|
||||
opentelemetry-api = "1.39.1"
|
||||
opentelemetry-exporter-otlp-proto-grpc = "1.39.1"
|
||||
orjson = "3.11.8"
|
||||
@@ -5902,14 +5902,14 @@ url = ".."
|
||||
|
||||
[[package]]
|
||||
name = "openhands-sdk"
|
||||
version = "1.31.1"
|
||||
version = "1.31.2"
|
||||
description = "OpenHands SDK - Core functionality for building AI agents"
|
||||
optional = false
|
||||
python-versions = ">=3.12"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "openhands_sdk-1.31.1-py3-none-any.whl", hash = "sha256:f86cda194fdf741a5c3cf2430b69e9bb1791976ea12c9d802f23e1c82683f9ef"},
|
||||
{file = "openhands_sdk-1.31.1.tar.gz", hash = "sha256:76845899ab0b7fc59e340f376dc1608ca4d5737f96ac9a9e8833122ff22787aa"},
|
||||
{file = "openhands_sdk-1.31.2-py3-none-any.whl", hash = "sha256:598f33d3d1d41e6f8da82a5028dd311475d4830887fbbb02a8558476b1ff5013"},
|
||||
{file = "openhands_sdk-1.31.2.tar.gz", hash = "sha256:722940940a9ccac0bedb778f0f799bb0e1f83f9b4d6d41fa4deb40db3f8bf646"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -5937,14 +5937,14 @@ vertex = ["google-cloud-aiplatform (>=1.38)"]
|
||||
|
||||
[[package]]
|
||||
name = "openhands-tools"
|
||||
version = "1.31.1"
|
||||
version = "1.31.2"
|
||||
description = "OpenHands Tools - Runtime tools for AI agents"
|
||||
optional = false
|
||||
python-versions = ">=3.12"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "openhands_tools-1.31.1-py3-none-any.whl", hash = "sha256:7514e3bcf30417f02ea3bf685e5e94c5f60bc957f244f86cfc006a2f8168d6ec"},
|
||||
{file = "openhands_tools-1.31.1.tar.gz", hash = "sha256:e36997ac423e3f4bf8bf6d44b200ae599afee6098fdc0531e58a42c37ca1455f"},
|
||||
{file = "openhands_tools-1.31.2-py3-none-any.whl", hash = "sha256:9cda8bc475aa53ba54b862e839b5265d71569acbe00e402aefc7251d0e2fc2f0"},
|
||||
{file = "openhands_tools-1.31.2.tar.gz", hash = "sha256:53950b5f465ad5e733d1c3e4bf007cb2b06176121a992aa2c361c4a8955e9885"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
||||
@@ -169,10 +169,7 @@ def test_migrated_payload_loads_via_user_settings_to_settings():
|
||||
assert settings.agent_settings.condenser.enabled is False
|
||||
assert settings.agent_settings.condenser.max_size == 128
|
||||
assert settings.agent_settings.mcp_config is not None
|
||||
assert (
|
||||
settings.agent_settings.mcp_config.mcpServers['admin'].url
|
||||
== 'https://mcp.example.com'
|
||||
)
|
||||
assert settings.agent_settings.mcp_config['admin'].url == 'https://mcp.example.com'
|
||||
assert settings.conversation_settings.max_iterations == 42
|
||||
assert settings.conversation_settings.confirmation_mode is True
|
||||
assert settings.conversation_settings.security_analyzer == 'llm'
|
||||
|
||||
@@ -726,6 +726,13 @@ async def test_store_keeps_mcp_config_private_to_acting_member(
|
||||
'user1': {'url': 'https://user1-mcp-server.com', 'transport': 'sse'}
|
||||
},
|
||||
}
|
||||
# The SDK 1.31.x wire format stores ``mcp_config`` as a flat server
|
||||
# map; ``Settings.update`` still accepts the legacy wrapper for
|
||||
# backwards compatibility, but ``model_dump(mode='json')`` — which is
|
||||
# what ``_get_persisted_agent_settings`` uses — no longer wraps.
|
||||
persisted_mcp_config = {
|
||||
'user1': {'url': 'https://user1-mcp-server.com', 'transport': 'sse'},
|
||||
}
|
||||
new_settings = DataSettings()
|
||||
new_settings.update(
|
||||
{
|
||||
@@ -760,7 +767,8 @@ async def test_store_keeps_mcp_config_private_to_acting_member(
|
||||
|
||||
assert 'mcp_config' not in org.agent_settings
|
||||
assert (
|
||||
members[admin_user_id].agent_settings_diff.get('mcp_config') == user_mcp_config
|
||||
members[admin_user_id].agent_settings_diff.get('mcp_config')
|
||||
== persisted_mcp_config
|
||||
)
|
||||
assert 'mcp_config' not in members[member1_user_id].agent_settings_diff
|
||||
assert 'mcp_config' not in members[member2_user_id].agent_settings_diff
|
||||
@@ -885,7 +893,7 @@ async def test_store_and_load_mcp_config_via_agent_settings(
|
||||
assert loaded is not None
|
||||
assert loaded.agent_settings.mcp_config is not None
|
||||
assert (
|
||||
loaded.agent_settings.mcp_config.mcpServers['admin'].url
|
||||
loaded.agent_settings.mcp_config['admin'].url
|
||||
== 'https://admin-private-server.com'
|
||||
)
|
||||
|
||||
@@ -941,7 +949,9 @@ async def test_load_drops_legacy_org_level_mcp_config(
|
||||
|
||||
# Assert — legacy org mcp_config is not inherited by member1
|
||||
assert loaded is not None
|
||||
assert loaded.agent_settings.mcp_config is None
|
||||
# The SDK normalizes ``None`` to ``{}`` so the absence of an MCP config
|
||||
# surfaces as an empty server map rather than ``None``.
|
||||
assert loaded.agent_settings.mcp_config == {}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -1277,11 +1287,10 @@ async def test_store_replaces_mcp_config_on_delete(
|
||||
.all()
|
||||
}
|
||||
|
||||
admin_servers = (
|
||||
members[admin_user_id]
|
||||
.agent_settings_diff.get('mcp_config', {})
|
||||
.get('mcpServers', {})
|
||||
)
|
||||
# The persisted ``mcp_config`` is the SDK 1.31.x flat server map (no
|
||||
# ``mcpServers`` wrapper), so reach directly into it instead of going
|
||||
# through the legacy wrapper key.
|
||||
admin_servers = members[admin_user_id].agent_settings_diff.get('mcp_config', {})
|
||||
assert set(admin_servers.keys()) == {'server1', 'server2'}
|
||||
assert 'mcp_config' not in members[member1_user_id].agent_settings_diff
|
||||
|
||||
|
||||
@@ -1299,17 +1299,19 @@ class LiveStatusAppConversationService(AppConversationServiceBase):
|
||||
return
|
||||
|
||||
sdk_mcp = user.agent_settings.mcp_config
|
||||
if not sdk_mcp or not sdk_mcp.mcpServers:
|
||||
if not sdk_mcp:
|
||||
return
|
||||
|
||||
try:
|
||||
count = len(sdk_mcp.mcpServers)
|
||||
count = len(sdk_mcp)
|
||||
_logger.info(
|
||||
f'Loading custom MCP config from user settings: {count} servers'
|
||||
)
|
||||
|
||||
for name, server in sdk_mcp.mcpServers.items():
|
||||
mcp_servers[name] = server.model_dump(exclude_none=True)
|
||||
for name, server in sdk_mcp.items():
|
||||
mcp_servers[name] = server.model_dump(
|
||||
exclude_none=True, context={'expose_secrets': 'plaintext'}
|
||||
)
|
||||
|
||||
_logger.info(
|
||||
f'Successfully merged custom MCP config: added {count} servers'
|
||||
@@ -1731,13 +1733,11 @@ class LiveStatusAppConversationService(AppConversationServiceBase):
|
||||
agent_definitions = list(get_registered_agent_definitions())
|
||||
|
||||
# --- build AgentSettings and create agent ---------------------------
|
||||
from fastmcp.mcp_config import MCPConfig
|
||||
|
||||
configured_agent_settings = user.agent_settings.model_copy(
|
||||
update={
|
||||
'llm': llm,
|
||||
'tools': tools,
|
||||
'mcp_config': MCPConfig(**mcp_config) if mcp_config else None,
|
||||
'mcp_config': mcp_config if mcp_config else {},
|
||||
'agent_context': AgentContext(
|
||||
system_message_suffix=effective_suffix,
|
||||
secrets=secrets,
|
||||
|
||||
@@ -14,7 +14,7 @@ from openhands.sdk.utils.models import DiscriminatedUnionMixin
|
||||
|
||||
# The version of the agent server to use for deployments.
|
||||
# Typically this will be the same as the values from the pyproject.toml
|
||||
AGENT_SERVER_IMAGE = 'ghcr.io/openhands/agent-server:1.31.1-python'
|
||||
AGENT_SERVER_IMAGE = 'ghcr.io/openhands/agent-server:1.31.2-python'
|
||||
|
||||
|
||||
class SandboxSpecService(ABC):
|
||||
|
||||
Generated
+10
-10
@@ -5520,14 +5520,14 @@ pydantic = ">=1.8"
|
||||
|
||||
[[package]]
|
||||
name = "openhands-agent-server"
|
||||
version = "1.31.1"
|
||||
version = "1.31.2"
|
||||
description = "OpenHands Agent Server - REST/WebSocket interface for OpenHands AI Agent"
|
||||
optional = false
|
||||
python-versions = ">=3.12"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "openhands_agent_server-1.31.1-py3-none-any.whl", hash = "sha256:baf654114bbd128b92753015c378c250c0017c15f4a72d02f3a5020776d71afb"},
|
||||
{file = "openhands_agent_server-1.31.1.tar.gz", hash = "sha256:ec066cdaf5edc35d23a5fc5b1d883cb91e40a23fc7c231cb6280f8480b6c5a50"},
|
||||
{file = "openhands_agent_server-1.31.2-py3-none-any.whl", hash = "sha256:df954eeabc973f99dcd18f2f679de074588333eb1e76bc85f4e5c143a88d52c6"},
|
||||
{file = "openhands_agent_server-1.31.2.tar.gz", hash = "sha256:ad787420c1da0f8b32f1a5714e66f923a8f22d83e7bebaa1e52eb43996fa7eab"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -5545,14 +5545,14 @@ wsproto = ">=1.2.0"
|
||||
|
||||
[[package]]
|
||||
name = "openhands-sdk"
|
||||
version = "1.31.1"
|
||||
version = "1.31.2"
|
||||
description = "OpenHands SDK - Core functionality for building AI agents"
|
||||
optional = false
|
||||
python-versions = ">=3.12"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "openhands_sdk-1.31.1-py3-none-any.whl", hash = "sha256:f86cda194fdf741a5c3cf2430b69e9bb1791976ea12c9d802f23e1c82683f9ef"},
|
||||
{file = "openhands_sdk-1.31.1.tar.gz", hash = "sha256:76845899ab0b7fc59e340f376dc1608ca4d5737f96ac9a9e8833122ff22787aa"},
|
||||
{file = "openhands_sdk-1.31.2-py3-none-any.whl", hash = "sha256:598f33d3d1d41e6f8da82a5028dd311475d4830887fbbb02a8558476b1ff5013"},
|
||||
{file = "openhands_sdk-1.31.2.tar.gz", hash = "sha256:722940940a9ccac0bedb778f0f799bb0e1f83f9b4d6d41fa4deb40db3f8bf646"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -5580,14 +5580,14 @@ vertex = ["google-cloud-aiplatform (>=1.38)"]
|
||||
|
||||
[[package]]
|
||||
name = "openhands-tools"
|
||||
version = "1.31.1"
|
||||
version = "1.31.2"
|
||||
description = "OpenHands Tools - Runtime tools for AI agents"
|
||||
optional = false
|
||||
python-versions = ">=3.12"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "openhands_tools-1.31.1-py3-none-any.whl", hash = "sha256:7514e3bcf30417f02ea3bf685e5e94c5f60bc957f244f86cfc006a2f8168d6ec"},
|
||||
{file = "openhands_tools-1.31.1.tar.gz", hash = "sha256:e36997ac423e3f4bf8bf6d44b200ae599afee6098fdc0531e58a42c37ca1455f"},
|
||||
{file = "openhands_tools-1.31.2-py3-none-any.whl", hash = "sha256:9cda8bc475aa53ba54b862e839b5265d71569acbe00e402aefc7251d0e2fc2f0"},
|
||||
{file = "openhands_tools-1.31.2.tar.gz", hash = "sha256:53950b5f465ad5e733d1c3e4bf007cb2b06176121a992aa2c361c4a8955e9885"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -13763,4 +13763,4 @@ cffi = ["cffi (>=1.17,<2.0) ; platform_python_implementation != \"PyPy\" and pyt
|
||||
[metadata]
|
||||
lock-version = "2.1"
|
||||
python-versions = "^3.12,<3.14"
|
||||
content-hash = "bc9735a9d4ad3f5705884f528cdda9f2d48659acf31016e87b108920269d1741"
|
||||
content-hash = "cad64b376b764decdf4f400fb93bda8852c90f0b7d0c0fe5c807167ae0f8aeeb"
|
||||
|
||||
+6
-6
@@ -58,9 +58,9 @@ dependencies = [
|
||||
"memory-profiler==0.61.0",
|
||||
"numpy==2.4.4",
|
||||
"openai==2.33.0",
|
||||
"openhands-agent-server==1.31.1",
|
||||
"openhands-sdk==1.31.1",
|
||||
"openhands-tools==1.31.1",
|
||||
"openhands-agent-server==1.31.2",
|
||||
"openhands-sdk==1.31.2",
|
||||
"openhands-tools==1.31.2",
|
||||
"opentelemetry-api==1.39.1",
|
||||
"opentelemetry-exporter-otlp-proto-grpc==1.39.1",
|
||||
"orjson==3.11.8",
|
||||
@@ -248,9 +248,9 @@ e2b-code-interpreter = { version = "^2.0.0", optional = true }
|
||||
pybase62 = "1.0.0"
|
||||
|
||||
# V1 dependencies
|
||||
openhands-sdk = "==1.31.1"
|
||||
openhands-agent-server = "==1.31.1"
|
||||
openhands-tools = "==1.31.1"
|
||||
openhands-sdk = "==1.31.2"
|
||||
openhands-agent-server = "==1.31.2"
|
||||
openhands-tools = "==1.31.2"
|
||||
joserfc = ">=1.0.0"
|
||||
sqlalchemy = { extras = [ "asyncio" ], version = "^2.0.40" }
|
||||
pg8000 = "1.31.5"
|
||||
|
||||
@@ -102,7 +102,7 @@ def test_replace_mcp_config_in_kind_switch():
|
||||
|
||||
s.update(_set_openhands(mcp_config={'mcpServers': {'foo': {'command': 'foo-bin'}}}))
|
||||
assert s.agent_settings.mcp_config is not None
|
||||
assert 'foo' in s.agent_settings.mcp_config.mcpServers
|
||||
assert 'foo' in s.agent_settings.mcp_config
|
||||
|
||||
|
||||
def test_loader_normalizes_legacy_llm_tag_at_current_schema_version():
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import pytest
|
||||
from fastmcp.mcp_config import MCPConfig, RemoteMCPServer
|
||||
|
||||
from openhands.app_server.settings.file_settings_store import FileSettingsStore
|
||||
from openhands.app_server.settings.settings_models import Settings
|
||||
@@ -18,13 +17,12 @@ async def test_user_auth_returns_stored_settings():
|
||||
stored_settings = Settings(
|
||||
agent_settings=OpenHandsAgentSettings(
|
||||
llm=LLM(model='anthropic/claude-sonnet-4-5-20250929'),
|
||||
mcp_config=MCPConfig(
|
||||
mcpServers={
|
||||
'frontend': RemoteMCPServer(
|
||||
url='http://frontend-server.com', transport='sse'
|
||||
)
|
||||
mcp_config={
|
||||
'frontend': {
|
||||
'url': 'http://frontend-server.com',
|
||||
'transport': 'sse',
|
||||
}
|
||||
),
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
@@ -42,8 +40,8 @@ async def test_user_auth_returns_stored_settings():
|
||||
assert settings.agent_settings.llm.model == 'anthropic/claude-sonnet-4-5-20250929'
|
||||
mcp = settings.agent_settings.mcp_config
|
||||
assert mcp is not None
|
||||
assert len(mcp.mcpServers) == 1
|
||||
assert 'frontend' in mcp.mcpServers
|
||||
assert len(mcp) == 1
|
||||
assert 'frontend' in mcp
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -52,13 +50,12 @@ async def test_user_auth_caching_behavior():
|
||||
stored_settings = Settings(
|
||||
agent_settings=OpenHandsAgentSettings(
|
||||
llm=LLM(model='anthropic/claude-sonnet-4-5-20250929'),
|
||||
mcp_config=MCPConfig(
|
||||
mcpServers={
|
||||
'frontend': RemoteMCPServer(
|
||||
url='http://frontend-server.com', transport='sse'
|
||||
)
|
||||
mcp_config={
|
||||
'frontend': {
|
||||
'url': 'http://frontend-server.com',
|
||||
'transport': 'sse',
|
||||
}
|
||||
),
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ import warnings
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from fastmcp.mcp_config import MCPConfig
|
||||
from pydantic import SecretStr, ValidationError
|
||||
|
||||
import openhands.app_server.settings.settings_models as settings_module
|
||||
@@ -148,26 +147,23 @@ def test_settings_agent_settings_keeps_sdk_mcp_shape_canonical():
|
||||
settings = Settings(
|
||||
agent_settings=OpenHandsAgentSettings(
|
||||
llm=LLM(model='sdk-model'),
|
||||
mcp_config=MCPConfig(
|
||||
mcpServers={
|
||||
'sse_server': {
|
||||
'url': 'https://example.com/sse',
|
||||
'transport': 'sse',
|
||||
}
|
||||
},
|
||||
),
|
||||
mcp_config={
|
||||
'sse_server': {
|
||||
'url': 'https://example.com/sse',
|
||||
'transport': 'sse',
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
mcp_config = settings.agent_settings.mcp_config
|
||||
assert mcp_config is not None
|
||||
servers = mcp_config.mcpServers
|
||||
assert 'sse_server' in servers
|
||||
assert servers['sse_server'].transport == 'sse'
|
||||
assert servers['sse_server'].url == 'https://example.com/sse'
|
||||
assert 'sse_server' in mcp_config
|
||||
assert mcp_config['sse_server'].transport == 'sse'
|
||||
assert mcp_config['sse_server'].url == 'https://example.com/sse'
|
||||
|
||||
api_values = settings.agent_settings.model_dump(mode='json')
|
||||
assert 'sse_server' in api_values['mcp_config']['mcpServers']
|
||||
assert 'sse_server' in api_values['mcp_config']
|
||||
|
||||
|
||||
def test_settings_update_mcp_config():
|
||||
@@ -192,23 +188,21 @@ def test_settings_update_mcp_config():
|
||||
|
||||
mcp = settings.agent_settings.mcp_config
|
||||
assert mcp is not None
|
||||
assert 'custom' in mcp.mcpServers
|
||||
assert mcp.mcpServers['custom'].transport == 'http'
|
||||
assert mcp.mcpServers['custom'].url == 'https://example.com/mcp'
|
||||
assert 'custom' in mcp
|
||||
assert mcp['custom'].transport == 'http'
|
||||
assert mcp['custom'].url == 'https://example.com/mcp'
|
||||
|
||||
|
||||
def test_settings_update_replaces_existing_mcp_servers():
|
||||
settings = Settings(
|
||||
agent_settings=OpenHandsAgentSettings(
|
||||
llm=LLM(model='sdk-model'),
|
||||
mcp_config=MCPConfig(
|
||||
mcpServers={
|
||||
'stale': {
|
||||
'transport': 'sse',
|
||||
'url': 'https://example.com/stale',
|
||||
}
|
||||
mcp_config={
|
||||
'stale': {
|
||||
'transport': 'sse',
|
||||
'url': 'https://example.com/stale',
|
||||
}
|
||||
),
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
@@ -229,28 +223,28 @@ def test_settings_update_replaces_existing_mcp_servers():
|
||||
|
||||
mcp = settings.agent_settings.mcp_config
|
||||
assert mcp is not None
|
||||
assert set(mcp.mcpServers) == {'fresh'}
|
||||
assert mcp.mcpServers['fresh'].url == 'https://example.com/fresh'
|
||||
assert set(mcp) == {'fresh'}
|
||||
assert mcp['fresh'].url == 'https://example.com/fresh'
|
||||
|
||||
|
||||
def test_settings_update_can_clear_mcp_config():
|
||||
settings = Settings(
|
||||
agent_settings=OpenHandsAgentSettings(
|
||||
llm=LLM(model='sdk-model'),
|
||||
mcp_config=MCPConfig(
|
||||
mcpServers={
|
||||
'custom': {
|
||||
'transport': 'http',
|
||||
'url': 'https://example.com/mcp',
|
||||
}
|
||||
mcp_config={
|
||||
'custom': {
|
||||
'transport': 'http',
|
||||
'url': 'https://example.com/mcp',
|
||||
}
|
||||
),
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
settings.update({'agent_settings_diff': {'mcp_config': None}})
|
||||
|
||||
assert settings.agent_settings.mcp_config is None
|
||||
# The SDK normalizes ``None`` to ``{}`` so cleared configs round-trip as an
|
||||
# empty server map rather than ``None``.
|
||||
assert settings.agent_settings.mcp_config == {}
|
||||
|
||||
|
||||
def test_settings_update_batch():
|
||||
@@ -328,14 +322,12 @@ def test_switch_to_profile_preserves_other_agent_settings():
|
||||
verification=VerificationSettings(
|
||||
critic_enabled=True, critic_mode='all_actions'
|
||||
),
|
||||
mcp_config=MCPConfig(
|
||||
mcpServers={
|
||||
's': {
|
||||
'transport': 'http',
|
||||
'url': 'https://example.com/mcp',
|
||||
}
|
||||
mcp_config={
|
||||
's': {
|
||||
'transport': 'http',
|
||||
'url': 'https://example.com/mcp',
|
||||
}
|
||||
),
|
||||
},
|
||||
),
|
||||
)
|
||||
settings.llm_profiles.save('p', LLM(model='anthropic/claude-opus-4'))
|
||||
@@ -346,7 +338,7 @@ def test_switch_to_profile_preserves_other_agent_settings():
|
||||
assert settings.agent_settings.condenser.max_size == 321
|
||||
assert settings.agent_settings.verification.critic_mode == 'all_actions'
|
||||
assert settings.agent_settings.mcp_config is not None
|
||||
assert 's' in settings.agent_settings.mcp_config.mcpServers
|
||||
assert 's' in settings.agent_settings.mcp_config
|
||||
|
||||
|
||||
def test_delete_active_profile_promotes_remaining_one():
|
||||
|
||||
@@ -3169,7 +3169,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "openhands-agent-server"
|
||||
version = "1.31.1"
|
||||
version = "1.31.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "aiosqlite" },
|
||||
@@ -3184,9 +3184,9 @@ dependencies = [
|
||||
{ name = "websockets" },
|
||||
{ name = "wsproto" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/64/85/76849e5881cf2af9d43be35ef158cbd9a6cdc38b1985ad2eee1d84a48631/openhands_agent_server-1.31.1.tar.gz", hash = "sha256:ec066cdaf5edc35d23a5fc5b1d883cb91e40a23fc7c231cb6280f8480b6c5a50", size = 188958, upload-time = "2026-07-05T20:05:18.571Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/88/d7/4b7359c13259ea16d1123908ada51eb26057519ce5cbdfada34918d5173d/openhands_agent_server-1.31.2.tar.gz", hash = "sha256:ad787420c1da0f8b32f1a5714e66f923a8f22d83e7bebaa1e52eb43996fa7eab", size = 194950, upload-time = "2026-07-07T03:50:02.354Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/90/0c/f475bad22c3808fbea42ee45957ccf2c352b2bd6ef7a55a34d89b330c55c/openhands_agent_server-1.31.1-py3-none-any.whl", hash = "sha256:baf654114bbd128b92753015c378c250c0017c15f4a72d02f3a5020776d71afb", size = 216371, upload-time = "2026-07-05T20:05:13.912Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/51/63/85328c7e1566d1e9f2eabd15b2cd7ea673a96d57ca386df0259824c0cd5f/openhands_agent_server-1.31.2-py3-none-any.whl", hash = "sha256:df954eeabc973f99dcd18f2f679de074588333eb1e76bc85f4e5c143a88d52c6", size = 223053, upload-time = "2026-07-07T03:49:57Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3347,9 +3347,9 @@ requires-dist = [
|
||||
{ name = "memory-profiler", specifier = "==0.61.0" },
|
||||
{ name = "numpy", specifier = "==2.4.4" },
|
||||
{ name = "openai", specifier = "==2.33.0" },
|
||||
{ name = "openhands-agent-server", specifier = "==1.31.1" },
|
||||
{ name = "openhands-sdk", specifier = "==1.31.1" },
|
||||
{ name = "openhands-tools", specifier = "==1.31.1" },
|
||||
{ name = "openhands-agent-server", specifier = "==1.31.2" },
|
||||
{ name = "openhands-sdk", specifier = "==1.31.2" },
|
||||
{ name = "openhands-tools", specifier = "==1.31.2" },
|
||||
{ name = "opentelemetry-api", specifier = "==1.39.1" },
|
||||
{ name = "opentelemetry-exporter-otlp-proto-grpc", specifier = "==1.39.1" },
|
||||
{ name = "orjson", specifier = "==3.11.8" },
|
||||
@@ -3427,7 +3427,7 @@ test = [
|
||||
|
||||
[[package]]
|
||||
name = "openhands-sdk"
|
||||
version = "1.31.1"
|
||||
version = "1.31.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "agent-client-protocol" },
|
||||
@@ -3448,14 +3448,14 @@ dependencies = [
|
||||
{ name = "tree-sitter-bash" },
|
||||
{ name = "websockets" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d5/e6/abd31fdd08fe4c61bb899ae7f351175ef19e4da0c49cc745e586e27556fb/openhands_sdk-1.31.1.tar.gz", hash = "sha256:76845899ab0b7fc59e340f376dc1608ca4d5737f96ac9a9e8833122ff22787aa", size = 599131, upload-time = "2026-07-05T20:05:19.433Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d5/94/4acddd54f9eb6347ea57412ec55c93d0a89f8e6635660cc75c8ef6e4c518/openhands_sdk-1.31.2.tar.gz", hash = "sha256:722940940a9ccac0bedb778f0f799bb0e1f83f9b4d6d41fa4deb40db3f8bf646", size = 604293, upload-time = "2026-07-07T03:50:03.299Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/00/fe/2cb2d48a7230281f63d83b526f4cacb0fe85e5ee2f44864661550dac38fd/openhands_sdk-1.31.1-py3-none-any.whl", hash = "sha256:f86cda194fdf741a5c3cf2430b69e9bb1791976ea12c9d802f23e1c82683f9ef", size = 720301, upload-time = "2026-07-05T20:05:15.129Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/75/ff69d1db866f80627cf9ef5f5ef9be4bb8f140a0660b44c08d37ae88f571/openhands_sdk-1.31.2-py3-none-any.whl", hash = "sha256:598f33d3d1d41e6f8da82a5028dd311475d4830887fbbb02a8558476b1ff5013", size = 726174, upload-time = "2026-07-07T03:49:58.431Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openhands-tools"
|
||||
version = "1.31.1"
|
||||
version = "1.31.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "binaryornot" },
|
||||
@@ -3469,9 +3469,9 @@ dependencies = [
|
||||
{ name = "tree-sitter" },
|
||||
{ name = "tree-sitter-bash" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c1/c0/e1b2f523cb9163b9252e74e78957ecb8683351ddf127934e9a3802214b19/openhands_tools-1.31.1.tar.gz", hash = "sha256:e36997ac423e3f4bf8bf6d44b200ae599afee6098fdc0531e58a42c37ca1455f", size = 145901, upload-time = "2026-07-05T20:05:20.723Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/20/ec/a206f7005967bdc6ae2c757c84aa71bf41f801445341915c0845154e3af2/openhands_tools-1.31.2.tar.gz", hash = "sha256:53950b5f465ad5e733d1c3e4bf007cb2b06176121a992aa2c361c4a8955e9885", size = 145922, upload-time = "2026-07-07T03:50:04.279Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/36/2e/62918f223c6325b03b7e895828f7534a5d8eb64516db0824885647fa3033/openhands_tools-1.31.1-py3-none-any.whl", hash = "sha256:7514e3bcf30417f02ea3bf685e5e94c5f60bc957f244f86cfc006a2f8168d6ec", size = 191220, upload-time = "2026-07-05T20:05:16.514Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/10/355d63a497c6106154fb52a9a8787ae7b59dc1d1a5e65171df438cdf1059/openhands_tools-1.31.2-py3-none-any.whl", hash = "sha256:9cda8bc475aa53ba54b862e839b5265d71569acbe00e402aefc7251d0e2fc2f0", size = 191219, upload-time = "2026-07-07T03:49:59.72Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
Reference in New Issue
Block a user