agentscope-runtime 0.2.0b2__py3-none-any.whl → 1.0.0b1__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 +474 -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/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 +256 -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 +170 -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} +12 -18
- 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/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 -2
- agentscope_runtime/sandbox/client/http_client.py +1 -0
- agentscope_runtime/sandbox/enums.py +2 -0
- agentscope_runtime/sandbox/manager/sandbox_manager.py +18 -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.0b2.dist-info → agentscope_runtime-1.0.0b1.dist-info}/METADATA +234 -165
- agentscope_runtime-1.0.0b1.dist-info/RECORD +240 -0
- {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0b1.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 -220
- 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.0b2.dist-info/RECORD +0 -183
- {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0b1.dist-info}/WHEEL +0 -0
- {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0b1.dist-info}/licenses/LICENSE +0 -0
- {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0b1.dist-info}/top_level.txt +0 -0
|
@@ -13,7 +13,8 @@ class FastAPITemplateManager:
|
|
|
13
13
|
def __init__(self):
|
|
14
14
|
"""Initialize template manager."""
|
|
15
15
|
self.template_dir = os.path.join(
|
|
16
|
-
os.path.dirname(__file__),
|
|
16
|
+
os.path.dirname(os.path.dirname(__file__)),
|
|
17
|
+
"templates",
|
|
17
18
|
)
|
|
18
19
|
self.env = Environment(
|
|
19
20
|
loader=FileSystemLoader(self.template_dir),
|
|
@@ -59,7 +60,6 @@ class FastAPITemplateManager:
|
|
|
59
60
|
response_type: str = "sse",
|
|
60
61
|
runner_code: str = "",
|
|
61
62
|
func_code: str = "",
|
|
62
|
-
services_config: str = "",
|
|
63
63
|
protocol_adapters: Optional[str] = None,
|
|
64
64
|
**kwargs,
|
|
65
65
|
) -> str:
|
|
@@ -73,7 +73,6 @@ class FastAPITemplateManager:
|
|
|
73
73
|
response_type: Response type
|
|
74
74
|
runner_code: Code to setup runner
|
|
75
75
|
func_code: Code to setup custom function
|
|
76
|
-
services_config: Services configuration code
|
|
77
76
|
protocol_adapters: Protocol adapters code string
|
|
78
77
|
**kwargs: Additional template variables
|
|
79
78
|
|
|
@@ -89,7 +88,6 @@ class FastAPITemplateManager:
|
|
|
89
88
|
response_type=response_type,
|
|
90
89
|
runner_code=runner_code,
|
|
91
90
|
func_code=func_code,
|
|
92
|
-
services_config=services_config,
|
|
93
91
|
protocol_adapters=protocol_adapters,
|
|
94
92
|
**kwargs,
|
|
95
93
|
)
|
|
@@ -251,13 +251,17 @@ class ProcessManager:
|
|
|
251
251
|
"""
|
|
252
252
|
import socket
|
|
253
253
|
|
|
254
|
+
# Normalize host for connection check
|
|
255
|
+
# When service binds to 0.0.0.0, we need to connect to 127.0.0.1
|
|
256
|
+
check_host = self._normalize_host_for_check(host)
|
|
257
|
+
|
|
254
258
|
end_time = asyncio.get_event_loop().time() + timeout
|
|
255
259
|
|
|
256
260
|
while asyncio.get_event_loop().time() < end_time:
|
|
257
261
|
try:
|
|
258
262
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
|
|
259
263
|
sock.settimeout(1)
|
|
260
|
-
result = sock.connect_ex((
|
|
264
|
+
result = sock.connect_ex((check_host, port))
|
|
261
265
|
if result == 0:
|
|
262
266
|
return True
|
|
263
267
|
except Exception:
|
|
@@ -266,3 +270,21 @@ class ProcessManager:
|
|
|
266
270
|
await asyncio.sleep(0.5)
|
|
267
271
|
|
|
268
272
|
return False
|
|
273
|
+
|
|
274
|
+
@staticmethod
|
|
275
|
+
def _normalize_host_for_check(host: str) -> str:
|
|
276
|
+
"""Normalize host for connection check.
|
|
277
|
+
|
|
278
|
+
When a service binds to 0.0.0.0 (all interfaces), it cannot be
|
|
279
|
+
directly connected to. We need to connect to 127.0.0.1 instead
|
|
280
|
+
to check if the service is running locally.
|
|
281
|
+
|
|
282
|
+
Args:
|
|
283
|
+
host: The host the service binds to
|
|
284
|
+
|
|
285
|
+
Returns:
|
|
286
|
+
The host to use for connection check
|
|
287
|
+
"""
|
|
288
|
+
if host in ("0.0.0.0", "::"):
|
|
289
|
+
return "127.0.0.1"
|
|
290
|
+
return host
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Auto-generated main.py for AgentApp deployment.
|
|
4
|
+
|
|
5
|
+
This file imports and runs the AgentApp from the original entrypoint file,
|
|
6
|
+
avoiding circular deployment issues.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import argparse
|
|
10
|
+
import asyncio
|
|
11
|
+
from agentscope_runtime.engine.deployers.utils.deployment_modes import DeploymentMode
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
from {{ module_name }} import {{ object_name }}
|
|
15
|
+
|
|
16
|
+
# Type whitelist for argument parser to prevent code injection
|
|
17
|
+
ALLOWED_TYPES = {
|
|
18
|
+
"int": int,
|
|
19
|
+
"str": str,
|
|
20
|
+
"float": float,
|
|
21
|
+
"bool": bool,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def main():
|
|
26
|
+
"""Run the AgentApp service."""
|
|
27
|
+
parser = argparse.ArgumentParser(
|
|
28
|
+
description="{{ object_name }} Service"
|
|
29
|
+
)
|
|
30
|
+
parser.add_argument(
|
|
31
|
+
"--host",
|
|
32
|
+
default="{{ host }}",
|
|
33
|
+
help="Host to bind to (default: {{ host }})"
|
|
34
|
+
)
|
|
35
|
+
parser.add_argument(
|
|
36
|
+
"--port",
|
|
37
|
+
type=int,
|
|
38
|
+
default={{ port }},
|
|
39
|
+
help="Port to bind to (default: {{ port }})"
|
|
40
|
+
)
|
|
41
|
+
parser.add_argument(
|
|
42
|
+
"--embed-task-processor",
|
|
43
|
+
action="store_true",
|
|
44
|
+
default=False,
|
|
45
|
+
help="Whether to embed task processor"
|
|
46
|
+
)
|
|
47
|
+
{% if extra_parameters %}
|
|
48
|
+
|
|
49
|
+
# Additional runtime parameters
|
|
50
|
+
{% for param in extra_parameters %}
|
|
51
|
+
{% set cli_arg = param.cli_name or '--' + param.name.replace('_', '-') %}
|
|
52
|
+
parser.add_argument(
|
|
53
|
+
{{ cli_arg | tojson }},
|
|
54
|
+
{% if param.type == "bool" %}
|
|
55
|
+
action="store_true",
|
|
56
|
+
default={{ param.default | default(False) | lower }},
|
|
57
|
+
{% else %}
|
|
58
|
+
type=ALLOWED_TYPES[{{ param.type | tojson }}],
|
|
59
|
+
default={{ param.default | tojson if param.default is not none else 'None' }},
|
|
60
|
+
{% endif %}
|
|
61
|
+
help={{ (param.help or param.name) | tojson }}
|
|
62
|
+
)
|
|
63
|
+
{% endfor %}
|
|
64
|
+
{% endif %}
|
|
65
|
+
|
|
66
|
+
args = parser.parse_args()
|
|
67
|
+
|
|
68
|
+
# Run the AgentApp with specified parameters
|
|
69
|
+
{{ object_name }}.run(
|
|
70
|
+
mode=DeploymentMode.DETACHED_PROCESS,
|
|
71
|
+
host=args.host,
|
|
72
|
+
port=args.port,
|
|
73
|
+
embed_task_processor=args.embed_task_processor,
|
|
74
|
+
{% if extra_parameters %}
|
|
75
|
+
# Additional parameters
|
|
76
|
+
{% for param in extra_parameters %}
|
|
77
|
+
{{ param.name }}=args.{{ param.name }},
|
|
78
|
+
{% endfor %}
|
|
79
|
+
{% endif %}
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
if __name__ == "__main__":
|
|
84
|
+
main()
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Auto-generated main.py for Runner deployment.
|
|
4
|
+
|
|
5
|
+
This file imports the Runner from the original entrypoint file,
|
|
6
|
+
wraps it in an AgentApp, and runs it as a service.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import argparse
|
|
10
|
+
import asyncio
|
|
11
|
+
from {{ module_name }} import {{ object_name }}
|
|
12
|
+
from agentscope_runtime.engine.app import AgentApp
|
|
13
|
+
|
|
14
|
+
# Type whitelist for argument parser to prevent code injection
|
|
15
|
+
ALLOWED_TYPES = {
|
|
16
|
+
"int": int,
|
|
17
|
+
"str": str,
|
|
18
|
+
"float": float,
|
|
19
|
+
"bool": bool,
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# Wrap the runner in an AgentApp
|
|
24
|
+
app = AgentApp(
|
|
25
|
+
app_name="{{ app_name }}",
|
|
26
|
+
app_description="{{ app_description }}",
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@app.query(framework="agentscope")
|
|
31
|
+
async def query_func(self, msgs, **kwargs):
|
|
32
|
+
"""Query handler that uses the runner."""
|
|
33
|
+
result = await {{ object_name }}(msgs)
|
|
34
|
+
return result
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
async def main():
|
|
38
|
+
"""Run the Runner as an AgentApp service."""
|
|
39
|
+
parser = argparse.ArgumentParser(
|
|
40
|
+
description="{{ object_name }} Service (wrapped in AgentApp)"
|
|
41
|
+
)
|
|
42
|
+
parser.add_argument(
|
|
43
|
+
"--host",
|
|
44
|
+
default="{{ host }}",
|
|
45
|
+
help="Host to bind to (default: {{ host }})"
|
|
46
|
+
)
|
|
47
|
+
parser.add_argument(
|
|
48
|
+
"--port",
|
|
49
|
+
type=int,
|
|
50
|
+
default={{ port }},
|
|
51
|
+
help="Port to bind to (default: {{ port }})"
|
|
52
|
+
)
|
|
53
|
+
parser.add_argument(
|
|
54
|
+
"--embed-task-processor",
|
|
55
|
+
action="store_true",
|
|
56
|
+
default=False,
|
|
57
|
+
help="Whether to embed task processor"
|
|
58
|
+
)
|
|
59
|
+
{% if extra_parameters %}
|
|
60
|
+
|
|
61
|
+
# Additional runtime parameters
|
|
62
|
+
{% for param in extra_parameters %}
|
|
63
|
+
{% set cli_arg = param.cli_name or '--' + param.name.replace('_', '-') %}
|
|
64
|
+
parser.add_argument(
|
|
65
|
+
{{ cli_arg | tojson }},
|
|
66
|
+
{% if param.type == "bool" %}
|
|
67
|
+
action="store_true",
|
|
68
|
+
default={{ param.default | default(False) | lower }},
|
|
69
|
+
{% else %}
|
|
70
|
+
type=ALLOWED_TYPES[{{ param.type | tojson }}],
|
|
71
|
+
default={{ param.default | tojson if param.default is not none else 'None' }},
|
|
72
|
+
{% endif %}
|
|
73
|
+
help={{ (param.help or param.name) | tojson }}
|
|
74
|
+
)
|
|
75
|
+
{% endfor %}
|
|
76
|
+
{% endif %}
|
|
77
|
+
|
|
78
|
+
args = parser.parse_args()
|
|
79
|
+
|
|
80
|
+
# Run the wrapped AgentApp with specified parameters
|
|
81
|
+
await app.run(
|
|
82
|
+
host=args.host,
|
|
83
|
+
port=args.port,
|
|
84
|
+
embed_task_processor=args.embed_task_processor,
|
|
85
|
+
{% if extra_parameters %}
|
|
86
|
+
# Additional parameters
|
|
87
|
+
{% for param in extra_parameters %}
|
|
88
|
+
{{ param.name }}=args.{{ param.name }},
|
|
89
|
+
{% endfor %}
|
|
90
|
+
{% endif %}
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
if __name__ == "__main__":
|
|
95
|
+
asyncio.run(main())
|
|
@@ -19,8 +19,6 @@ import uvicorn
|
|
|
19
19
|
from agentscope_runtime.engine.deployers.utils.deployment_modes import DeploymentMode
|
|
20
20
|
from agentscope_runtime.engine.deployers.utils.service_utils import (
|
|
21
21
|
FastAPIAppFactory,
|
|
22
|
-
ServicesConfig,
|
|
23
|
-
ServiceConfig,
|
|
24
22
|
)
|
|
25
23
|
from agentscope_runtime.engine.schemas.agent_schemas import AgentRequest
|
|
26
24
|
from typing import Callable, Optional, Dict, List, Any, Union
|
|
@@ -41,45 +39,6 @@ from agent_file import {{endpoint.function_name}}
|
|
|
41
39
|
|
|
42
40
|
|
|
43
41
|
|
|
44
|
-
def load_services_config() -> ServicesConfig:
|
|
45
|
-
"""Load services configuration from environment variables or config file."""
|
|
46
|
-
config_file = os.getenv('AGENTSCOPE_SERVICES_CONFIG')
|
|
47
|
-
|
|
48
|
-
if config_file and os.path.exists(config_file):
|
|
49
|
-
# Load from JSON config file
|
|
50
|
-
import json
|
|
51
|
-
with open(config_file, 'r', encoding='utf-8') as f:
|
|
52
|
-
config_data = json.load(f)
|
|
53
|
-
return ServicesConfig.model_validate(config_data)
|
|
54
|
-
else:
|
|
55
|
-
# Load from environment variables
|
|
56
|
-
memory_provider = os.getenv('MEMORY_PROVIDER', 'in_memory')
|
|
57
|
-
session_provider = os.getenv('SESSION_HISTORY_PROVIDER', 'in_memory')
|
|
58
|
-
|
|
59
|
-
memory_config = {}
|
|
60
|
-
session_config = {}
|
|
61
|
-
|
|
62
|
-
# Add Redis configuration if using Redis
|
|
63
|
-
if memory_provider == 'redis':
|
|
64
|
-
memory_config = {
|
|
65
|
-
'host': os.getenv('REDIS_HOST', 'localhost'),
|
|
66
|
-
'port': int(os.getenv('REDIS_PORT', 6379)),
|
|
67
|
-
'db': int(os.getenv('REDIS_MEMORY_DB', 0))
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if session_provider == 'redis':
|
|
71
|
-
session_config = {
|
|
72
|
-
'host': os.getenv('REDIS_HOST', 'localhost'),
|
|
73
|
-
'port': int(os.getenv('REDIS_PORT', 6379)),
|
|
74
|
-
'db': int(os.getenv('REDIS_SESSION_DB', 1))
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return ServicesConfig(
|
|
78
|
-
memory=ServiceConfig(provider=memory_provider, config=memory_config),
|
|
79
|
-
session_history=ServiceConfig(provider=session_provider, config=session_config)
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
|
|
83
42
|
def load_celery_config():
|
|
84
43
|
"""Load Celery configuration from environment variables or infer from existing config."""
|
|
85
44
|
celery_config = {
|
|
@@ -162,9 +121,6 @@ async def after_finish(app, **kwargs):
|
|
|
162
121
|
pass
|
|
163
122
|
|
|
164
123
|
|
|
165
|
-
# Load services configuration
|
|
166
|
-
services_config = load_services_config()
|
|
167
|
-
|
|
168
124
|
# Load Celery configuration
|
|
169
125
|
celery_config = load_celery_config()
|
|
170
126
|
|
|
@@ -181,7 +137,6 @@ else:
|
|
|
181
137
|
app = FastAPIAppFactory.create_app(
|
|
182
138
|
endpoint_path="{{endpoint_path}}",
|
|
183
139
|
mode=deployment_mode,
|
|
184
|
-
services_config=services_config,
|
|
185
140
|
before_start=before_start,
|
|
186
141
|
after_finish=after_finish,
|
|
187
142
|
stream=True,
|
|
@@ -30,7 +30,7 @@ except ImportError: # pragma: no cover - fallback on older Pythons
|
|
|
30
30
|
tomllib = None # type: ignore
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
def _read_text_file_lines(file_path: Path) -> List[str]:
|
|
34
34
|
if not file_path.is_file():
|
|
35
35
|
return []
|
|
36
36
|
return [
|
|
@@ -39,16 +39,32 @@ async def _read_text_file_lines(file_path: Path) -> List[str]:
|
|
|
39
39
|
]
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
def _parse_requirements_txt(req_path: Path) -> Tuple[List[str], List[str]]:
|
|
43
|
+
"""
|
|
44
|
+
Parse requirements.txt, separating standard requirements from local wheel paths.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
Tuple of (standard_requirements, local_wheel_paths)
|
|
48
|
+
"""
|
|
49
|
+
standard_requirements: List[str] = []
|
|
50
|
+
local_wheel_paths: List[str] = []
|
|
51
|
+
|
|
52
|
+
for line in _read_text_file_lines(req_path):
|
|
45
53
|
if not line or line.startswith("#"):
|
|
46
54
|
continue
|
|
47
|
-
requirements.append(line)
|
|
48
|
-
return requirements
|
|
49
55
|
|
|
56
|
+
# Check if this is a local wheel file path
|
|
57
|
+
if line.endswith(".whl") and (
|
|
58
|
+
"/" in line or "\\" in line or line.startswith(".")
|
|
59
|
+
):
|
|
60
|
+
local_wheel_paths.append(line)
|
|
61
|
+
else:
|
|
62
|
+
standard_requirements.append(line)
|
|
63
|
+
|
|
64
|
+
return standard_requirements, local_wheel_paths
|
|
50
65
|
|
|
51
|
-
|
|
66
|
+
|
|
67
|
+
def _parse_pyproject_toml(pyproject_path: Path) -> List[str]:
|
|
52
68
|
deps: List[str] = []
|
|
53
69
|
if not pyproject_path.is_file():
|
|
54
70
|
return deps
|
|
@@ -114,15 +130,30 @@ async def _parse_pyproject_toml(pyproject_path: Path) -> List[str]:
|
|
|
114
130
|
return deps
|
|
115
131
|
|
|
116
132
|
|
|
117
|
-
|
|
133
|
+
def _gather_user_dependencies(
|
|
134
|
+
project_dir: Path,
|
|
135
|
+
) -> Tuple[List[str], List[Path]]:
|
|
136
|
+
"""
|
|
137
|
+
Gather user dependencies from pyproject.toml and requirements.txt.
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
Tuple of (standard_dependencies, local_wheel_files)
|
|
141
|
+
where local_wheel_files are absolute paths to wheel files
|
|
142
|
+
"""
|
|
118
143
|
pyproject = project_dir / "pyproject.toml"
|
|
119
144
|
req_txt = project_dir / "requirements.txt"
|
|
120
145
|
deps: List[str] = []
|
|
146
|
+
local_wheels: List[Path] = []
|
|
147
|
+
|
|
121
148
|
if pyproject.is_file():
|
|
122
|
-
dep =
|
|
149
|
+
dep = _parse_pyproject_toml(pyproject)
|
|
123
150
|
deps.extend(dep)
|
|
151
|
+
|
|
124
152
|
if req_txt.is_file():
|
|
125
|
-
#
|
|
153
|
+
# Parse requirements.txt to separate standard deps from local wheels
|
|
154
|
+
standard_reqs, local_wheel_paths = _parse_requirements_txt(req_txt)
|
|
155
|
+
|
|
156
|
+
# Merge standard requirements, avoiding duplicates
|
|
126
157
|
existing = set(
|
|
127
158
|
d.split("[", 1)[0]
|
|
128
159
|
.split("=", 1)[0]
|
|
@@ -132,7 +163,7 @@ async def _gather_user_dependencies(project_dir: Path) -> List[str]:
|
|
|
132
163
|
.lower()
|
|
133
164
|
for d in deps
|
|
134
165
|
)
|
|
135
|
-
for r in
|
|
166
|
+
for r in standard_reqs:
|
|
136
167
|
name_key = (
|
|
137
168
|
r.split("[", 1)[0]
|
|
138
169
|
.split("=", 1)[0]
|
|
@@ -143,7 +174,18 @@ async def _gather_user_dependencies(project_dir: Path) -> List[str]:
|
|
|
143
174
|
)
|
|
144
175
|
if name_key not in existing:
|
|
145
176
|
deps.append(r)
|
|
146
|
-
|
|
177
|
+
|
|
178
|
+
# Process local wheel paths - convert to absolute paths
|
|
179
|
+
for wheel_path_str in local_wheel_paths:
|
|
180
|
+
# Handle relative paths like ./wheels/xxx.whl or wheels/xxx.whl
|
|
181
|
+
wheel_path = Path(wheel_path_str)
|
|
182
|
+
if not wheel_path.is_absolute():
|
|
183
|
+
wheel_path = (project_dir / wheel_path).resolve()
|
|
184
|
+
|
|
185
|
+
if wheel_path.exists() and wheel_path.is_file():
|
|
186
|
+
local_wheels.append(wheel_path)
|
|
187
|
+
|
|
188
|
+
return deps, local_wheels
|
|
147
189
|
|
|
148
190
|
|
|
149
191
|
def _venv_python(venv_dir: Path) -> Path:
|
|
@@ -163,7 +205,7 @@ def _write_file(path: Path, content: str) -> None:
|
|
|
163
205
|
path.write_text(content, encoding="utf-8")
|
|
164
206
|
|
|
165
207
|
|
|
166
|
-
|
|
208
|
+
def generate_wrapper_project(
|
|
167
209
|
build_root: Path,
|
|
168
210
|
user_project_dir: Path,
|
|
169
211
|
start_cmd: str,
|
|
@@ -203,28 +245,47 @@ async def generate_wrapper_project(
|
|
|
203
245
|
)
|
|
204
246
|
|
|
205
247
|
# 2) Dependencies
|
|
206
|
-
|
|
248
|
+
_, local_wheels = _gather_user_dependencies(user_project_dir)
|
|
249
|
+
|
|
250
|
+
# Copy local wheel files to wrapper project
|
|
251
|
+
if local_wheels:
|
|
252
|
+
wheels_dir = wrapper_dir / "deploy_starter" / "wheels"
|
|
253
|
+
wheels_dir.mkdir(parents=True, exist_ok=True)
|
|
254
|
+
for wheel_file in local_wheels:
|
|
255
|
+
dest = wheels_dir / wheel_file.name
|
|
256
|
+
shutil.copy2(wheel_file, dest)
|
|
257
|
+
|
|
207
258
|
wrapper_deps = [
|
|
208
259
|
"pyyaml",
|
|
209
260
|
"alibabacloud-oss-v2",
|
|
210
|
-
"alibabacloud-bailian20231229",
|
|
261
|
+
"alibabacloud-bailian20231229>=2.6.0",
|
|
262
|
+
"alibabacloud-agentrun20250910>=2.0.1",
|
|
211
263
|
"alibabacloud-credentials",
|
|
212
264
|
"alibabacloud-tea-openapi",
|
|
213
265
|
"alibabacloud-tea-util",
|
|
214
266
|
"python-dotenv",
|
|
267
|
+
"jinja2",
|
|
268
|
+
"psutil",
|
|
215
269
|
]
|
|
216
270
|
# De-duplicate while preserving order
|
|
217
271
|
seen = set()
|
|
272
|
+
standard_reqs, local_wheel_paths = _parse_requirements_txt(
|
|
273
|
+
user_project_dir / "requirements.txt",
|
|
274
|
+
)
|
|
275
|
+
|
|
218
276
|
install_requires: List[str] = []
|
|
219
|
-
for pkg in wrapper_deps +
|
|
277
|
+
for pkg in wrapper_deps + standard_reqs:
|
|
220
278
|
key = pkg.strip().lower()
|
|
221
279
|
if key and key not in seen:
|
|
222
280
|
seen.add(key)
|
|
223
281
|
install_requires.append(pkg)
|
|
224
282
|
|
|
283
|
+
req_content = "\n".join(install_requires) + "\n"
|
|
284
|
+
req_content += "\n".join(local_wheel_paths) + "\n"
|
|
285
|
+
|
|
225
286
|
# 3) Packaging metadata
|
|
226
287
|
unique_suffix = uuid.uuid4().hex[:8]
|
|
227
|
-
package_name = f"
|
|
288
|
+
package_name = f"agentscope_runtime_{unique_suffix}"
|
|
228
289
|
version = f"0.1.{int(time.time())}"
|
|
229
290
|
|
|
230
291
|
# 4) Template package: deploy_starter
|
|
@@ -248,7 +309,29 @@ def read_config():
|
|
|
248
309
|
return yaml.safe_load(f) or {{}}
|
|
249
310
|
|
|
250
311
|
|
|
312
|
+
def install_local_wheels():
|
|
313
|
+
\"\"\"Install local wheel files if they exist.\"\"\"
|
|
314
|
+
wheels_dir = Path(__file__).resolve().parent / 'wheels'
|
|
315
|
+
if wheels_dir.exists() and wheels_dir.is_dir():
|
|
316
|
+
wheel_files = list(wheels_dir.glob('*.whl'))
|
|
317
|
+
if wheel_files:
|
|
318
|
+
print(f'[deploy_starter] Installing {{len(wheel_files)}} local wheel(s)...')
|
|
319
|
+
for wheel in wheel_files:
|
|
320
|
+
try:
|
|
321
|
+
subprocess.run(
|
|
322
|
+
['pip', 'install', '--no-deps', str(wheel)],
|
|
323
|
+
check=True,
|
|
324
|
+
capture_output=True,
|
|
325
|
+
)
|
|
326
|
+
print(f'[deploy_starter] Installed: {{wheel.name}}')
|
|
327
|
+
except subprocess.CalledProcessError as e:
|
|
328
|
+
print(f'[deploy_starter] Warning: Failed to install {{wheel.name}}: {{e}}', file=sys.stderr)
|
|
329
|
+
|
|
330
|
+
|
|
251
331
|
def main():
|
|
332
|
+
# Install local wheels first
|
|
333
|
+
install_local_wheels()
|
|
334
|
+
|
|
252
335
|
cfg = read_config()
|
|
253
336
|
subdir = cfg.get('APP_SUBDIR_NAME')
|
|
254
337
|
if not subdir:
|
|
@@ -336,6 +419,23 @@ APP_SUBDIR_NAME: "{project_basename}"
|
|
|
336
419
|
|
|
337
420
|
setup_py = f"""
|
|
338
421
|
from setuptools import setup, find_packages
|
|
422
|
+
import os
|
|
423
|
+
import subprocess
|
|
424
|
+
import sys
|
|
425
|
+
from pathlib import Path
|
|
426
|
+
from setuptools import setup, find_packages
|
|
427
|
+
from setuptools.command.install import install
|
|
428
|
+
|
|
429
|
+
def run():
|
|
430
|
+
# Step 1: Install all .whl files in the ./wheel/ directory (relative to setup.py)
|
|
431
|
+
wheel_dir = Path(__file__).parent / "wheel"
|
|
432
|
+
if wheel_dir.is_dir():
|
|
433
|
+
whl_files = sorted(wheel_dir.glob("*.whl"))
|
|
434
|
+
if whl_files:
|
|
435
|
+
for whl in whl_files:
|
|
436
|
+
# Use the same Python interpreter to avoid env issues
|
|
437
|
+
subprocess.check_call([sys.executable, "-m", "pip", "install", str(whl)])
|
|
438
|
+
|
|
339
439
|
|
|
340
440
|
setup(
|
|
341
441
|
name='{package_name}',
|
|
@@ -350,13 +450,14 @@ setup(
|
|
|
350
450
|
manifest_in = """
|
|
351
451
|
recursive-include deploy_starter *.yml
|
|
352
452
|
recursive-include deploy_starter/user_bundle *
|
|
453
|
+
recursive-include deploy_starter/wheels *.whl
|
|
353
454
|
"""
|
|
354
455
|
_write_file(wrapper_dir / "MANIFEST.in", manifest_in)
|
|
355
456
|
|
|
356
457
|
return wrapper_dir, wrapper_dir / "dist"
|
|
357
458
|
|
|
358
459
|
|
|
359
|
-
|
|
460
|
+
def build_wheel(project_dir: Path) -> Path:
|
|
360
461
|
"""
|
|
361
462
|
Build a wheel inside an isolated virtual environment to avoid PEP 668
|
|
362
463
|
issues. Returns the path to the built wheel.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# pylint: disable=unused-argument
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
from agentscope_runtime.engine import Runner
|
|
6
|
+
from agentscope_runtime.engine.schemas.agent_schemas import (
|
|
7
|
+
AgentRequest,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class SimpleRunner(Runner):
|
|
14
|
+
def __init__(self) -> None:
|
|
15
|
+
super().__init__()
|
|
16
|
+
self.framework_type = "text"
|
|
17
|
+
|
|
18
|
+
async def query_handler(
|
|
19
|
+
self,
|
|
20
|
+
request: AgentRequest = None,
|
|
21
|
+
**kwargs,
|
|
22
|
+
):
|
|
23
|
+
print(request)
|
|
24
|
+
yield "Hi"
|
|
25
|
+
yield "! My name is Friday"
|
|
26
|
+
yield "."
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ErrorRunner(Runner):
|
|
30
|
+
def __init__(self) -> None:
|
|
31
|
+
super().__init__()
|
|
32
|
+
self.framework_type = "text"
|
|
33
|
+
|
|
34
|
+
async def query_handler(
|
|
35
|
+
self,
|
|
36
|
+
request: AgentRequest = None,
|
|
37
|
+
**kwargs,
|
|
38
|
+
):
|
|
39
|
+
yield "Hi"
|
|
40
|
+
raise RuntimeError("Error")
|