agentscope-runtime 1.0.4__py3-none-any.whl → 1.0.5__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/agentscope/stream.py +1 -1
- agentscope_runtime/adapters/langgraph/stream.py +120 -70
- agentscope_runtime/cli/commands/deploy.py +465 -1
- agentscope_runtime/cli/commands/stop.py +16 -0
- agentscope_runtime/common/container_clients/__init__.py +52 -0
- agentscope_runtime/common/container_clients/agentrun_client.py +6 -4
- agentscope_runtime/common/container_clients/boxlite_client.py +442 -0
- agentscope_runtime/common/container_clients/docker_client.py +0 -20
- agentscope_runtime/common/container_clients/fc_client.py +6 -4
- agentscope_runtime/common/container_clients/gvisor_client.py +38 -0
- agentscope_runtime/common/container_clients/knative_client.py +1 -0
- agentscope_runtime/common/utils/deprecation.py +164 -0
- agentscope_runtime/engine/app/agent_app.py +16 -4
- agentscope_runtime/engine/deployers/__init__.py +31 -20
- agentscope_runtime/engine/deployers/adapter/__init__.py +8 -0
- agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +9 -8
- agentscope_runtime/engine/deployers/adapter/a2a/nacos_a2a_registry.py +19 -1
- agentscope_runtime/engine/deployers/adapter/agui/__init__.py +8 -0
- agentscope_runtime/engine/deployers/adapter/agui/agui_adapter_utils.py +652 -0
- agentscope_runtime/engine/deployers/adapter/agui/agui_protocol_adapter.py +225 -0
- agentscope_runtime/engine/deployers/pai_deployer.py +2335 -0
- agentscope_runtime/engine/deployers/utils/net_utils.py +37 -0
- agentscope_runtime/engine/deployers/utils/oss_utils.py +38 -0
- agentscope_runtime/engine/deployers/utils/package.py +46 -42
- agentscope_runtime/engine/helpers/agent_api_client.py +372 -0
- agentscope_runtime/engine/runner.py +1 -0
- agentscope_runtime/engine/schemas/agent_schemas.py +9 -3
- agentscope_runtime/engine/services/agent_state/__init__.py +7 -0
- agentscope_runtime/engine/services/memory/__init__.py +7 -0
- agentscope_runtime/engine/services/memory/redis_memory_service.py +15 -16
- agentscope_runtime/engine/services/session_history/__init__.py +7 -0
- agentscope_runtime/engine/tracing/local_logging_handler.py +2 -3
- agentscope_runtime/sandbox/box/sandbox.py +4 -0
- agentscope_runtime/sandbox/manager/sandbox_manager.py +11 -25
- agentscope_runtime/sandbox/manager/server/config.py +3 -1
- agentscope_runtime/sandbox/model/manager_config.py +11 -9
- agentscope_runtime/tools/modelstudio_memory/__init__.py +106 -0
- agentscope_runtime/tools/modelstudio_memory/base.py +220 -0
- agentscope_runtime/tools/modelstudio_memory/config.py +86 -0
- agentscope_runtime/tools/modelstudio_memory/core.py +594 -0
- agentscope_runtime/tools/modelstudio_memory/exceptions.py +60 -0
- agentscope_runtime/tools/modelstudio_memory/schemas.py +253 -0
- agentscope_runtime/version.py +1 -1
- {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/METADATA +101 -62
- {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/RECORD +49 -34
- {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/WHEEL +0 -0
- {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/entry_points.txt +0 -0
- {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/licenses/LICENSE +0 -0
- {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import asyncio
|
|
3
|
+
import json
|
|
4
|
+
import logging
|
|
5
|
+
import traceback
|
|
6
|
+
from typing import Any, AsyncGenerator, Callable, List, Optional
|
|
7
|
+
from uuid import uuid4
|
|
8
|
+
|
|
9
|
+
from ag_ui.core.types import Context, Message, Tool
|
|
10
|
+
from fastapi import FastAPI, HTTPException
|
|
11
|
+
from fastapi.responses import StreamingResponse
|
|
12
|
+
from pydantic import BaseModel, Field
|
|
13
|
+
|
|
14
|
+
from agentscope_runtime.engine.schemas.agent_schemas import AgentRequest, Event
|
|
15
|
+
|
|
16
|
+
from .agui_adapter_utils import (
|
|
17
|
+
AGUIAdapter,
|
|
18
|
+
AGUIEvent,
|
|
19
|
+
AGUIEventType,
|
|
20
|
+
RunErrorEvent,
|
|
21
|
+
)
|
|
22
|
+
from ..protocol_adapter import ProtocolAdapter
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
SSE_HEADERS = {
|
|
27
|
+
"Cache-Control": "no-cache",
|
|
28
|
+
"Connection": "keep-alive",
|
|
29
|
+
"X-Accel-Buffering": "no",
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class FlexibleRunAgentInput(BaseModel):
|
|
34
|
+
"""
|
|
35
|
+
Flexible input for running an agent with optional fields.
|
|
36
|
+
|
|
37
|
+
This is a custom model that relaxes the required constraints from
|
|
38
|
+
the original ag_ui.RunAgentInput, making state, tools, context,
|
|
39
|
+
and forwarded_props optional for better API flexibility.
|
|
40
|
+
|
|
41
|
+
Supports both snake_case (thread_id) and camelCase (threadId) field names.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
thread_id: str = Field(..., alias="threadId")
|
|
45
|
+
run_id: str = Field(..., alias="runId")
|
|
46
|
+
parent_run_id: Optional[str] = Field(None, alias="parentRunId")
|
|
47
|
+
state: Any = None
|
|
48
|
+
messages: List[Message] = Field(default_factory=list)
|
|
49
|
+
tools: List[Tool] = Field(default_factory=list)
|
|
50
|
+
context: List[Context] = Field(default_factory=list)
|
|
51
|
+
forwarded_props: Any = Field(None, alias="forwardedProps")
|
|
52
|
+
|
|
53
|
+
model_config = {
|
|
54
|
+
"extra": "allow",
|
|
55
|
+
"populate_by_name": True,
|
|
56
|
+
"json_schema_extra": {
|
|
57
|
+
"example": {
|
|
58
|
+
"threadId": "thread_123",
|
|
59
|
+
"runId": "run_456",
|
|
60
|
+
"messages": [
|
|
61
|
+
{
|
|
62
|
+
"id": "msg_1",
|
|
63
|
+
"role": "system",
|
|
64
|
+
"content": "You are a helpful assistant.",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"id": "msg_2",
|
|
68
|
+
"role": "user",
|
|
69
|
+
"content": "Hello",
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
"tools": [],
|
|
73
|
+
"context": [],
|
|
74
|
+
"forwardedProps": None,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class AGUIAdaptorConfig(BaseModel):
|
|
81
|
+
"""
|
|
82
|
+
Configuration for AGUI adaptor.
|
|
83
|
+
|
|
84
|
+
Attributes:
|
|
85
|
+
route_path: The path of the AGUI endpoint.
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
route_path: str = Field(default="/ag-ui")
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class AGUIDefaultAdapter(ProtocolAdapter):
|
|
92
|
+
def __init__(
|
|
93
|
+
self,
|
|
94
|
+
config: Optional[AGUIAdaptorConfig] = None,
|
|
95
|
+
**kwargs,
|
|
96
|
+
) -> None:
|
|
97
|
+
self.config = config or AGUIAdaptorConfig()
|
|
98
|
+
super().__init__(**kwargs)
|
|
99
|
+
self._execution_func: Optional[
|
|
100
|
+
Callable[[AgentRequest], AsyncGenerator[Event, None]]
|
|
101
|
+
] = None
|
|
102
|
+
self._max_concurrent_requests = kwargs.get(
|
|
103
|
+
"max_concurrent_requests",
|
|
104
|
+
100,
|
|
105
|
+
)
|
|
106
|
+
self._semaphore = asyncio.Semaphore(self._max_concurrent_requests)
|
|
107
|
+
|
|
108
|
+
async def _handle_requests(
|
|
109
|
+
self,
|
|
110
|
+
agent_run_input: FlexibleRunAgentInput,
|
|
111
|
+
) -> StreamingResponse:
|
|
112
|
+
"""
|
|
113
|
+
Handle AG-UI streaming request.
|
|
114
|
+
"""
|
|
115
|
+
await self._semaphore.acquire()
|
|
116
|
+
request_id = f"agui_{uuid4()}"
|
|
117
|
+
logger.info(
|
|
118
|
+
"[AGUI] start request_id=%s, request=%s",
|
|
119
|
+
request_id,
|
|
120
|
+
agent_run_input.model_dump_json(by_alias=True, ensure_ascii=False),
|
|
121
|
+
)
|
|
122
|
+
try:
|
|
123
|
+
return StreamingResponse(
|
|
124
|
+
self._stream_with_semaphore(
|
|
125
|
+
agent_run_input,
|
|
126
|
+
request_id,
|
|
127
|
+
),
|
|
128
|
+
media_type="text/event-stream",
|
|
129
|
+
headers=SSE_HEADERS,
|
|
130
|
+
)
|
|
131
|
+
except HTTPException:
|
|
132
|
+
self._semaphore.release()
|
|
133
|
+
logger.info("[AGUI] end request_id=%s", request_id)
|
|
134
|
+
raise
|
|
135
|
+
except Exception as e:
|
|
136
|
+
logger.error(
|
|
137
|
+
f"Unexpected error in _handle_requests: {e}\n"
|
|
138
|
+
f"{traceback.format_exc()}",
|
|
139
|
+
)
|
|
140
|
+
self._semaphore.release()
|
|
141
|
+
logger.info("[AGUI] end request_id=%s", request_id)
|
|
142
|
+
raise HTTPException(
|
|
143
|
+
status_code=500,
|
|
144
|
+
detail="Internal server error",
|
|
145
|
+
) from e
|
|
146
|
+
|
|
147
|
+
def as_sse_data(self, event: AGUIEvent) -> str:
|
|
148
|
+
data = event.model_dump(
|
|
149
|
+
mode="json",
|
|
150
|
+
exclude_none=True,
|
|
151
|
+
by_alias=True,
|
|
152
|
+
)
|
|
153
|
+
return f"data: {json.dumps(data, ensure_ascii=False)}\n\n"
|
|
154
|
+
|
|
155
|
+
async def _generate_stream_response(
|
|
156
|
+
self,
|
|
157
|
+
request: FlexibleRunAgentInput,
|
|
158
|
+
):
|
|
159
|
+
assert self._execution_func is not None
|
|
160
|
+
adapter = AGUIAdapter(
|
|
161
|
+
thread_id=request.thread_id,
|
|
162
|
+
run_id=request.run_id,
|
|
163
|
+
)
|
|
164
|
+
try:
|
|
165
|
+
agent_request = adapter.convert_agui_request_to_agent_request(
|
|
166
|
+
request,
|
|
167
|
+
)
|
|
168
|
+
async for event in self._execution_func(agent_request):
|
|
169
|
+
logger.debug(
|
|
170
|
+
"Streaming Agent API Event: %s",
|
|
171
|
+
event.model_dump(),
|
|
172
|
+
)
|
|
173
|
+
agui_events = adapter.convert_agent_event_to_agui_events(event)
|
|
174
|
+
for agui_event in agui_events:
|
|
175
|
+
yield self.as_sse_data(agui_event)
|
|
176
|
+
|
|
177
|
+
if not adapter.run_finished_emitted:
|
|
178
|
+
# pylint: disable=protected-access
|
|
179
|
+
adapter._run_finished_emitted = True
|
|
180
|
+
yield self.as_sse_data(
|
|
181
|
+
adapter.build_run_event(
|
|
182
|
+
event_type=AGUIEventType.RUN_FINISHED,
|
|
183
|
+
),
|
|
184
|
+
)
|
|
185
|
+
except Exception as e:
|
|
186
|
+
logger.error(
|
|
187
|
+
f"AG-UI stream failed: {e}\n{traceback.format_exc()}",
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
error_event = RunErrorEvent(
|
|
191
|
+
message=f"Unexpected stream error: {e}",
|
|
192
|
+
code="unexpected_stream_error",
|
|
193
|
+
).model_dump(
|
|
194
|
+
mode="json",
|
|
195
|
+
exclude_none=True,
|
|
196
|
+
)
|
|
197
|
+
yield f"data: {json.dumps(error_event, ensure_ascii=False)}\n\n"
|
|
198
|
+
return
|
|
199
|
+
|
|
200
|
+
async def _stream_with_semaphore(
|
|
201
|
+
self,
|
|
202
|
+
request: FlexibleRunAgentInput,
|
|
203
|
+
request_id: str,
|
|
204
|
+
):
|
|
205
|
+
try:
|
|
206
|
+
async for chunk in self._generate_stream_response(request):
|
|
207
|
+
yield chunk
|
|
208
|
+
finally:
|
|
209
|
+
self._semaphore.release()
|
|
210
|
+
logger.info("[AGUI] end request_id=%s", request_id)
|
|
211
|
+
|
|
212
|
+
def add_endpoint(self, app: FastAPI, func, **kwargs) -> Any:
|
|
213
|
+
"""
|
|
214
|
+
Add AG-UI endpoint to FastAPI app.
|
|
215
|
+
"""
|
|
216
|
+
self._execution_func = func
|
|
217
|
+
app.add_api_route(
|
|
218
|
+
self.config.route_path,
|
|
219
|
+
self._handle_requests,
|
|
220
|
+
methods=["POST"],
|
|
221
|
+
tags=[
|
|
222
|
+
"ag-ui",
|
|
223
|
+
],
|
|
224
|
+
)
|
|
225
|
+
return app
|