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.
Files changed (49) hide show
  1. agentscope_runtime/adapters/agentscope/stream.py +1 -1
  2. agentscope_runtime/adapters/langgraph/stream.py +120 -70
  3. agentscope_runtime/cli/commands/deploy.py +465 -1
  4. agentscope_runtime/cli/commands/stop.py +16 -0
  5. agentscope_runtime/common/container_clients/__init__.py +52 -0
  6. agentscope_runtime/common/container_clients/agentrun_client.py +6 -4
  7. agentscope_runtime/common/container_clients/boxlite_client.py +442 -0
  8. agentscope_runtime/common/container_clients/docker_client.py +0 -20
  9. agentscope_runtime/common/container_clients/fc_client.py +6 -4
  10. agentscope_runtime/common/container_clients/gvisor_client.py +38 -0
  11. agentscope_runtime/common/container_clients/knative_client.py +1 -0
  12. agentscope_runtime/common/utils/deprecation.py +164 -0
  13. agentscope_runtime/engine/app/agent_app.py +16 -4
  14. agentscope_runtime/engine/deployers/__init__.py +31 -20
  15. agentscope_runtime/engine/deployers/adapter/__init__.py +8 -0
  16. agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +9 -8
  17. agentscope_runtime/engine/deployers/adapter/a2a/nacos_a2a_registry.py +19 -1
  18. agentscope_runtime/engine/deployers/adapter/agui/__init__.py +8 -0
  19. agentscope_runtime/engine/deployers/adapter/agui/agui_adapter_utils.py +652 -0
  20. agentscope_runtime/engine/deployers/adapter/agui/agui_protocol_adapter.py +225 -0
  21. agentscope_runtime/engine/deployers/pai_deployer.py +2335 -0
  22. agentscope_runtime/engine/deployers/utils/net_utils.py +37 -0
  23. agentscope_runtime/engine/deployers/utils/oss_utils.py +38 -0
  24. agentscope_runtime/engine/deployers/utils/package.py +46 -42
  25. agentscope_runtime/engine/helpers/agent_api_client.py +372 -0
  26. agentscope_runtime/engine/runner.py +1 -0
  27. agentscope_runtime/engine/schemas/agent_schemas.py +9 -3
  28. agentscope_runtime/engine/services/agent_state/__init__.py +7 -0
  29. agentscope_runtime/engine/services/memory/__init__.py +7 -0
  30. agentscope_runtime/engine/services/memory/redis_memory_service.py +15 -16
  31. agentscope_runtime/engine/services/session_history/__init__.py +7 -0
  32. agentscope_runtime/engine/tracing/local_logging_handler.py +2 -3
  33. agentscope_runtime/sandbox/box/sandbox.py +4 -0
  34. agentscope_runtime/sandbox/manager/sandbox_manager.py +11 -25
  35. agentscope_runtime/sandbox/manager/server/config.py +3 -1
  36. agentscope_runtime/sandbox/model/manager_config.py +11 -9
  37. agentscope_runtime/tools/modelstudio_memory/__init__.py +106 -0
  38. agentscope_runtime/tools/modelstudio_memory/base.py +220 -0
  39. agentscope_runtime/tools/modelstudio_memory/config.py +86 -0
  40. agentscope_runtime/tools/modelstudio_memory/core.py +594 -0
  41. agentscope_runtime/tools/modelstudio_memory/exceptions.py +60 -0
  42. agentscope_runtime/tools/modelstudio_memory/schemas.py +253 -0
  43. agentscope_runtime/version.py +1 -1
  44. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/METADATA +101 -62
  45. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/RECORD +49 -34
  46. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/WHEEL +0 -0
  47. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/entry_points.txt +0 -0
  48. {agentscope_runtime-1.0.4.dist-info → agentscope_runtime-1.0.5.dist-info}/licenses/LICENSE +0 -0
  49. {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