agentscope-runtime 0.1.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.
Files changed (131) hide show
  1. agentscope_runtime/__init__.py +4 -0
  2. agentscope_runtime/engine/__init__.py +9 -0
  3. agentscope_runtime/engine/agents/__init__.py +2 -0
  4. agentscope_runtime/engine/agents/agentscope_agent/__init__.py +6 -0
  5. agentscope_runtime/engine/agents/agentscope_agent/agent.py +342 -0
  6. agentscope_runtime/engine/agents/agentscope_agent/hooks.py +156 -0
  7. agentscope_runtime/engine/agents/agno_agent.py +220 -0
  8. agentscope_runtime/engine/agents/base_agent.py +29 -0
  9. agentscope_runtime/engine/agents/langgraph_agent.py +59 -0
  10. agentscope_runtime/engine/agents/llm_agent.py +51 -0
  11. agentscope_runtime/engine/deployers/__init__.py +3 -0
  12. agentscope_runtime/engine/deployers/adapter/__init__.py +0 -0
  13. agentscope_runtime/engine/deployers/adapter/a2a/__init__.py +2 -0
  14. agentscope_runtime/engine/deployers/adapter/a2a/a2a_adapter_utils.py +425 -0
  15. agentscope_runtime/engine/deployers/adapter/a2a/a2a_agent_adapter.py +69 -0
  16. agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +60 -0
  17. agentscope_runtime/engine/deployers/adapter/protocol_adapter.py +24 -0
  18. agentscope_runtime/engine/deployers/base.py +17 -0
  19. agentscope_runtime/engine/deployers/local_deployer.py +586 -0
  20. agentscope_runtime/engine/helpers/helper.py +127 -0
  21. agentscope_runtime/engine/llms/__init__.py +3 -0
  22. agentscope_runtime/engine/llms/base_llm.py +60 -0
  23. agentscope_runtime/engine/llms/qwen_llm.py +47 -0
  24. agentscope_runtime/engine/misc/__init__.py +0 -0
  25. agentscope_runtime/engine/runner.py +186 -0
  26. agentscope_runtime/engine/schemas/__init__.py +0 -0
  27. agentscope_runtime/engine/schemas/agent_schemas.py +551 -0
  28. agentscope_runtime/engine/schemas/context.py +54 -0
  29. agentscope_runtime/engine/services/__init__.py +9 -0
  30. agentscope_runtime/engine/services/base.py +77 -0
  31. agentscope_runtime/engine/services/context_manager.py +129 -0
  32. agentscope_runtime/engine/services/environment_manager.py +50 -0
  33. agentscope_runtime/engine/services/manager.py +174 -0
  34. agentscope_runtime/engine/services/memory_service.py +270 -0
  35. agentscope_runtime/engine/services/sandbox_service.py +198 -0
  36. agentscope_runtime/engine/services/session_history_service.py +256 -0
  37. agentscope_runtime/engine/tracing/__init__.py +40 -0
  38. agentscope_runtime/engine/tracing/base.py +309 -0
  39. agentscope_runtime/engine/tracing/local_logging_handler.py +356 -0
  40. agentscope_runtime/engine/tracing/tracing_metric.py +69 -0
  41. agentscope_runtime/engine/tracing/wrapper.py +321 -0
  42. agentscope_runtime/sandbox/__init__.py +14 -0
  43. agentscope_runtime/sandbox/box/__init__.py +0 -0
  44. agentscope_runtime/sandbox/box/base/__init__.py +0 -0
  45. agentscope_runtime/sandbox/box/base/base_sandbox.py +37 -0
  46. agentscope_runtime/sandbox/box/base/box/__init__.py +0 -0
  47. agentscope_runtime/sandbox/box/browser/__init__.py +0 -0
  48. agentscope_runtime/sandbox/box/browser/box/__init__.py +0 -0
  49. agentscope_runtime/sandbox/box/browser/browser_sandbox.py +176 -0
  50. agentscope_runtime/sandbox/box/dummy/__init__.py +0 -0
  51. agentscope_runtime/sandbox/box/dummy/dummy_sandbox.py +26 -0
  52. agentscope_runtime/sandbox/box/filesystem/__init__.py +0 -0
  53. agentscope_runtime/sandbox/box/filesystem/box/__init__.py +0 -0
  54. agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +87 -0
  55. agentscope_runtime/sandbox/box/sandbox.py +115 -0
  56. agentscope_runtime/sandbox/box/shared/__init__.py +0 -0
  57. agentscope_runtime/sandbox/box/shared/app.py +44 -0
  58. agentscope_runtime/sandbox/box/shared/dependencies/__init__.py +5 -0
  59. agentscope_runtime/sandbox/box/shared/dependencies/deps.py +22 -0
  60. agentscope_runtime/sandbox/box/shared/routers/__init__.py +12 -0
  61. agentscope_runtime/sandbox/box/shared/routers/generic.py +173 -0
  62. agentscope_runtime/sandbox/box/shared/routers/mcp.py +207 -0
  63. agentscope_runtime/sandbox/box/shared/routers/mcp_utils.py +153 -0
  64. agentscope_runtime/sandbox/box/shared/routers/runtime_watcher.py +187 -0
  65. agentscope_runtime/sandbox/box/shared/routers/workspace.py +325 -0
  66. agentscope_runtime/sandbox/box/training_box/__init__.py +0 -0
  67. agentscope_runtime/sandbox/box/training_box/base.py +120 -0
  68. agentscope_runtime/sandbox/box/training_box/env_service.py +752 -0
  69. agentscope_runtime/sandbox/box/training_box/environments/__init__.py +0 -0
  70. agentscope_runtime/sandbox/box/training_box/environments/appworld/appworld_env.py +987 -0
  71. agentscope_runtime/sandbox/box/training_box/registry.py +54 -0
  72. agentscope_runtime/sandbox/box/training_box/src/trajectory.py +278 -0
  73. agentscope_runtime/sandbox/box/training_box/training_box.py +219 -0
  74. agentscope_runtime/sandbox/build.py +213 -0
  75. agentscope_runtime/sandbox/client/__init__.py +5 -0
  76. agentscope_runtime/sandbox/client/http_client.py +527 -0
  77. agentscope_runtime/sandbox/client/training_client.py +265 -0
  78. agentscope_runtime/sandbox/constant.py +5 -0
  79. agentscope_runtime/sandbox/custom/__init__.py +16 -0
  80. agentscope_runtime/sandbox/custom/custom_sandbox.py +40 -0
  81. agentscope_runtime/sandbox/custom/example.py +37 -0
  82. agentscope_runtime/sandbox/enums.py +68 -0
  83. agentscope_runtime/sandbox/manager/__init__.py +4 -0
  84. agentscope_runtime/sandbox/manager/collections/__init__.py +22 -0
  85. agentscope_runtime/sandbox/manager/collections/base_mapping.py +20 -0
  86. agentscope_runtime/sandbox/manager/collections/base_queue.py +25 -0
  87. agentscope_runtime/sandbox/manager/collections/base_set.py +25 -0
  88. agentscope_runtime/sandbox/manager/collections/in_memory_mapping.py +22 -0
  89. agentscope_runtime/sandbox/manager/collections/in_memory_queue.py +28 -0
  90. agentscope_runtime/sandbox/manager/collections/in_memory_set.py +27 -0
  91. agentscope_runtime/sandbox/manager/collections/redis_mapping.py +26 -0
  92. agentscope_runtime/sandbox/manager/collections/redis_queue.py +27 -0
  93. agentscope_runtime/sandbox/manager/collections/redis_set.py +23 -0
  94. agentscope_runtime/sandbox/manager/container_clients/__init__.py +8 -0
  95. agentscope_runtime/sandbox/manager/container_clients/base_client.py +39 -0
  96. agentscope_runtime/sandbox/manager/container_clients/docker_client.py +170 -0
  97. agentscope_runtime/sandbox/manager/sandbox_manager.py +694 -0
  98. agentscope_runtime/sandbox/manager/server/__init__.py +0 -0
  99. agentscope_runtime/sandbox/manager/server/app.py +194 -0
  100. agentscope_runtime/sandbox/manager/server/config.py +68 -0
  101. agentscope_runtime/sandbox/manager/server/models.py +17 -0
  102. agentscope_runtime/sandbox/manager/storage/__init__.py +10 -0
  103. agentscope_runtime/sandbox/manager/storage/data_storage.py +16 -0
  104. agentscope_runtime/sandbox/manager/storage/local_storage.py +44 -0
  105. agentscope_runtime/sandbox/manager/storage/oss_storage.py +89 -0
  106. agentscope_runtime/sandbox/manager/utils.py +78 -0
  107. agentscope_runtime/sandbox/mcp_server.py +192 -0
  108. agentscope_runtime/sandbox/model/__init__.py +12 -0
  109. agentscope_runtime/sandbox/model/api.py +16 -0
  110. agentscope_runtime/sandbox/model/container.py +72 -0
  111. agentscope_runtime/sandbox/model/manager_config.py +158 -0
  112. agentscope_runtime/sandbox/registry.py +129 -0
  113. agentscope_runtime/sandbox/tools/__init__.py +12 -0
  114. agentscope_runtime/sandbox/tools/base/__init__.py +8 -0
  115. agentscope_runtime/sandbox/tools/base/tool.py +52 -0
  116. agentscope_runtime/sandbox/tools/browser/__init__.py +57 -0
  117. agentscope_runtime/sandbox/tools/browser/tool.py +597 -0
  118. agentscope_runtime/sandbox/tools/filesystem/__init__.py +32 -0
  119. agentscope_runtime/sandbox/tools/filesystem/tool.py +319 -0
  120. agentscope_runtime/sandbox/tools/function_tool.py +321 -0
  121. agentscope_runtime/sandbox/tools/mcp_tool.py +191 -0
  122. agentscope_runtime/sandbox/tools/sandbox_tool.py +104 -0
  123. agentscope_runtime/sandbox/tools/tool.py +123 -0
  124. agentscope_runtime/sandbox/tools/utils.py +68 -0
  125. agentscope_runtime/version.py +2 -0
  126. agentscope_runtime-0.1.0.dist-info/METADATA +327 -0
  127. agentscope_runtime-0.1.0.dist-info/RECORD +131 -0
  128. agentscope_runtime-0.1.0.dist-info/WHEEL +5 -0
  129. agentscope_runtime-0.1.0.dist-info/entry_points.txt +4 -0
  130. agentscope_runtime-0.1.0.dist-info/licenses/LICENSE +202 -0
  131. agentscope_runtime-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,551 @@
