agentscope-runtime 0.1.5b1__py3-none-any.whl → 0.1.6__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/engine/agents/agentscope_agent.py +447 -0
- agentscope_runtime/engine/agents/agno_agent.py +19 -18
- agentscope_runtime/engine/agents/autogen_agent.py +13 -8
- agentscope_runtime/engine/agents/utils.py +53 -0
- agentscope_runtime/engine/deployers/__init__.py +0 -13
- agentscope_runtime/engine/deployers/local_deployer.py +501 -356
- agentscope_runtime/engine/helpers/helper.py +60 -41
- agentscope_runtime/engine/runner.py +11 -36
- agentscope_runtime/engine/schemas/agent_schemas.py +2 -70
- agentscope_runtime/engine/services/sandbox_service.py +62 -70
- agentscope_runtime/engine/services/tablestore_memory_service.py +304 -0
- agentscope_runtime/engine/services/tablestore_rag_service.py +143 -0
- agentscope_runtime/engine/services/tablestore_session_history_service.py +293 -0
- agentscope_runtime/engine/services/utils/tablestore_service_utils.py +352 -0
- agentscope_runtime/sandbox/__init__.py +2 -0
- agentscope_runtime/sandbox/box/base/__init__.py +4 -0
- agentscope_runtime/sandbox/box/base/base_sandbox.py +4 -3
- agentscope_runtime/sandbox/box/browser/__init__.py +4 -0
- agentscope_runtime/sandbox/box/browser/browser_sandbox.py +8 -13
- agentscope_runtime/sandbox/box/dummy/__init__.py +4 -0
- agentscope_runtime/sandbox/box/filesystem/__init__.py +4 -0
- agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +8 -6
- agentscope_runtime/sandbox/box/gui/__init__.py +4 -0
- agentscope_runtime/sandbox/box/gui/gui_sandbox.py +80 -0
- agentscope_runtime/sandbox/box/sandbox.py +5 -2
- agentscope_runtime/sandbox/box/shared/routers/generic.py +20 -1
- agentscope_runtime/sandbox/box/training_box/__init__.py +4 -0
- agentscope_runtime/sandbox/box/training_box/training_box.py +10 -15
- agentscope_runtime/sandbox/build.py +143 -58
- agentscope_runtime/sandbox/client/http_client.py +43 -49
- agentscope_runtime/sandbox/client/training_client.py +0 -1
- agentscope_runtime/sandbox/constant.py +24 -1
- agentscope_runtime/sandbox/custom/custom_sandbox.py +5 -5
- agentscope_runtime/sandbox/custom/example.py +2 -2
- agentscope_runtime/sandbox/enums.py +1 -0
- agentscope_runtime/sandbox/manager/collections/in_memory_mapping.py +11 -6
- agentscope_runtime/sandbox/manager/collections/redis_mapping.py +25 -9
- agentscope_runtime/sandbox/manager/container_clients/__init__.py +0 -10
- agentscope_runtime/sandbox/manager/container_clients/agentrun_client.py +1098 -0
- agentscope_runtime/sandbox/manager/container_clients/docker_client.py +33 -205
- agentscope_runtime/sandbox/manager/container_clients/kubernetes_client.py +8 -555
- agentscope_runtime/sandbox/manager/sandbox_manager.py +187 -88
- agentscope_runtime/sandbox/manager/server/app.py +82 -14
- agentscope_runtime/sandbox/manager/server/config.py +50 -3
- agentscope_runtime/sandbox/model/container.py +6 -23
- agentscope_runtime/sandbox/model/manager_config.py +93 -5
- agentscope_runtime/sandbox/tools/gui/__init__.py +7 -0
- agentscope_runtime/sandbox/tools/gui/tool.py +77 -0
- agentscope_runtime/sandbox/tools/mcp_tool.py +6 -2
- agentscope_runtime/sandbox/utils.py +124 -0
- agentscope_runtime/version.py +1 -1
- {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/METADATA +168 -77
- {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/RECORD +59 -78
- {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/entry_points.txt +0 -1
- agentscope_runtime/engine/agents/agentscope_agent/__init__.py +0 -6
- agentscope_runtime/engine/agents/agentscope_agent/agent.py +0 -401
- agentscope_runtime/engine/agents/agentscope_agent/hooks.py +0 -169
- agentscope_runtime/engine/agents/llm_agent.py +0 -51
- agentscope_runtime/engine/deployers/adapter/responses/response_api_adapter_utils.py +0 -2886
- agentscope_runtime/engine/deployers/adapter/responses/response_api_agent_adapter.py +0 -51
- agentscope_runtime/engine/deployers/adapter/responses/response_api_protocol_adapter.py +0 -314
- agentscope_runtime/engine/deployers/cli_fc_deploy.py +0 -143
- agentscope_runtime/engine/deployers/kubernetes_deployer.py +0 -265
- agentscope_runtime/engine/deployers/modelstudio_deployer.py +0 -626
- agentscope_runtime/engine/deployers/utils/deployment_modes.py +0 -14
- agentscope_runtime/engine/deployers/utils/docker_image_utils/__init__.py +0 -8
- agentscope_runtime/engine/deployers/utils/docker_image_utils/docker_image_builder.py +0 -429
- agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +0 -240
- agentscope_runtime/engine/deployers/utils/docker_image_utils/runner_image_factory.py +0 -297
- agentscope_runtime/engine/deployers/utils/package_project_utils.py +0 -932
- agentscope_runtime/engine/deployers/utils/service_utils/__init__.py +0 -9
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +0 -504
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_templates.py +0 -157
- agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +0 -268
- 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/deployers/utils/wheel_packager.py +0 -389
- agentscope_runtime/engine/helpers/agent_api_builder.py +0 -651
- agentscope_runtime/engine/llms/__init__.py +0 -3
- agentscope_runtime/engine/llms/base_llm.py +0 -60
- agentscope_runtime/engine/llms/qwen_llm.py +0 -47
- agentscope_runtime/engine/schemas/embedding.py +0 -37
- agentscope_runtime/engine/schemas/modelstudio_llm.py +0 -310
- agentscope_runtime/engine/schemas/oai_llm.py +0 -538
- agentscope_runtime/engine/schemas/realtime.py +0 -254
- /agentscope_runtime/engine/{deployers/adapter/responses → services/utils}/__init__.py +0 -0
- /agentscope_runtime/{engine/deployers/utils → sandbox/box/gui/box}/__init__.py +0 -0
- {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/WHEEL +0 -0
- {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/licenses/LICENSE +0 -0
- {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/top_level.txt +0 -0
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
# pylint: disable=unused-argument,line-too-long
|
|
3
|
-
import logging
|
|
4
|
-
import traceback
|
|
5
|
-
from typing import Callable, Dict
|
|
6
|
-
|
|
7
|
-
from agentscope_runtime.engine.deployers.adapter.responses.response_api_adapter_utils import ( # noqa: E501
|
|
8
|
-
ResponsesAdapter,
|
|
9
|
-
)
|
|
10
|
-
|
|
11
|
-
logger = logging.getLogger(__name__)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class ResponseAPIExecutor:
|
|
15
|
-
def __init__(self, func: Callable, **kwargs):
|
|
16
|
-
self._func = func
|
|
17
|
-
|
|
18
|
-
async def execute(
|
|
19
|
-
self,
|
|
20
|
-
request: Dict,
|
|
21
|
-
):
|
|
22
|
-
# Start executing agent
|
|
23
|
-
sequence_counter = 0
|
|
24
|
-
responses_adapter = ResponsesAdapter()
|
|
25
|
-
|
|
26
|
-
# Convert input parameters to agent api
|
|
27
|
-
agent_request = (
|
|
28
|
-
responses_adapter.convert_responses_request_to_agent_request(
|
|
29
|
-
request,
|
|
30
|
-
)
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
try:
|
|
34
|
-
async for event in self._func(request=agent_request):
|
|
35
|
-
# Convert Agent API events to Responses API events
|
|
36
|
-
responses_event = (
|
|
37
|
-
responses_adapter.convert_agent_event_to_responses_event(
|
|
38
|
-
event,
|
|
39
|
-
)
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
event_count = 0
|
|
43
|
-
if responses_event:
|
|
44
|
-
for event in responses_event:
|
|
45
|
-
# Uniformly set sequence_number
|
|
46
|
-
event.sequence_number = sequence_counter
|
|
47
|
-
sequence_counter += 1
|
|
48
|
-
event_count += 1
|
|
49
|
-
yield event
|
|
50
|
-
except Exception as e:
|
|
51
|
-
logger.error(f"An error occurred: {e}, {traceback.format_exc()}")
|
|
@@ -1,314 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
import asyncio
|
|
3
|
-
import json
|
|
4
|
-
import logging
|
|
5
|
-
import traceback
|
|
6
|
-
from typing import Callable, Dict, Any, Optional, AsyncGenerator
|
|
7
|
-
from uuid import uuid4
|
|
8
|
-
|
|
9
|
-
from fastapi import FastAPI, Request, HTTPException
|
|
10
|
-
from fastapi.responses import StreamingResponse, JSONResponse
|
|
11
|
-
|
|
12
|
-
# OpenAI Response API official type definition
|
|
13
|
-
from openai.types.responses import ResponseCreateParams
|
|
14
|
-
|
|
15
|
-
from .response_api_adapter_utils import ResponsesAdapter
|
|
16
|
-
from .response_api_agent_adapter import ResponseAPIExecutor
|
|
17
|
-
from ..protocol_adapter import ProtocolAdapter
|
|
18
|
-
from ....schemas.agent_schemas import AgentRequest, BaseResponse
|
|
19
|
-
|
|
20
|
-
logger = logging.getLogger(__name__)
|
|
21
|
-
|
|
22
|
-
RESPONSES_ENDPOINT_PATH = "/compatible-mode/v1/responses"
|
|
23
|
-
SSE_HEADERS = {
|
|
24
|
-
"Cache-Control": "no-cache",
|
|
25
|
-
"Connection": "keep-alive",
|
|
26
|
-
"X-Accel-Buffering": "no", # disable Nginx buffering
|
|
27
|
-
"Access-Control-Allow-Origin": "*",
|
|
28
|
-
"Access-Control-Allow-Methods": "POST, OPTIONS",
|
|
29
|
-
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
class ResponseAPIDefaultAdapter(ProtocolAdapter):
|
|
34
|
-
def __init__(self, **kwargs):
|
|
35
|
-
super().__init__(**kwargs)
|
|
36
|
-
self._executor: Optional[ResponseAPIExecutor] = None
|
|
37
|
-
self._timeout = kwargs.get("timeout", 300) # seconds
|
|
38
|
-
self._max_concurrent_requests = kwargs.get(
|
|
39
|
-
"max_concurrent_requests",
|
|
40
|
-
100,
|
|
41
|
-
)
|
|
42
|
-
self._semaphore = asyncio.Semaphore(self._max_concurrent_requests)
|
|
43
|
-
|
|
44
|
-
async def _handle_requests(self, request: Request) -> StreamingResponse:
|
|
45
|
-
"""
|
|
46
|
-
Handle OpenAI Response API request.
|
|
47
|
-
|
|
48
|
-
Args:
|
|
49
|
-
request: FastAPI Request object
|
|
50
|
-
|
|
51
|
-
Returns:
|
|
52
|
-
StreamingResponse: SSE streaming response
|
|
53
|
-
"""
|
|
54
|
-
# Concurrency guard per request
|
|
55
|
-
await self._semaphore.acquire()
|
|
56
|
-
request_id = f"resp_{uuid4()}"
|
|
57
|
-
logger.info("[ResponseAPI] start request_id=%s", request_id)
|
|
58
|
-
try:
|
|
59
|
-
# Parse request body
|
|
60
|
-
request_data = await request.json()
|
|
61
|
-
|
|
62
|
-
stream = request_data.get("stream", False)
|
|
63
|
-
|
|
64
|
-
# Stream or non-stream
|
|
65
|
-
if stream:
|
|
66
|
-
# Return SSE streaming response with timeout control
|
|
67
|
-
return StreamingResponse(
|
|
68
|
-
self._generate_stream_response_with_timeout(
|
|
69
|
-
request=request_data,
|
|
70
|
-
request_id=request_id,
|
|
71
|
-
),
|
|
72
|
-
media_type="text/event-stream",
|
|
73
|
-
headers=SSE_HEADERS,
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
# Non-stream JSON response
|
|
77
|
-
response_obj = await self._collect_non_stream_response(
|
|
78
|
-
request=request_data,
|
|
79
|
-
request_id=request_id,
|
|
80
|
-
)
|
|
81
|
-
return JSONResponse(content=response_obj)
|
|
82
|
-
|
|
83
|
-
except HTTPException:
|
|
84
|
-
raise
|
|
85
|
-
except Exception as e:
|
|
86
|
-
logger.error(
|
|
87
|
-
f"Unexpected error in _handle_requests: {e}\n"
|
|
88
|
-
f"{traceback.format_exc()}",
|
|
89
|
-
)
|
|
90
|
-
raise HTTPException(
|
|
91
|
-
status_code=500,
|
|
92
|
-
detail="Internal server error",
|
|
93
|
-
) from e
|
|
94
|
-
finally:
|
|
95
|
-
self._semaphore.release()
|
|
96
|
-
logger.info("[ResponseAPI] end request_id=%s", request_id)
|
|
97
|
-
|
|
98
|
-
def _convert_response_request_to_agent_request(
|
|
99
|
-
self,
|
|
100
|
-
response_request: ResponseCreateParams,
|
|
101
|
-
) -> AgentRequest:
|
|
102
|
-
"""
|
|
103
|
-
Convert an OpenAI Response API request to Agent API request.
|
|
104
|
-
|
|
105
|
-
Args:
|
|
106
|
-
response_request: OpenAI Response API request
|
|
107
|
-
|
|
108
|
-
Returns:
|
|
109
|
-
AgentRequest: Agent API request
|
|
110
|
-
"""
|
|
111
|
-
# Convert with ResponsesAdapter
|
|
112
|
-
adapter = ResponsesAdapter()
|
|
113
|
-
agent_request = adapter.convert_responses_request_to_agent_request(
|
|
114
|
-
response_request.model_dump(),
|
|
115
|
-
)
|
|
116
|
-
|
|
117
|
-
return agent_request
|
|
118
|
-
|
|
119
|
-
async def _collect_non_stream_response(
|
|
120
|
-
self,
|
|
121
|
-
request: Dict,
|
|
122
|
-
request_id: str,
|
|
123
|
-
) -> Dict[str, Any]:
|
|
124
|
-
"""
|
|
125
|
-
Run the agent and build a non-streaming OpenAI Responses API object.
|
|
126
|
-
|
|
127
|
-
This collects events until completion and returns a single JSON object
|
|
128
|
-
representing the final response.
|
|
129
|
-
"""
|
|
130
|
-
last_agent_response: Optional[BaseResponse] = None
|
|
131
|
-
try:
|
|
132
|
-
async for event in self._executor.execute(request):
|
|
133
|
-
last_agent_response = event
|
|
134
|
-
except Exception:
|
|
135
|
-
# Map to Responses error shape
|
|
136
|
-
return {
|
|
137
|
-
"id": request_id,
|
|
138
|
-
"object": "response",
|
|
139
|
-
"status": "failed",
|
|
140
|
-
"error": {
|
|
141
|
-
"code": "non_stream_error",
|
|
142
|
-
"message": "Failed to build non-stream response",
|
|
143
|
-
},
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if not last_agent_response:
|
|
147
|
-
# No response produced
|
|
148
|
-
return {
|
|
149
|
-
"id": request_id,
|
|
150
|
-
"object": "response",
|
|
151
|
-
"status": "failed",
|
|
152
|
-
"error": {
|
|
153
|
-
"code": "empty_response",
|
|
154
|
-
"message": "No response produced by agent",
|
|
155
|
-
},
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
# Convert to dict for JSONResponse
|
|
159
|
-
return last_agent_response.model_dump(exclude_none=True)
|
|
160
|
-
|
|
161
|
-
async def _generate_stream_response_with_timeout(
|
|
162
|
-
self,
|
|
163
|
-
request: Dict,
|
|
164
|
-
request_id: str,
|
|
165
|
-
) -> AsyncGenerator[str, None]:
|
|
166
|
-
"""
|
|
167
|
-
Generate SSE streaming response with timeout.
|
|
168
|
-
|
|
169
|
-
Args:
|
|
170
|
-
agent_request: Agent API request
|
|
171
|
-
|
|
172
|
-
Yields:
|
|
173
|
-
str: SSE data chunks
|
|
174
|
-
"""
|
|
175
|
-
try:
|
|
176
|
-
# Add timeout with asyncio.wait_for
|
|
177
|
-
async for chunk in self._generate_stream_response(
|
|
178
|
-
request=request,
|
|
179
|
-
request_id=request_id,
|
|
180
|
-
):
|
|
181
|
-
yield chunk
|
|
182
|
-
except asyncio.TimeoutError:
|
|
183
|
-
logger.error(f"Request timeout after {self._timeout} seconds")
|
|
184
|
-
# Send timeout error event
|
|
185
|
-
timeout_event = {
|
|
186
|
-
"id": request_id,
|
|
187
|
-
"object": "response",
|
|
188
|
-
"status": "failed",
|
|
189
|
-
"error": {
|
|
190
|
-
"code": "timeout",
|
|
191
|
-
"message": f"Request timed out after "
|
|
192
|
-
f"{self._timeout} seconds",
|
|
193
|
-
},
|
|
194
|
-
}
|
|
195
|
-
yield (
|
|
196
|
-
f"event: response.failed\n"
|
|
197
|
-
f"data: {json.dumps(timeout_event)}\n\n"
|
|
198
|
-
)
|
|
199
|
-
except Exception as e:
|
|
200
|
-
logger.error(
|
|
201
|
-
f"Error in timeout-controlled stream: {e}\n"
|
|
202
|
-
f"{traceback.format_exc()}",
|
|
203
|
-
)
|
|
204
|
-
# Send error event
|
|
205
|
-
error_event = {
|
|
206
|
-
"id": request_id,
|
|
207
|
-
"object": "response",
|
|
208
|
-
"status": "failed",
|
|
209
|
-
"error": {
|
|
210
|
-
"code": "stream_error",
|
|
211
|
-
"message": str(e),
|
|
212
|
-
},
|
|
213
|
-
}
|
|
214
|
-
yield (
|
|
215
|
-
f"event: response.failed\n"
|
|
216
|
-
f"data: {json.dumps(error_event)}\n\n"
|
|
217
|
-
)
|
|
218
|
-
|
|
219
|
-
async def _generate_stream_response(
|
|
220
|
-
self,
|
|
221
|
-
request: Dict,
|
|
222
|
-
request_id: str,
|
|
223
|
-
) -> AsyncGenerator[str, None]:
|
|
224
|
-
"""
|
|
225
|
-
Generate SSE streaming response.
|
|
226
|
-
|
|
227
|
-
Args:
|
|
228
|
-
request: Responses API request
|
|
229
|
-
|
|
230
|
-
Yields:
|
|
231
|
-
str: SSE data chunks
|
|
232
|
-
"""
|
|
233
|
-
try:
|
|
234
|
-
# Handle streaming events
|
|
235
|
-
async for event in self._executor.execute(request):
|
|
236
|
-
try:
|
|
237
|
-
if event:
|
|
238
|
-
# Serialize event
|
|
239
|
-
event_data = event.model_dump(exclude_none=True)
|
|
240
|
-
data = json.dumps(event_data, ensure_ascii=False)
|
|
241
|
-
|
|
242
|
-
# Set SSE event type based on event type
|
|
243
|
-
event_type = event_data.get("type", "message")
|
|
244
|
-
yield f"event: {event_type}\ndata: {data}\n\n"
|
|
245
|
-
|
|
246
|
-
except Exception as e:
|
|
247
|
-
logger.error(
|
|
248
|
-
f"Error processing event: {e}\n"
|
|
249
|
-
f"{traceback.format_exc()}",
|
|
250
|
-
)
|
|
251
|
-
# Send error event
|
|
252
|
-
error_event = {
|
|
253
|
-
"id": request_id,
|
|
254
|
-
"object": "response",
|
|
255
|
-
"status": "failed",
|
|
256
|
-
"error": {
|
|
257
|
-
"code": "processing_error",
|
|
258
|
-
"message": str(e),
|
|
259
|
-
},
|
|
260
|
-
}
|
|
261
|
-
yield (
|
|
262
|
-
f"event: response.failed\n"
|
|
263
|
-
f"data: {json.dumps(error_event)}\n\n"
|
|
264
|
-
)
|
|
265
|
-
break
|
|
266
|
-
except Exception as e:
|
|
267
|
-
logger.error(
|
|
268
|
-
f"Error in stream generation: {e}\n{traceback.format_exc()}",
|
|
269
|
-
)
|
|
270
|
-
# Send error event
|
|
271
|
-
error_event = {
|
|
272
|
-
"id": request_id,
|
|
273
|
-
"object": "response",
|
|
274
|
-
"status": "failed",
|
|
275
|
-
"error": {
|
|
276
|
-
"code": "stream_error",
|
|
277
|
-
"message": str(e),
|
|
278
|
-
},
|
|
279
|
-
}
|
|
280
|
-
yield (
|
|
281
|
-
f"event: response.failed\n"
|
|
282
|
-
f"data: {json.dumps(error_event)}\n\n"
|
|
283
|
-
)
|
|
284
|
-
|
|
285
|
-
def add_endpoint(self, app: FastAPI, func: Callable, **kwargs) -> None:
|
|
286
|
-
"""
|
|
287
|
-
Add endpoint to FastAPI app.
|
|
288
|
-
|
|
289
|
-
Args:
|
|
290
|
-
app: FastAPI application instance
|
|
291
|
-
func: handler function
|
|
292
|
-
**kwargs: extra options
|
|
293
|
-
"""
|
|
294
|
-
# Create executor
|
|
295
|
-
self._executor = ResponseAPIExecutor(func=func)
|
|
296
|
-
|
|
297
|
-
# Register route
|
|
298
|
-
app.post(
|
|
299
|
-
RESPONSES_ENDPOINT_PATH,
|
|
300
|
-
openapi_extra={
|
|
301
|
-
"requestBody": {
|
|
302
|
-
"content": {
|
|
303
|
-
"application/json": {
|
|
304
|
-
"schema": {
|
|
305
|
-
"$ref": "#/components/schemas/ResponseAPI",
|
|
306
|
-
},
|
|
307
|
-
},
|
|
308
|
-
},
|
|
309
|
-
"required": True,
|
|
310
|
-
"description": "OpenAI Response API compatible "
|
|
311
|
-
"request format",
|
|
312
|
-
},
|
|
313
|
-
},
|
|
314
|
-
)(self._handle_requests)
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
import argparse
|
|
3
|
-
import asyncio
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
from typing import Optional
|
|
6
|
-
|
|
7
|
-
from .modelstudio_deployer import ModelstudioDeployManager
|
|
8
|
-
from .utils.wheel_packager import build_wheel
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def _parse_args() -> argparse.Namespace:
|
|
12
|
-
parser = argparse.ArgumentParser(
|
|
13
|
-
description="One-click deploy your service to Alibaba Bailian "
|
|
14
|
-
"Function Compute (FC)",
|
|
15
|
-
)
|
|
16
|
-
parser.add_argument(
|
|
17
|
-
"--mode",
|
|
18
|
-
choices=["wrapper", "native"],
|
|
19
|
-
default="wrapper",
|
|
20
|
-
help="Build mode: wrapper (default) packages your project into a "
|
|
21
|
-
"starter; native builds your current project directly.",
|
|
22
|
-
)
|
|
23
|
-
parser.add_argument(
|
|
24
|
-
"--whl-path",
|
|
25
|
-
dest="whl_path",
|
|
26
|
-
default=None,
|
|
27
|
-
help="Path to an external wheel file to deploy directly (skip build)",
|
|
28
|
-
)
|
|
29
|
-
parser.add_argument(
|
|
30
|
-
"--dir",
|
|
31
|
-
default=None,
|
|
32
|
-
help="Path to your project directory (wrapper mode)",
|
|
33
|
-
)
|
|
34
|
-
parser.add_argument(
|
|
35
|
-
"--cmd",
|
|
36
|
-
default=None,
|
|
37
|
-
help="Command to start your service (wrapper mode), e.g., 'python "
|
|
38
|
-
"app.py'",
|
|
39
|
-
)
|
|
40
|
-
parser.add_argument(
|
|
41
|
-
"--deploy-name",
|
|
42
|
-
dest="deploy_name",
|
|
43
|
-
default=None,
|
|
44
|
-
help="Deploy name (agent_name). Random if omitted",
|
|
45
|
-
)
|
|
46
|
-
parser.add_argument(
|
|
47
|
-
"--skip-upload",
|
|
48
|
-
action="store_true",
|
|
49
|
-
help="Only build wheel, do not upload/deploy",
|
|
50
|
-
)
|
|
51
|
-
parser.add_argument(
|
|
52
|
-
"--telemetry",
|
|
53
|
-
choices=["enable", "disable"],
|
|
54
|
-
default="enable",
|
|
55
|
-
help="Enable or disable telemetry (default: enable)",
|
|
56
|
-
)
|
|
57
|
-
parser.add_argument(
|
|
58
|
-
"--build-root",
|
|
59
|
-
dest="build_root",
|
|
60
|
-
default=None,
|
|
61
|
-
help="Custom directory for temporary build artifacts (optional)",
|
|
62
|
-
)
|
|
63
|
-
return parser.parse_args()
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
async def _run(
|
|
67
|
-
dir_path: Optional[str],
|
|
68
|
-
cmd: Optional[str],
|
|
69
|
-
deploy_name: Optional[str],
|
|
70
|
-
skip_upload: bool,
|
|
71
|
-
telemetry_enabled: bool,
|
|
72
|
-
build_root: Optional[str],
|
|
73
|
-
mode: str,
|
|
74
|
-
whl_path: Optional[str],
|
|
75
|
-
):
|
|
76
|
-
deployer = ModelstudioDeployManager(build_root=build_root)
|
|
77
|
-
# If a wheel path is provided, skip local build entirely
|
|
78
|
-
if whl_path:
|
|
79
|
-
return await deployer.deploy(
|
|
80
|
-
project_dir=None,
|
|
81
|
-
cmd=None,
|
|
82
|
-
deploy_name=deploy_name,
|
|
83
|
-
skip_upload=skip_upload,
|
|
84
|
-
telemetry_enabled=telemetry_enabled,
|
|
85
|
-
external_whl_path=whl_path,
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
if mode == "native":
|
|
89
|
-
# Build the current project directly as a wheel, then upload/deploy
|
|
90
|
-
project_dir_path = Path.cwd()
|
|
91
|
-
built_whl = await build_wheel(project_dir_path)
|
|
92
|
-
return await deployer.deploy(
|
|
93
|
-
project_dir=None,
|
|
94
|
-
cmd=None,
|
|
95
|
-
deploy_name=deploy_name,
|
|
96
|
-
skip_upload=skip_upload,
|
|
97
|
-
telemetry_enabled=telemetry_enabled,
|
|
98
|
-
external_whl_path=str(built_whl),
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
# wrapper mode (default): require dir and cmd
|
|
102
|
-
if not dir_path or not cmd:
|
|
103
|
-
raise SystemExit(
|
|
104
|
-
"In wrapper mode, --dir and --cmd are required. Alternatively "
|
|
105
|
-
"use --mode native or --whl-path.",
|
|
106
|
-
)
|
|
107
|
-
return await deployer.deploy(
|
|
108
|
-
project_dir=dir_path,
|
|
109
|
-
cmd=cmd,
|
|
110
|
-
deploy_name=deploy_name,
|
|
111
|
-
skip_upload=skip_upload,
|
|
112
|
-
telemetry_enabled=telemetry_enabled,
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
def main() -> None:
|
|
117
|
-
args = _parse_args()
|
|
118
|
-
telemetry_enabled = args.telemetry == "enable"
|
|
119
|
-
result = asyncio.run(
|
|
120
|
-
_run(
|
|
121
|
-
dir_path=args.dir,
|
|
122
|
-
cmd=args.cmd,
|
|
123
|
-
deploy_name=args.deploy_name,
|
|
124
|
-
skip_upload=args.skip_upload,
|
|
125
|
-
telemetry_enabled=telemetry_enabled,
|
|
126
|
-
build_root=args.build_root,
|
|
127
|
-
mode=args.mode,
|
|
128
|
-
whl_path=args.whl_path,
|
|
129
|
-
),
|
|
130
|
-
)
|
|
131
|
-
print("Built wheel at:", result.get("wheel_path", ""))
|
|
132
|
-
if result.get("artifact_url"):
|
|
133
|
-
print("Artifact URL:", result.get("artifact_url"))
|
|
134
|
-
print("Deploy ID:", result.get("deploy_id"))
|
|
135
|
-
print("Resource Name:", result.get("resource_name"))
|
|
136
|
-
if result.get("workspace_id"):
|
|
137
|
-
print("Workspace:", result.get("workspace_id"))
|
|
138
|
-
if result.get("url"):
|
|
139
|
-
print("Console Url:", result.get("url"))
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if __name__ == "__main__": # pragma: no cover
|
|
143
|
-
main()
|