agentscope-runtime 0.2.0b1__py3-none-any.whl → 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agentscope_runtime/adapters/__init__.py +0 -0
- agentscope_runtime/adapters/agentscope/__init__.py +0 -0
- agentscope_runtime/adapters/agentscope/long_term_memory/__init__.py +6 -0
- agentscope_runtime/adapters/agentscope/long_term_memory/_long_term_memory_adapter.py +258 -0
- agentscope_runtime/adapters/agentscope/memory/__init__.py +6 -0
- agentscope_runtime/adapters/agentscope/memory/_memory_adapter.py +152 -0
- agentscope_runtime/adapters/agentscope/message.py +535 -0
- agentscope_runtime/adapters/agentscope/stream.py +506 -0
- agentscope_runtime/adapters/agentscope/tool/__init__.py +9 -0
- agentscope_runtime/adapters/agentscope/tool/sandbox_tool.py +69 -0
- agentscope_runtime/adapters/agentscope/tool/tool.py +233 -0
- agentscope_runtime/adapters/autogen/__init__.py +0 -0
- agentscope_runtime/adapters/autogen/tool/__init__.py +7 -0
- agentscope_runtime/adapters/autogen/tool/tool.py +211 -0
- agentscope_runtime/adapters/text/__init__.py +0 -0
- agentscope_runtime/adapters/text/stream.py +29 -0
- agentscope_runtime/common/collections/redis_mapping.py +4 -1
- agentscope_runtime/common/container_clients/fc_client.py +855 -0
- agentscope_runtime/common/container_clients/kubernetes_client.py +6 -13
- agentscope_runtime/common/utils/__init__.py +0 -0
- agentscope_runtime/common/utils/lazy_loader.py +57 -0
- agentscope_runtime/engine/__init__.py +25 -18
- agentscope_runtime/engine/app/agent_app.py +161 -91
- agentscope_runtime/engine/app/base_app.py +4 -118
- agentscope_runtime/engine/constant.py +8 -0
- agentscope_runtime/engine/deployers/__init__.py +8 -0
- agentscope_runtime/engine/deployers/adapter/__init__.py +2 -0
- agentscope_runtime/engine/deployers/adapter/a2a/a2a_adapter_utils.py +0 -21
- agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +28 -9
- agentscope_runtime/engine/deployers/adapter/responses/__init__.py +2 -0
- agentscope_runtime/engine/deployers/adapter/responses/response_api_adapter_utils.py +5 -2
- agentscope_runtime/engine/deployers/adapter/responses/response_api_protocol_adapter.py +1 -1
- agentscope_runtime/engine/deployers/agentrun_deployer.py +2541 -0
- agentscope_runtime/engine/deployers/cli_fc_deploy.py +1 -1
- agentscope_runtime/engine/deployers/kubernetes_deployer.py +9 -21
- agentscope_runtime/engine/deployers/local_deployer.py +47 -74
- agentscope_runtime/engine/deployers/modelstudio_deployer.py +216 -50
- agentscope_runtime/engine/deployers/utils/app_runner_utils.py +29 -0
- agentscope_runtime/engine/deployers/utils/detached_app.py +510 -0
- agentscope_runtime/engine/deployers/utils/docker_image_utils/__init__.py +1 -1
- agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +1 -1
- agentscope_runtime/engine/deployers/utils/docker_image_utils/{runner_image_factory.py → image_factory.py} +121 -61
- agentscope_runtime/engine/deployers/utils/package.py +693 -0
- agentscope_runtime/engine/deployers/utils/service_utils/__init__.py +0 -5
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +301 -282
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_templates.py +2 -4
- agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +23 -1
- agentscope_runtime/engine/deployers/utils/templates/app_main.py.j2 +84 -0
- agentscope_runtime/engine/deployers/utils/templates/runner_main.py.j2 +95 -0
- agentscope_runtime/engine/deployers/utils/{service_utils → templates}/standalone_main.py.j2 +0 -45
- agentscope_runtime/engine/deployers/utils/wheel_packager.py +119 -18
- agentscope_runtime/engine/helpers/runner.py +40 -0
- agentscope_runtime/engine/runner.py +171 -130
- agentscope_runtime/engine/schemas/agent_schemas.py +114 -3
- agentscope_runtime/engine/schemas/modelstudio_llm.py +4 -2
- agentscope_runtime/engine/schemas/oai_llm.py +23 -23
- agentscope_runtime/engine/schemas/response_api.py +65 -0
- agentscope_runtime/engine/schemas/session.py +24 -0
- agentscope_runtime/engine/services/__init__.py +0 -9
- agentscope_runtime/engine/services/agent_state/__init__.py +16 -0
- agentscope_runtime/engine/services/agent_state/redis_state_service.py +113 -0
- agentscope_runtime/engine/services/agent_state/state_service.py +179 -0
- agentscope_runtime/engine/services/memory/__init__.py +24 -0
- agentscope_runtime/engine/services/{mem0_memory_service.py → memory/mem0_memory_service.py} +17 -13
- agentscope_runtime/engine/services/{memory_service.py → memory/memory_service.py} +28 -7
- agentscope_runtime/engine/services/{redis_memory_service.py → memory/redis_memory_service.py} +1 -1
- agentscope_runtime/engine/services/{reme_personal_memory_service.py → memory/reme_personal_memory_service.py} +9 -6
- agentscope_runtime/engine/services/{reme_task_memory_service.py → memory/reme_task_memory_service.py} +2 -2
- agentscope_runtime/engine/services/{tablestore_memory_service.py → memory/tablestore_memory_service.py} +16 -19
- agentscope_runtime/engine/services/sandbox/__init__.py +13 -0
- agentscope_runtime/engine/services/{sandbox_service.py → sandbox/sandbox_service.py} +86 -71
- agentscope_runtime/engine/services/session_history/__init__.py +23 -0
- agentscope_runtime/engine/services/{redis_session_history_service.py → session_history/redis_session_history_service.py} +3 -2
- agentscope_runtime/engine/services/{session_history_service.py → session_history/session_history_service.py} +44 -34
- agentscope_runtime/engine/services/{tablestore_session_history_service.py → session_history/tablestore_session_history_service.py} +14 -19
- agentscope_runtime/engine/services/utils/tablestore_service_utils.py +2 -2
- agentscope_runtime/engine/tracing/base.py +10 -9
- agentscope_runtime/engine/tracing/message_util.py +1 -1
- agentscope_runtime/engine/tracing/tracing_util.py +7 -2
- agentscope_runtime/engine/tracing/wrapper.py +49 -31
- agentscope_runtime/sandbox/__init__.py +10 -2
- agentscope_runtime/sandbox/box/agentbay/__init__.py +4 -0
- agentscope_runtime/sandbox/box/agentbay/agentbay_sandbox.py +559 -0
- agentscope_runtime/sandbox/box/base/base_sandbox.py +12 -0
- agentscope_runtime/sandbox/box/browser/browser_sandbox.py +115 -11
- agentscope_runtime/sandbox/box/cloud/__init__.py +4 -0
- agentscope_runtime/sandbox/box/cloud/cloud_sandbox.py +254 -0
- agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +66 -0
- agentscope_runtime/sandbox/box/gui/gui_sandbox.py +42 -0
- agentscope_runtime/sandbox/box/mobile/__init__.py +4 -0
- agentscope_runtime/sandbox/box/mobile/box/__init__.py +0 -0
- agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +216 -0
- agentscope_runtime/sandbox/box/training_box/training_box.py +2 -44
- agentscope_runtime/sandbox/client/http_client.py +1 -0
- agentscope_runtime/sandbox/enums.py +2 -1
- agentscope_runtime/sandbox/manager/sandbox_manager.py +15 -2
- agentscope_runtime/sandbox/manager/server/app.py +12 -0
- agentscope_runtime/sandbox/manager/server/config.py +19 -0
- agentscope_runtime/sandbox/model/manager_config.py +79 -2
- agentscope_runtime/sandbox/utils.py +0 -18
- agentscope_runtime/tools/RAGs/__init__.py +0 -0
- agentscope_runtime/tools/RAGs/modelstudio_rag.py +377 -0
- agentscope_runtime/tools/RAGs/modelstudio_rag_lite.py +219 -0
- agentscope_runtime/tools/__init__.py +119 -0
- agentscope_runtime/tools/_constants.py +18 -0
- agentscope_runtime/tools/alipay/__init__.py +4 -0
- agentscope_runtime/tools/alipay/base.py +334 -0
- agentscope_runtime/tools/alipay/payment.py +835 -0
- agentscope_runtime/tools/alipay/subscribe.py +551 -0
- agentscope_runtime/tools/base.py +264 -0
- agentscope_runtime/tools/cli/__init__.py +0 -0
- agentscope_runtime/tools/cli/modelstudio_mcp_server.py +78 -0
- agentscope_runtime/tools/generations/__init__.py +75 -0
- agentscope_runtime/tools/generations/async_image_to_video.py +350 -0
- agentscope_runtime/tools/generations/async_image_to_video_wan25.py +366 -0
- agentscope_runtime/tools/generations/async_speech_to_video.py +422 -0
- agentscope_runtime/tools/generations/async_text_to_video.py +320 -0
- agentscope_runtime/tools/generations/async_text_to_video_wan25.py +334 -0
- agentscope_runtime/tools/generations/image_edit.py +208 -0
- agentscope_runtime/tools/generations/image_edit_wan25.py +193 -0
- agentscope_runtime/tools/generations/image_generation.py +202 -0
- agentscope_runtime/tools/generations/image_generation_wan25.py +201 -0
- agentscope_runtime/tools/generations/image_style_repaint.py +208 -0
- agentscope_runtime/tools/generations/image_to_video.py +233 -0
- agentscope_runtime/tools/generations/qwen_image_edit.py +205 -0
- agentscope_runtime/tools/generations/qwen_image_generation.py +214 -0
- agentscope_runtime/tools/generations/qwen_text_to_speech.py +154 -0
- agentscope_runtime/tools/generations/speech_to_text.py +260 -0
- agentscope_runtime/tools/generations/speech_to_video.py +314 -0
- agentscope_runtime/tools/generations/text_to_video.py +221 -0
- agentscope_runtime/tools/mcp_wrapper.py +215 -0
- agentscope_runtime/tools/realtime_clients/__init__.py +13 -0
- agentscope_runtime/tools/realtime_clients/asr_client.py +27 -0
- agentscope_runtime/tools/realtime_clients/azure_asr_client.py +195 -0
- agentscope_runtime/tools/realtime_clients/azure_tts_client.py +383 -0
- agentscope_runtime/tools/realtime_clients/modelstudio_asr_client.py +151 -0
- agentscope_runtime/tools/realtime_clients/modelstudio_tts_client.py +199 -0
- agentscope_runtime/tools/realtime_clients/realtime_tool.py +55 -0
- agentscope_runtime/tools/realtime_clients/tts_client.py +33 -0
- agentscope_runtime/tools/searches/__init__.py +3 -0
- agentscope_runtime/tools/searches/modelstudio_search.py +877 -0
- agentscope_runtime/tools/searches/modelstudio_search_lite.py +310 -0
- agentscope_runtime/tools/utils/__init__.py +0 -0
- agentscope_runtime/tools/utils/api_key_util.py +45 -0
- agentscope_runtime/tools/utils/crypto_utils.py +99 -0
- agentscope_runtime/tools/utils/mcp_util.py +35 -0
- agentscope_runtime/version.py +1 -1
- {agentscope_runtime-0.2.0b1.dist-info → agentscope_runtime-1.0.0.dist-info}/METADATA +244 -168
- agentscope_runtime-1.0.0.dist-info/RECORD +240 -0
- {agentscope_runtime-0.2.0b1.dist-info → agentscope_runtime-1.0.0.dist-info}/entry_points.txt +1 -0
- agentscope_runtime/engine/agents/__init__.py +0 -2
- agentscope_runtime/engine/agents/agentscope_agent.py +0 -488
- agentscope_runtime/engine/agents/agno_agent.py +0 -222
- agentscope_runtime/engine/agents/autogen_agent.py +0 -250
- agentscope_runtime/engine/agents/base_agent.py +0 -29
- agentscope_runtime/engine/agents/langgraph_agent.py +0 -59
- agentscope_runtime/engine/agents/utils.py +0 -53
- agentscope_runtime/engine/deployers/utils/package_project_utils.py +0 -1163
- agentscope_runtime/engine/deployers/utils/service_utils/service_config.py +0 -75
- agentscope_runtime/engine/deployers/utils/service_utils/service_factory.py +0 -220
- agentscope_runtime/engine/helpers/helper.py +0 -179
- agentscope_runtime/engine/schemas/context.py +0 -54
- agentscope_runtime/engine/services/context_manager.py +0 -164
- agentscope_runtime/engine/services/environment_manager.py +0 -50
- agentscope_runtime/engine/services/manager.py +0 -174
- agentscope_runtime/engine/services/rag_service.py +0 -195
- agentscope_runtime/engine/services/tablestore_rag_service.py +0 -143
- agentscope_runtime/sandbox/tools/__init__.py +0 -12
- agentscope_runtime/sandbox/tools/base/__init__.py +0 -8
- agentscope_runtime/sandbox/tools/base/tool.py +0 -52
- agentscope_runtime/sandbox/tools/browser/__init__.py +0 -57
- agentscope_runtime/sandbox/tools/browser/tool.py +0 -597
- agentscope_runtime/sandbox/tools/filesystem/__init__.py +0 -32
- agentscope_runtime/sandbox/tools/filesystem/tool.py +0 -319
- agentscope_runtime/sandbox/tools/function_tool.py +0 -321
- agentscope_runtime/sandbox/tools/gui/__init__.py +0 -7
- agentscope_runtime/sandbox/tools/gui/tool.py +0 -77
- agentscope_runtime/sandbox/tools/mcp_tool.py +0 -195
- agentscope_runtime/sandbox/tools/sandbox_tool.py +0 -104
- agentscope_runtime/sandbox/tools/tool.py +0 -238
- agentscope_runtime/sandbox/tools/utils.py +0 -68
- agentscope_runtime-0.2.0b1.dist-info/RECORD +0 -183
- {agentscope_runtime-0.2.0b1.dist-info → agentscope_runtime-1.0.0.dist-info}/WHEEL +0 -0
- {agentscope_runtime-0.2.0b1.dist-info → agentscope_runtime-1.0.0.dist-info}/licenses/LICENSE +0 -0
- {agentscope_runtime-0.2.0b1.dist-info → agentscope_runtime-1.0.0.dist-info}/top_level.txt +0 -0
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
# pylint: disable=too-many-branches,
|
|
3
|
-
# pylint: disable=too-many-statements
|
|
4
|
-
|
|
5
|
-
import hashlib
|
|
6
|
-
import logging
|
|
2
|
+
# pylint: disable=too-many-branches,too-many-statements
|
|
7
3
|
import time
|
|
4
|
+
import hashlib
|
|
8
5
|
import traceback
|
|
6
|
+
import logging
|
|
7
|
+
|
|
9
8
|
from typing import Optional, Tuple
|
|
10
9
|
|
|
11
10
|
from kubernetes import client
|
|
@@ -16,14 +15,12 @@ from .base_client import BaseClient
|
|
|
16
15
|
|
|
17
16
|
logger = logging.getLogger(__name__)
|
|
18
17
|
|
|
19
|
-
DEFAULT_IMAGE_REGISTRY = "agentscope-registry.ap-southeast-1.cr.aliyuncs.com"
|
|
20
|
-
|
|
21
18
|
|
|
22
19
|
class KubernetesClient(BaseClient):
|
|
23
20
|
def __init__(
|
|
24
21
|
self,
|
|
25
22
|
config=None,
|
|
26
|
-
image_registry: Optional[str] =
|
|
23
|
+
image_registry: Optional[str] = None,
|
|
27
24
|
):
|
|
28
25
|
self.config = config
|
|
29
26
|
namespace = self.config.k8s_namespace
|
|
@@ -157,11 +154,7 @@ class KubernetesClient(BaseClient):
|
|
|
157
154
|
container_name = name or "main-container"
|
|
158
155
|
|
|
159
156
|
# Container specification
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if not self.image_registry:
|
|
163
|
-
image = image
|
|
164
|
-
else:
|
|
157
|
+
if self.image_registry:
|
|
165
158
|
image = f"{self.image_registry}/{image}"
|
|
166
159
|
|
|
167
160
|
container = client.V1Container(
|
|
File without changes
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import importlib
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def install_lazy_loader(globals_dict, lazy_map):
|
|
6
|
+
"""
|
|
7
|
+
Install __getattr__ and __all__ for lazy loading of module members.
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
globals_dict: The globals() of the current module.
|
|
11
|
+
Pass the globals() from the module where this is called.
|
|
12
|
+
lazy_map: dict[name, module_path]
|
|
13
|
+
OR dict[name, dict(module=..., hint=...)]
|
|
14
|
+
The hint is an optional message for missing dependencies.
|
|
15
|
+
"""
|
|
16
|
+
__all__ = list(lazy_map.keys())
|
|
17
|
+
|
|
18
|
+
def __getattr__(name):
|
|
19
|
+
if name in lazy_map:
|
|
20
|
+
entry = lazy_map[name]
|
|
21
|
+
module_path, hint = None, None
|
|
22
|
+
|
|
23
|
+
# Support two configuration formats
|
|
24
|
+
if isinstance(entry, str):
|
|
25
|
+
module_path = entry
|
|
26
|
+
elif isinstance(entry, dict):
|
|
27
|
+
module_path = entry["module"]
|
|
28
|
+
hint = entry.get("hint")
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
module = importlib.import_module(
|
|
32
|
+
module_path,
|
|
33
|
+
globals_dict["__name__"],
|
|
34
|
+
)
|
|
35
|
+
except ImportError as e:
|
|
36
|
+
msg = f"Failed to import {name}. Possible missing dependency."
|
|
37
|
+
if hint:
|
|
38
|
+
msg += f" Please install dependency: {hint}"
|
|
39
|
+
else:
|
|
40
|
+
msg += (
|
|
41
|
+
" Please install dependency: pip install "
|
|
42
|
+
"agentscope-runtime[ext]"
|
|
43
|
+
)
|
|
44
|
+
raise ImportError(msg) from e
|
|
45
|
+
|
|
46
|
+
obj = getattr(module, name)
|
|
47
|
+
# Cache in globals to avoid reloading
|
|
48
|
+
globals_dict[name] = obj
|
|
49
|
+
return obj
|
|
50
|
+
|
|
51
|
+
raise AttributeError(
|
|
52
|
+
f"module {globals_dict['__name__']} has no attribute {name}",
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# Modify the globals of the calling module
|
|
56
|
+
globals_dict["__all__"] = __all__
|
|
57
|
+
globals_dict["__getattr__"] = __getattr__
|
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
MemoryService,
|
|
6
|
-
SessionHistoryService,
|
|
7
|
-
)
|
|
8
|
-
from .deployers import DeployManager, LocalDeployManager
|
|
9
|
-
from .runner import Runner
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
10
5
|
from .app import AgentApp
|
|
6
|
+
from .runner import Runner
|
|
7
|
+
from ..common.utils.lazy_loader import install_lazy_loader
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from .deployers import (
|
|
11
|
+
DeployManager,
|
|
12
|
+
LocalDeployManager,
|
|
13
|
+
KubernetesDeployManager,
|
|
14
|
+
ModelstudioDeployManager,
|
|
15
|
+
AgentRunDeployManager,
|
|
16
|
+
)
|
|
11
17
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
|
|
19
|
+
install_lazy_loader(
|
|
20
|
+
globals(),
|
|
21
|
+
{
|
|
22
|
+
"DeployManager": ".deployers",
|
|
23
|
+
"LocalDeployManager": ".deployers",
|
|
24
|
+
"KubernetesDeployManager": ".deployers",
|
|
25
|
+
"ModelstudioDeployManager": ".deployers",
|
|
26
|
+
"AgentRunDeployManager": ".deployers",
|
|
27
|
+
},
|
|
28
|
+
)
|
|
@@ -1,28 +1,23 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
import asyncio
|
|
3
2
|
import logging
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import types
|
|
4
|
+
import subprocess
|
|
5
|
+
import shlex
|
|
6
|
+
from typing import Optional, Callable, List
|
|
6
7
|
|
|
7
8
|
import uvicorn
|
|
8
|
-
from fastapi import FastAPI
|
|
9
9
|
from pydantic import BaseModel
|
|
10
10
|
|
|
11
11
|
from .base_app import BaseApp
|
|
12
|
-
from ..
|
|
12
|
+
from ..deployers import DeployManager
|
|
13
13
|
from ..deployers.adapter.a2a import A2AFastAPIDefaultAdapter
|
|
14
14
|
from ..deployers.adapter.responses.response_api_protocol_adapter import (
|
|
15
15
|
ResponseAPIDefaultAdapter,
|
|
16
16
|
)
|
|
17
17
|
from ..deployers.utils.deployment_modes import DeploymentMode
|
|
18
18
|
from ..deployers.utils.service_utils.fastapi_factory import FastAPIAppFactory
|
|
19
|
-
from ..deployers.utils.service_utils.service_config import (
|
|
20
|
-
DEFAULT_SERVICES_CONFIG,
|
|
21
|
-
)
|
|
22
19
|
from ..runner import Runner
|
|
23
20
|
from ..schemas.agent_schemas import AgentRequest
|
|
24
|
-
from ..services.context_manager import ContextManager
|
|
25
|
-
from ..services.environment_manager import EnvironmentManager
|
|
26
21
|
from ...version import __version__
|
|
27
22
|
|
|
28
23
|
logger = logging.getLogger(__name__)
|
|
@@ -36,9 +31,8 @@ class AgentApp(BaseApp):
|
|
|
36
31
|
def __init__(
|
|
37
32
|
self,
|
|
38
33
|
*,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
context_manager: Optional[ContextManager] = None,
|
|
34
|
+
app_name: str = "",
|
|
35
|
+
app_description: str = "",
|
|
42
36
|
endpoint_path: str = "/process",
|
|
43
37
|
response_type: str = "sse",
|
|
44
38
|
stream: bool = True,
|
|
@@ -47,6 +41,8 @@ class AgentApp(BaseApp):
|
|
|
47
41
|
after_finish: Optional[Callable] = None,
|
|
48
42
|
broker_url: Optional[str] = None,
|
|
49
43
|
backend_url: Optional[str] = None,
|
|
44
|
+
runner: Optional[Runner] = None,
|
|
45
|
+
enable_embedded_worker: bool = False,
|
|
50
46
|
**kwargs,
|
|
51
47
|
):
|
|
52
48
|
"""
|
|
@@ -65,135 +61,209 @@ class AgentApp(BaseApp):
|
|
|
65
61
|
self.after_finish = after_finish
|
|
66
62
|
self.broker_url = broker_url
|
|
67
63
|
self.backend_url = backend_url
|
|
64
|
+
self.enable_embedded_worker = enable_embedded_worker
|
|
68
65
|
|
|
69
|
-
self.
|
|
70
|
-
self._runner = None
|
|
66
|
+
self._runner = runner
|
|
71
67
|
self.custom_endpoints = [] # Store custom endpoints
|
|
72
68
|
|
|
73
|
-
|
|
69
|
+
# Custom Handlers
|
|
70
|
+
self._query_handler: Optional[Callable] = None
|
|
71
|
+
self._init_handler: Optional[Callable] = None
|
|
72
|
+
self._shutdown_handler: Optional[Callable] = None
|
|
73
|
+
self._framework_type: Optional[str] = None
|
|
74
|
+
|
|
75
|
+
a2a_protocol = A2AFastAPIDefaultAdapter(
|
|
76
|
+
agent_name=app_name,
|
|
77
|
+
agent_description=app_description,
|
|
78
|
+
)
|
|
79
|
+
|
|
74
80
|
response_protocol = ResponseAPIDefaultAdapter()
|
|
75
81
|
self.protocol_adapters = [a2a_protocol, response_protocol]
|
|
76
82
|
|
|
77
|
-
|
|
78
|
-
self._runner = Runner(
|
|
79
|
-
agent=self._agent,
|
|
80
|
-
environment_manager=environment_manager,
|
|
81
|
-
context_manager=context_manager,
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
@asynccontextmanager
|
|
85
|
-
async def lifespan(app: FastAPI) -> Any:
|
|
86
|
-
"""Manage the application lifespan."""
|
|
87
|
-
if hasattr(self, "before_start") and self.before_start:
|
|
88
|
-
if asyncio.iscoroutinefunction(self.before_start):
|
|
89
|
-
await self.before_start(app, **getattr(self, "kwargs", {}))
|
|
90
|
-
else:
|
|
91
|
-
self.before_start(app, **getattr(self, "kwargs", {}))
|
|
92
|
-
yield
|
|
93
|
-
if hasattr(self, "after_finish") and self.after_finish:
|
|
94
|
-
if asyncio.iscoroutinefunction(self.after_finish):
|
|
95
|
-
await self.after_finish(app, **getattr(self, "kwargs", {}))
|
|
96
|
-
else:
|
|
97
|
-
self.after_finish(app, **getattr(self, "kwargs", {}))
|
|
98
|
-
|
|
99
|
-
kwargs = {
|
|
83
|
+
self._app_kwargs = {
|
|
100
84
|
"title": "Agent Service",
|
|
101
85
|
"version": __version__,
|
|
102
86
|
"description": "Production-ready Agent Service API",
|
|
103
|
-
"lifespan": lifespan,
|
|
104
87
|
**kwargs,
|
|
105
88
|
}
|
|
106
89
|
|
|
107
|
-
if self._runner:
|
|
108
|
-
if self.stream:
|
|
109
|
-
self.func = self._runner.stream_query
|
|
110
|
-
else:
|
|
111
|
-
self.func = self._runner.query
|
|
112
|
-
|
|
113
90
|
super().__init__(
|
|
114
91
|
broker_url=broker_url,
|
|
115
92
|
backend_url=backend_url,
|
|
116
|
-
**kwargs,
|
|
117
93
|
)
|
|
118
94
|
|
|
119
95
|
# Store custom endpoints and tasks for deployment
|
|
120
96
|
# but don't add them to FastAPI here - let FastAPIAppFactory handle it
|
|
121
97
|
|
|
98
|
+
def init(self, func):
|
|
99
|
+
"""Register init hook (support async and sync functions)."""
|
|
100
|
+
self._init_handler = func
|
|
101
|
+
return func
|
|
102
|
+
|
|
103
|
+
def query(self, framework: Optional[str] = "agentscope"):
|
|
104
|
+
"""
|
|
105
|
+
Register run hook and optionally specify agent framework.
|
|
106
|
+
Allowed framework values: 'agentscope', 'autogen', 'agno', 'langgraph'.
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
allowed_frameworks = {"agentscope", "autogen", "agno", "langgraph"}
|
|
110
|
+
if framework not in allowed_frameworks:
|
|
111
|
+
raise ValueError(f"framework must be one of {allowed_frameworks}")
|
|
112
|
+
|
|
113
|
+
def decorator(func):
|
|
114
|
+
self._query_handler = func
|
|
115
|
+
self._framework_type = framework
|
|
116
|
+
return func
|
|
117
|
+
|
|
118
|
+
return decorator
|
|
119
|
+
|
|
120
|
+
def shutdown(self, func):
|
|
121
|
+
"""Register shutdown hook (support async and sync functions)."""
|
|
122
|
+
self._shutdown_handler = func
|
|
123
|
+
return func
|
|
124
|
+
|
|
125
|
+
def _build_runner(self):
|
|
126
|
+
if self._runner is None:
|
|
127
|
+
self._runner = Runner()
|
|
128
|
+
|
|
129
|
+
if self._framework_type is not None:
|
|
130
|
+
self._runner.framework_type = self._framework_type
|
|
131
|
+
|
|
132
|
+
if self._query_handler is not None:
|
|
133
|
+
self._runner.query_handler = types.MethodType(
|
|
134
|
+
self._query_handler,
|
|
135
|
+
self._runner,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
if self._init_handler is not None:
|
|
139
|
+
self._runner.init_handler = types.MethodType(
|
|
140
|
+
self._init_handler,
|
|
141
|
+
self._runner,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
if self._shutdown_handler is not None:
|
|
145
|
+
self._runner.shutdown_handler = types.MethodType(
|
|
146
|
+
self._shutdown_handler,
|
|
147
|
+
self._runner,
|
|
148
|
+
)
|
|
149
|
+
|
|
122
150
|
def run(
|
|
123
151
|
self,
|
|
124
152
|
host="0.0.0.0",
|
|
125
153
|
port=8090,
|
|
126
|
-
|
|
127
|
-
services_config=None,
|
|
154
|
+
web_ui=False,
|
|
128
155
|
**kwargs,
|
|
129
156
|
):
|
|
130
157
|
"""
|
|
131
|
-
|
|
158
|
+
Launch the AgentApp HTTP API server.
|
|
159
|
+
|
|
160
|
+
This method starts a FastAPI server for the agent service.
|
|
161
|
+
Optionally, it can also launch a browser-based Web UI for
|
|
162
|
+
interacting with the agent.
|
|
163
|
+
|
|
164
|
+
Note:
|
|
165
|
+
If `web_ui=True` and this is the **first time** launching the Web UI,
|
|
166
|
+
additional time may be required to initialize. This happens because the
|
|
167
|
+
underlying Node.js command (`npx @agentscope-ai/chat
|
|
168
|
+
agentscope-runtime-webui`) might install dependencies and set up
|
|
169
|
+
the runtime environment.
|
|
132
170
|
|
|
133
171
|
Args:
|
|
134
|
-
host: Host to bind to
|
|
135
|
-
port: Port to
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
172
|
+
host (str): Host address to bind to. Default "0.0.0.0".
|
|
173
|
+
port (int): Port number to serve the application on. Default 8090.
|
|
174
|
+
web_ui (bool): If True, launches the Agentscope Web UI in a
|
|
175
|
+
separate process, pointing it to the API endpoint. This
|
|
176
|
+
allows interactive use via browser. Default False.
|
|
177
|
+
**kwargs: Additional keyword arguments passed to FastAPIAppFactory
|
|
178
|
+
when creating the FastAPI application.
|
|
179
|
+
|
|
180
|
+
Example:
|
|
181
|
+
>>> app = AgentApp(app_name="MyAgent")
|
|
182
|
+
>>> app.run(host="127.0.0.1", port=8000, web_ui=True)
|
|
139
183
|
"""
|
|
184
|
+
# Build runner
|
|
185
|
+
self._build_runner()
|
|
140
186
|
|
|
141
187
|
try:
|
|
142
188
|
logger.info(
|
|
143
189
|
"[AgentApp] Starting AgentApp with FastAPIAppFactory...",
|
|
144
190
|
)
|
|
145
|
-
|
|
146
|
-
# Use default services config if not provided
|
|
147
|
-
if services_config is None:
|
|
148
|
-
services_config = DEFAULT_SERVICES_CONFIG
|
|
149
|
-
|
|
150
|
-
# Create FastAPI application using the factory
|
|
151
|
-
fastapi_app = FastAPIAppFactory.create_app(
|
|
152
|
-
runner=self._runner,
|
|
153
|
-
endpoint_path=self.endpoint_path,
|
|
154
|
-
request_model=self.request_model,
|
|
155
|
-
response_type=self.response_type,
|
|
156
|
-
stream=self.stream,
|
|
157
|
-
before_start=self.before_start,
|
|
158
|
-
after_finish=self.after_finish,
|
|
159
|
-
mode=DeploymentMode.DAEMON_THREAD,
|
|
160
|
-
services_config=services_config,
|
|
161
|
-
protocol_adapters=self.protocol_adapters,
|
|
162
|
-
custom_endpoints=self.custom_endpoints,
|
|
163
|
-
broker_url=self.broker_url,
|
|
164
|
-
backend_url=self.backend_url,
|
|
165
|
-
enable_embedded_worker=embed_task_processor,
|
|
166
|
-
**kwargs,
|
|
167
|
-
)
|
|
191
|
+
fastapi_app = self.get_fastapi_app(**kwargs)
|
|
168
192
|
|
|
169
193
|
logger.info(f"[AgentApp] Starting server on {host}:{port}")
|
|
170
194
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
195
|
+
if web_ui:
|
|
196
|
+
webui_url = f"http://{host}:{port}{self.endpoint_path}"
|
|
197
|
+
cmd = (
|
|
198
|
+
f"npx @agentscope-ai/chat agentscope-runtime-webui "
|
|
199
|
+
f"--url {webui_url}"
|
|
200
|
+
)
|
|
201
|
+
logger.info(f"[AgentApp] WebUI started at {webui_url}")
|
|
202
|
+
logger.info(
|
|
203
|
+
"[AgentApp] Note: First WebUI launch may take extra time "
|
|
204
|
+
"as dependencies are installed.",
|
|
205
|
+
)
|
|
206
|
+
with subprocess.Popen(shlex.split(cmd)):
|
|
207
|
+
uvicorn.run(
|
|
208
|
+
fastapi_app,
|
|
209
|
+
host=host,
|
|
210
|
+
port=port,
|
|
211
|
+
log_level="info",
|
|
212
|
+
access_log=True,
|
|
213
|
+
)
|
|
214
|
+
else:
|
|
215
|
+
uvicorn.run(
|
|
216
|
+
fastapi_app,
|
|
217
|
+
host=host,
|
|
218
|
+
port=port,
|
|
219
|
+
log_level="info",
|
|
220
|
+
access_log=True,
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
except KeyboardInterrupt:
|
|
224
|
+
logger.info(
|
|
225
|
+
"[AgentApp] KeyboardInterrupt received, shutting down...",
|
|
178
226
|
)
|
|
179
227
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
228
|
+
def get_fastapi_app(self, **kwargs):
|
|
229
|
+
"""Get the FastAPI application"""
|
|
230
|
+
|
|
231
|
+
self._build_runner()
|
|
232
|
+
mode = kwargs.pop("mode", DeploymentMode.DAEMON_THREAD)
|
|
233
|
+
|
|
234
|
+
return FastAPIAppFactory.create_app(
|
|
235
|
+
runner=self._runner,
|
|
236
|
+
endpoint_path=self.endpoint_path,
|
|
237
|
+
request_model=self.request_model,
|
|
238
|
+
response_type=self.response_type,
|
|
239
|
+
stream=self.stream,
|
|
240
|
+
before_start=self.before_start,
|
|
241
|
+
after_finish=self.after_finish,
|
|
242
|
+
mode=mode,
|
|
243
|
+
protocol_adapters=self.protocol_adapters,
|
|
244
|
+
custom_endpoints=self.custom_endpoints,
|
|
245
|
+
broker_url=self.broker_url,
|
|
246
|
+
backend_url=self.backend_url,
|
|
247
|
+
enable_embedded_worker=self.enable_embedded_worker,
|
|
248
|
+
app_kwargs=self._app_kwargs,
|
|
249
|
+
**kwargs,
|
|
250
|
+
)
|
|
183
251
|
|
|
184
|
-
async def deploy(self, deployer, **kwargs):
|
|
252
|
+
async def deploy(self, deployer: DeployManager, **kwargs):
|
|
185
253
|
"""Deploy the agent app with custom endpoints support"""
|
|
186
254
|
# Pass custom endpoints and tasks to the deployer
|
|
255
|
+
# Build runner
|
|
256
|
+
self._build_runner()
|
|
187
257
|
|
|
188
258
|
deploy_kwargs = {
|
|
189
|
-
|
|
259
|
+
"app": self,
|
|
190
260
|
"custom_endpoints": self.custom_endpoints,
|
|
191
|
-
"agent": self._agent,
|
|
192
261
|
"runner": self._runner,
|
|
193
262
|
"endpoint_path": self.endpoint_path,
|
|
194
263
|
"stream": self.stream,
|
|
195
264
|
"protocol_adapters": self.protocol_adapters,
|
|
196
265
|
}
|
|
266
|
+
deploy_kwargs.update(kwargs)
|
|
197
267
|
return await deployer.deploy(**deploy_kwargs)
|
|
198
268
|
|
|
199
269
|
def endpoint(self, path: str, methods: Optional[List[str]] = None):
|
|
@@ -1,38 +1,29 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
import inspect
|
|
3
3
|
import logging
|
|
4
|
-
import threading
|
|
5
4
|
from typing import Callable, Optional
|
|
6
5
|
|
|
7
|
-
import
|
|
8
|
-
from fastapi import FastAPI, Request
|
|
9
|
-
from fastapi.responses import StreamingResponse
|
|
6
|
+
from fastapi import Request
|
|
10
7
|
|
|
11
8
|
from .celery_mixin import CeleryMixin
|
|
12
9
|
|
|
13
10
|
logger = logging.getLogger(__name__)
|
|
14
11
|
|
|
15
12
|
|
|
16
|
-
class BaseApp(
|
|
13
|
+
class BaseApp(CeleryMixin):
|
|
17
14
|
"""
|
|
18
|
-
BaseApp
|
|
19
|
-
|
|
15
|
+
BaseApp integrates Celery for asynchronous background task execution,
|
|
16
|
+
and provides FastAPI-like routing for task endpoints.
|
|
20
17
|
"""
|
|
21
18
|
|
|
22
19
|
def __init__(
|
|
23
20
|
self,
|
|
24
21
|
broker_url: Optional[str] = None,
|
|
25
22
|
backend_url: Optional[str] = None,
|
|
26
|
-
**kwargs,
|
|
27
23
|
):
|
|
28
24
|
# Initialize CeleryMixin
|
|
29
25
|
CeleryMixin.__init__(self, broker_url, backend_url)
|
|
30
26
|
|
|
31
|
-
self.server = None
|
|
32
|
-
|
|
33
|
-
# Initialize FastAPI
|
|
34
|
-
FastAPI.__init__(self, **kwargs)
|
|
35
|
-
|
|
36
27
|
def task(self, path: str, queue: str = "celery"):
|
|
37
28
|
"""
|
|
38
29
|
Register an asynchronous task endpoint.
|
|
@@ -74,108 +65,3 @@ class BaseApp(FastAPI, CeleryMixin):
|
|
|
74
65
|
return func
|
|
75
66
|
|
|
76
67
|
return decorator
|
|
77
|
-
|
|
78
|
-
def endpoint(self, path: str):
|
|
79
|
-
"""
|
|
80
|
-
Unified POST endpoint decorator.
|
|
81
|
-
Pure FastAPI functionality, independent of Celery.
|
|
82
|
-
Supports:
|
|
83
|
-
- Sync functions
|
|
84
|
-
- Async functions (coroutines)
|
|
85
|
-
- Sync/async generator functions (streaming responses)
|
|
86
|
-
"""
|
|
87
|
-
|
|
88
|
-
def decorator(func: Callable):
|
|
89
|
-
is_async_gen = inspect.isasyncgenfunction(func)
|
|
90
|
-
is_sync_gen = inspect.isgeneratorfunction(func)
|
|
91
|
-
|
|
92
|
-
if is_async_gen or is_sync_gen:
|
|
93
|
-
# Handle streaming responses
|
|
94
|
-
async def _stream_generator(request: Request):
|
|
95
|
-
if is_async_gen:
|
|
96
|
-
async for chunk in func(request):
|
|
97
|
-
yield chunk
|
|
98
|
-
else:
|
|
99
|
-
for chunk in func(request):
|
|
100
|
-
yield chunk
|
|
101
|
-
|
|
102
|
-
@self.post(path)
|
|
103
|
-
async def _wrapped(request: Request):
|
|
104
|
-
return StreamingResponse(
|
|
105
|
-
_stream_generator(request),
|
|
106
|
-
media_type="text/plain",
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
else:
|
|
110
|
-
# Handle regular responses
|
|
111
|
-
@self.post(path)
|
|
112
|
-
async def _wrapped(request: Request):
|
|
113
|
-
if inspect.iscoroutinefunction(func):
|
|
114
|
-
return await func(request)
|
|
115
|
-
else:
|
|
116
|
-
return func(request)
|
|
117
|
-
|
|
118
|
-
return func
|
|
119
|
-
|
|
120
|
-
return decorator
|
|
121
|
-
|
|
122
|
-
def run(
|
|
123
|
-
self,
|
|
124
|
-
host="0.0.0.0",
|
|
125
|
-
port=8090,
|
|
126
|
-
embed_task_processor=False,
|
|
127
|
-
**kwargs,
|
|
128
|
-
):
|
|
129
|
-
"""
|
|
130
|
-
Run FastAPI with uvicorn.
|
|
131
|
-
"""
|
|
132
|
-
if embed_task_processor:
|
|
133
|
-
if self.celery_app is None:
|
|
134
|
-
logger.warning(
|
|
135
|
-
"[AgentApp] Celery is not configured. "
|
|
136
|
-
"Cannot run embedded worker.",
|
|
137
|
-
)
|
|
138
|
-
else:
|
|
139
|
-
logger.warning(
|
|
140
|
-
"[AgentApp] embed_task_processor=True: Running "
|
|
141
|
-
"task_processor in embedded thread mode. This is "
|
|
142
|
-
"intended for development/debug purposes only. In "
|
|
143
|
-
"production, run Celery worker in a separate process!",
|
|
144
|
-
)
|
|
145
|
-
|
|
146
|
-
queues = self._registered_queues or {"celery"}
|
|
147
|
-
queue_list = ",".join(sorted(queues))
|
|
148
|
-
|
|
149
|
-
def start_celery_worker():
|
|
150
|
-
logger.info(
|
|
151
|
-
f"[AgentApp] Embedded worker listening "
|
|
152
|
-
f"queues: {queue_list}",
|
|
153
|
-
)
|
|
154
|
-
self.celery_app.worker_main(
|
|
155
|
-
[
|
|
156
|
-
"worker",
|
|
157
|
-
"--loglevel=INFO",
|
|
158
|
-
"-Q",
|
|
159
|
-
queue_list,
|
|
160
|
-
],
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
threading.Thread(
|
|
164
|
-
target=start_celery_worker,
|
|
165
|
-
daemon=True,
|
|
166
|
-
).start()
|
|
167
|
-
logger.info(
|
|
168
|
-
"[AgentApp] Embedded task processor started in background "
|
|
169
|
-
"thread (DEV mode).",
|
|
170
|
-
)
|
|
171
|
-
|
|
172
|
-
# TODO: Add CLI to main entrypoint to control run/deploy
|
|
173
|
-
|
|
174
|
-
config = uvicorn.Config(
|
|
175
|
-
app=self,
|
|
176
|
-
host=host,
|
|
177
|
-
port=port,
|
|
178
|
-
**kwargs,
|
|
179
|
-
)
|
|
180
|
-
self.server = uvicorn.Server(config)
|
|
181
|
-
self.server.run()
|
|
@@ -8,9 +8,17 @@ from .modelstudio_deployer import (
|
|
|
8
8
|
ModelstudioDeployManager,
|
|
9
9
|
)
|
|
10
10
|
|
|
11
|
+
try:
|
|
12
|
+
from .agentrun_deployer import (
|
|
13
|
+
AgentRunDeployManager,
|
|
14
|
+
)
|
|
15
|
+
except ImportError:
|
|
16
|
+
AgentRunDeployManager = None # type: ignore
|
|
17
|
+
|
|
11
18
|
__all__ = [
|
|
12
19
|
"DeployManager",
|
|
13
20
|
"LocalDeployManager",
|
|
14
21
|
"KubernetesDeployManager",
|
|
15
22
|
"ModelstudioDeployManager",
|
|
23
|
+
"AgentRunDeployManager",
|
|
16
24
|
]
|