1
+ # -*- coding: utf-8 -*-
2
+ # type: ignore
3
+ from copy import deepcopy
4
+ from datetime import datetime
5
+ from typing import List, Dict, Optional, Any
6
+ from typing import Union
7
+
8
+ try:
9
+ from typing import Self
10
+ except ImportError:
11
+ from typing_extensions import Self
12
+ from uuid import uuid4
13
+
14
+ from pydantic import BaseModel, Field, field_validator
15
+
16
+
17
+ class MessageType:
18
+ MESSAGE = "message"
19
+ FUNCTION_CALL = "function_call"
20
+ FUNCTION_CALL_OUTPUT = "function_call_output"
21
+ PLUGIN_CALL = "plugin_call"
22
+ PLUGIN_CALL_OUTPUT = "plugin_call_output"
23
+ COMPONENT_CALL = "component_call"
24
+ COMPONENT_CALL_OUTPUT = "component_call_output"
25
+ MCP_LIST_TOOLS = "mcp_list_tools"
26
+ MCP_APPROVAL_REQUEST = "mcp_approval_request"
27
+ MCP_TOOL_CALL = "mcp_call"
28
+ MCP_APPROVAL_RESPONSE = "mcp_approval_response"
29
+ HEARTBEAT = "heartbeat"
30
+ ERROR = "error"
31
+
32
+
33
+ class ContentType:
34
+ TEXT = "text"
35
+ DATA = "data"
36
+ IMAGE = "image"
37
+ AUDIO = "audio"
38
+
39
+
40
+ class Role:
41
+ ASSISTANT = "assistant"
42
+ USER = "user"
43
+ SYSTEM = "system"
44
+
45
+
46
+ class RunStatus:
47
+ """
48
+ Enum class for agent event message.
49
+ """
50
+
51
+ Created = "created"
52
+ InProgress = "in_progress"
53
+ Completed = "completed"
54
+ Canceled = "canceled"
55
+ Failed = "failed"
56
+ Rejected = "rejected"
57
+ Unknown = "unknown"
58
+
59
+
60
+ class FunctionParameters(BaseModel):
61
+ type: str
62
+ """The type of the parameters object. Must be `object`."""
63
+
64
+ properties: Dict[str, Any]
65
+ """The properties of the parameters object."""
66
+
67
+ required: Optional[List[str]]
68
+ """The names of the required properties."""
69
+
70
+
71
+ class FunctionTool(BaseModel):
72
+ """
73
+ Model class for prompt message tool.
74
+ """
75
+
76
+ name: str
77
+ """The name of the function to be called. """
78
+
79
+ description: str
80
+ """A description of what the function does, used by the model to choose
81
+ when and how to call the function.
82
+ """
83
+
84
+ parameters: Union[FunctionParameters, Dict[str, Any]]
85
+ """The parameters the functions accepts, described as a JSON Schema object.
86
+
87
+ """
88
+
89
+
90
+ class Tool(BaseModel):
91
+ """
92
+ Model class for assistant prompt message tool call.
93
+ """
94
+
95
+ type: Optional[str] = None
96
+ """The type of the tool. Currently, only `function` is supported."""
97
+
98
+ function: Optional[FunctionTool] = None
99
+ """The function that the model called."""
100
+
101
+
102
+ class FunctionCall(BaseModel):
103
+ """
104
+ Model class for assistant prompt message tool call function.
105
+ """
106
+
107
+ call_id: Optional[str] = None
108
+ """The ID of the tool call."""
109
+
110
+ name: Optional[str] = None
111
+ """The name of the function to call."""
112
+
113
+ arguments: Optional[str] = None
114
+ """The arguments to call the function with, as generated by the model in
115
+ JSON format.
116
+
117
+ Note that the model does not always generate valid JSON, and may
118
+ hallucinate parameters not defined by your function schema. Validate
119
+ the arguments in your code before calling your function.
120
+ """
121
+
122
+
123
+ class FunctionCallOutput(BaseModel):
124
+ """
125
+ Model class for assistant prompt message tool call function.
126
+ """
127
+
128
+ call_id: str
129
+ """The ID of the tool call."""
130
+
131
+ output: str
132
+ """The result of the function."""
133
+
134
+
135
+ class Error(BaseModel):
136
+ code: str
137
+ """The error code of the message."""
138
+
139
+ message: str
140
+ """The error message of the message."""
141
+
142
+
143
+ class Event(BaseModel):
144
+ sequence_number: Optional[str] = None
145
+ """sequence number of event"""
146
+
147
+ object: str
148
+ """The identity of the content part."""
149
+
150
+ status: Optional[str] = None
151
+ """The status of the message. in_progress, completed, or incomplete"""
152
+
153
+ error: Optional[Error] = None
154
+ """response error for output"""
155
+
156
+ def created(self) -> Self:
157
+ """
158
+ Set the message status to 'created'.
159
+ """
160
+ self.status = RunStatus.Created
161
+ return self
162
+
163
+ def in_progress(self) -> Self:
164
+ """
165
+ Set the message status to 'in_progress'.
166
+ """
167
+ self.status = RunStatus.InProgress
168
+ return self
169
+
170
+ def completed(self) -> Self:
171
+ """
172
+ Set the message status to 'completed'.
173
+ """
174
+ self.status = RunStatus.Completed
175
+ return self
176
+
177
+ def failed(self, error: Error) -> Self:
178
+ """
179
+ Set the message status to 'failed'.
180
+ """
181
+ self.status = RunStatus.Failed
182
+ self.error = error
183
+ return self
184
+
185
+ def rejected(self) -> Self:
186
+ """
187
+ Set the message status to 'rejected'.
188
+ """
189
+ self.status = RunStatus.Rejected
190
+ return self
191
+
192
+ def canceled(self) -> Self:
193
+ """
194
+ Set the message status to 'canceled'.
195
+ """
196
+ self.status = RunStatus.Canceled
197
+ return self
198
+
199
+
200
+ class Content(Event):
201
+ type: str
202
+ """The type of the content part."""
203
+
204
+ object: str = "content"
205
+ """The identity of the content part."""
206
+
207
+ index: Optional[int] = None
208
+ """the content index in message's content list"""
209
+
210
+ delta: Optional[bool] = False
211
+ """Whether this content is a delta."""
212
+
213
+ msg_id: str = None
214
+ """message unique id"""
215
+
216
+
217
+ class ImageContent(Content):
218
+ type: str = ContentType.IMAGE
219
+ """The type of the content part."""
220
+
221
+ image_url: Optional[str] = None
222
+ """The image URL details."""
223
+
224
+
225
+ class TextContent(Content):
226
+ type: str = ContentType.TEXT
227
+ """The type of the content part."""
228
+
229
+ text: Optional[str] = None
230
+ """The text content."""
231
+
232
+
233
+ class DataContent(Content):
234
+ type: str = ContentType.DATA
235
+ """The type of the content part."""
236
+
237
+ data: Optional[Dict] = None
238
+ """The data content."""
239
+
240
+
241
+ class Message(Event):
242
+ id: str = Field(default_factory=lambda: "msg_" + str(uuid4()))
243
+ """message unique id"""
244
+
245
+ object: str = "message"
246
+ """message identity"""
247
+
248
+ type: str = "message"
249
+ """The type of the message."""
250
+
251
+ status: str = RunStatus.Created
252
+ """The status of the message. in_progress, completed, or incomplete"""
253
+
254
+ role: Optional[str] = None
255
+ """The role of the messages author, should be in `user`,`system`,
256
+ 'assistant'."""
257
+
258
+ content: Optional[
259
+ List[Union[TextContent, ImageContent, DataContent]]
260
+ ] = None
261
+ """The contents of the message."""
262
+
263
+ code: Optional[str] = None
264
+ """The error code of the message."""
265
+
266
+ message: Optional[str] = None
267
+ """The error message of the message."""
268
+
269
+ def add_delta_content(
270
+ self,
271
+ new_content: Union[TextContent, ImageContent, DataContent],
272
+ ):
273
+ self.content = self.content or []
274
+
275
+ # new content
276
+ if new_content.index is None:
277
+ copy = deepcopy(new_content)
278
+ copy.delta = None
279
+ copy.index = None
280
+ copy.msg_id = None
281
+ self.content.append(copy)
282
+
283
+ new_content.index = len(self.content) - 1
284
+ new_content.msg_id = self.id
285
+ new_content.in_progress()
286
+ return new_content
287
+
288
+ # delta content
289
+ if new_content.delta is True:
290
+ # append the content
291
+ pre_content = self.content[new_content.index]
292
+ _type = pre_content.type
293
+
294
+ # append text
295
+ if _type == ContentType.TEXT:
296
+ pre_content.text += new_content.text
297
+
298
+ # append image_url
299
+ if _type == ContentType.IMAGE:
300
+ pre_content.image_url += new_content.image_url
301
+
302
+ # append data
303
+ if _type == ContentType.DATA:
304
+ for key in new_content.data:
305
+ if (
306
+ key in pre_content.data
307
+ and isinstance(pre_content.data[key], (list, str))
308
+ and isinstance(
309
+ new_content.data[key],
310
+ type(pre_content.data[key]),
311
+ )
312
+ ):
313
+ if isinstance(pre_content.data[key], list):
314
+ pre_content.data[key].extend(new_content.data[key])
315
+ elif isinstance(pre_content.data[key], str):
316
+ pre_content.data[key] += new_content.data[key]
317
+ new_content.msg_id = self.id
318
+ new_content.in_progress()
319
+ return new_content
320
+
321
+ return None
322
+
323
+ def content_completed(self, content_index: int):
324
+ if self.content is None:
325
+ return None
326
+ if content_index >= len(self.content):
327
+ return None
328
+ else:
329
+ content = self.content[content_index]
330
+ new_content = deepcopy(content)
331
+ new_content.delta = False
332
+ new_content.index = content_index
333
+ new_content.msg_id = self.id
334
+ new_content.completed()
335
+ return new_content
336
+
337
+ def add_content(
338
+ self,
339
+ new_content: Union[TextContent, ImageContent, DataContent],
340
+ ):
341
+ self.content = self.content or []
342
+
343
+ # new content
344
+ if new_content.index is None:
345
+ copy = deepcopy(new_content)
346
+ self.content.append(copy)
347
+
348
+ new_content.index = len(self.content) - 1
349
+ new_content.msg_id = self.id
350
+ new_content.completed()
351
+ return new_content
352
+
353
+ return None
354
+
355
+
356
+ class BaseRequest(BaseModel):
357
+ """agent request"""
358
+
359
+ input: List[Message]
360
+ """
361
+ input messages
362
+ """
363
+
364
+ stream: bool = True
365
+ """If set, partial message deltas will be sent, like in ChatGPT. """
366
+
367
+
368
+ class AgentRequest(BaseRequest):
369
+ """agent request"""
370
+
371
+ model: Optional[str] = None
372
+ """
373
+ model id
374
+ """
375
+
376
+ top_p: Optional[float] = None
377
+ """Nucleus sampling, between (0, 1.0], where the model considers the
378
+ results of the tokens with top_p probability mass.
379
+
380
+ So 0.1 means only the tokens comprising the top 10% probability mass are
381
+ considered.
382
+
383
+ We generally recommend altering this or `temperature` but not both.
384
+ """
385
+
386
+ temperature: Optional[float] = None
387
+ """What sampling temperature to use, between 0 and 2.
388
+
389
+ Higher values like 0.8 will make the output more random, while lower values
390
+ like 0.2 will make it more focused and deterministic.
391
+
392
+ We generally recommend altering this or `top_p` but not both.
393
+ """
394
+
395
+ frequency_penalty: Optional[float] = None
396
+ """Positive values penalize new tokens based on their existing frequency in
397
+ the text so far, decreasing the model's likelihood to repeat the same line
398
+ verbatim.
399
+
400
+ """
401
+
402
+ presence_penalty: Optional[float] = None
403
+ """Number between -2.0 and 2.0.
404
+
405
+ Positive values penalize new tokens based on whether they appear in the
406
+ text so far, increasing the model's likelihood to talk about new topics.
407
+
408
+ """
409
+
410
+ max_tokens: Optional[int] = None
411
+ """The maximum number of [tokens](/tokenizer) that can be generated in the
412
+ chat completion.
413
+
414
+ The total length of input tokens and generated tokens is limited by the
415
+ model's context length.
416
+ """
417
+
418
+ stop: Optional[Union[Optional[str], List[str]]] = None
419
+ """Up to 4 sequences where the API will stop generating further tokens."""
420
+
421
+ n: Optional[int] = Field(default=1, ge=1, le=5)
422
+ """How many chat completion choices to generate for each input message.
423
+
424
+ Note that you will be charged based on the number of generated tokens
425
+ across all of the choices. Keep `n` as `1` to minimize costs.
426
+ """
427
+
428
+ seed: Optional[int] = None
429
+ """If specified, system will make a best effort to sample
430
+ deterministically, such that repeated requests with the same `seed` and
431
+ parameters should return the same result.
432
+ """
433
+
434
+ tools: Optional[List[Union[Tool, Dict]]] = None
435
+ """
436
+ tool call list
437
+ """
438
+
439
+ session_id: Optional[str] = None
440
+ """conversation id for dialog"""
441
+
442
+ response_id: Optional[str] = None
443
+ """response unique id"""
444
+
445
+
446
+ class BaseResponse(Event):
447
+ id: Optional[str] = Field(
448
+ default_factory=lambda: "response_"
449
+ + str(
450
+ uuid4(),
451
+ ),
452
+ )
453
+ """response unique id"""
454
+
455
+ @field_validator("id", mode="before")
456
+ @classmethod
457
+ def validate_id(cls, v):
458
+ if v is None:
459
+ return "response_" + str(uuid4())
460
+ return v
461
+
462
+ object: str = "response"
463
+ """response identity"""
464
+
465
+ status: str = RunStatus.Created
466
+ """response run status"""
467
+
468
+ created_at: int = int(datetime.now().timestamp())
469
+ """request start time"""
470
+
471
+ completed_at: Optional[int] = None
472
+ """request completed time"""
473
+
474
+ output: Optional[List[Message]] = None
475
+ """response data for output"""
476
+
477
+ usage: Optional[Dict] = None
478
+ """response usage for output"""
479
+
480
+ def add_new_message(self, message: Message):
481
+ self.output = self.output or []
482
+ self.output.append(message)
483
+
484
+
485
+ class AgentResponse(BaseResponse):
486
+ """agent response"""
487
+
488
+ session_id: Optional[str] = None
489
+ """conversation id for dialog"""
490
+
491
+
492
+ def convert_to_openai_tool_call(function: FunctionCall):
493
+ return {
494
+ "id": function.get("call_id", None),
495
+ "type": "function",
496
+ "function": {
497
+ "name": function.get("name", None),
498
+ "arguments": function.get("arguments", None),
499
+ },
500
+ }
501
+
502
+
503
+ def convert_to_openai_messages(messages: List[Message]) -> list:
504
+ """
505
+ Convert a generic message protocol to a model-specific protocol.
506
+ Args:
507
+ messages: Original list of messages
508
+ Returns:
509
+ list: Message format required by the model
510
+ """
511
+ converted = []
512
+ for msg in messages:
513
+ if MessageType.MESSAGE == msg.type:
514
+ converted.append(
515
+ {
516
+ "role": msg.role,
517
+ "content": [c.model_dump() for c in msg.content],
518
+ },
519
+ )
520
+
521
+ if MessageType.FUNCTION_CALL == msg.type:
522
+ converted.append(
523
+ {
524
+ "role": Role.ASSISTANT,
525
+ "tool_calls": [
526
+ convert_to_openai_tool_call(c.data)
527
+ for c in msg.content
528
+ ],
529
+ },
530
+ )
531
+
532
+ if MessageType.FUNCTION_CALL_OUTPUT == msg.type:
533
+ for function_call_output in msg.content:
534
+ converted.append(
535
+ {
536
+ "role": "tool",
537
+ "tool_call_id": function_call_output.data.get(
538
+ "call_id",
539
+ ),
540
+ "content": function_call_output.data.get("output"),
541
+ },
542
+ )
543
+ return converted
544
+
545
+
546
+ def convert_to_openai_tools(tools: List[Union[Tool, Dict]]) -> Optional[list]:
547
+ if not tools:
548
+ return None
549
+ return [
550
+ tool.model_dump() if isinstance(tool, Tool) else tool for tool in tools
551
+ ]
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+ from typing import Optional, List, Dict
3
+
4
+ from pydantic import BaseModel, ConfigDict
5
+
6
+ from .agent_schemas import AgentRequest
7
+ from .agent_schemas import Message
8
+ from ..agents.base_agent import Agent
9
+ from ..services.context_manager import ContextManager
10
+
11
+ from ..services.session_history_service import (
12
+ Session,
13
+ )
14
+ from ..services.environment_manager import EnvironmentManager
15
+
16
+
17
+ class Context(BaseModel):
18
+ """
19
+ Holds all contextual information for a single agent invocation.
20
+
21
+ This object is created by the Runner and passed through the agent
22
+ execution flow, providing access to necessary services and data,
23
+ including a live request queue for real-time interaction.
24
+ """
25
+
26
+ model_config = ConfigDict(
27
+ arbitrary_types_allowed=True,
28
+ extra="forbid",
29
+ )
30
+
31
+ # Core context
32
+ user_id: str
33
+ session: Session = Session(id="", user_id="")
34
+ activate_tools: list = []
35
+ new_message: Optional[Message] = None
36
+ current_messages: List[Message] = []
37
+ request: AgentRequest
38
+ new_message_dict: Optional[Dict] = None
39
+ messages_list: List[Dict] = []
40
+
41
+ # Services available to the agent
42
+
43
+ environment_manager: Optional[EnvironmentManager] = None
44
+ context_manager: Optional[ContextManager] = None
45
+ # Agent specific config
46
+ agent: Agent
47
+ agent_config: Optional[dict] = None
48
+
49
+ @property
50
+ def messages(self):
51
+ if self.new_message_dict:
52
+ return self.messages_list + [self.new_message_dict]
53
+ else:
54
+ return self.messages_list
@@ -0,0 +1,9 @@
1
+ # -*- coding: utf-8 -*-
2
+ from .base import (
3
+ Service,
4
+ ServiceWithLifecycleManager,
5
+ ServiceLifecycleManagerMixin,
6
+ )
7
+ from .sandbox_service import SandboxService
8
+ from .memory_service import MemoryService
9
+ from .session_history_service import SessionHistoryService
@@ -0,0 +1,77 @@
1
+ # -*- coding: utf-8 -*-
2
+ from abc import ABC, abstractmethod
3
+
4
+
5
+ class Service(ABC):
6
+ """Abstract base class for services.
7
+
8
+ This class defines the interface that all services must implement.
9
+ """
10
+
11
+ @abstractmethod
12
+ async def start(self) -> None:
13
+ """
14
+ Starts the service, initializing any necessary resources or
15
+ connections.
16
+ """
17
+
18
+ @abstractmethod
19
+ async def stop(self) -> None:
20
+ """Stops the service, releasing any acquired resources."""
21
+
22
+ @abstractmethod
23
+ async def health(self) -> bool:
24
+ """
25
+ Checks the health of the service.
26
+
27
+ Returns:
28
+ True if the service is healthy, False otherwise.
29
+ """
30
+
31
+
32
+ class ServiceLifecycleManagerMixin:
33
+ """Mixin class that provides async lifecycle manager functionality for
34
+ services.
35
+
36
+ This mixin can be used with any class that implements the Service
37
+ interface.
38
+ """
39
+
40
+ async def __aenter__(self):
41
+ """Async context manager entry."""
42
+ await self.start()
43
+ return self
44
+
45
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
46
+ """Async context manager exit."""
47
+ await self.stop()
48
+ return False
49
+
50
+
51
+ class ServiceWithLifecycleManager(Service, ServiceLifecycleManagerMixin):
52
+ """Base class for services that want async lifecycle manager functionality.
53
+
54
+ This class combines the Service interface with the context manager mixin,
55
+ providing a convenient base class for most service implementations.
56
+
57
+ Note: This is an abstract base class. Subclasses must implement the
58
+ abstract methods from the Service class.
59
+ """
60
+
61
+ @abstractmethod
62
+ async def start(self) -> None:
63
+ """Starts the service, initializing any necessary resources or
64
+ connections."""
65
+
66
+ @abstractmethod
67
+ async def stop(self) -> None:
68
+ """Stops the service, releasing any acquired resources."""
69
+
70
+ @abstractmethod
71
+ async def health(self) -> bool:
72
+ """
73
+ Checks the health of the service.
74
+
75
+ Returns:
76
+ True if the service is healthy, False otherwise.
77
+ """