python-codex 0.2.7__py3-none-any.whl → 0.3.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.
- pycodex/__init__.py +14 -14
- pycodex/agent.py +465 -499
- pycodex/bootstrap.py +417 -0
- pycodex/cli.py +236 -510
- pycodex/compat.py +19 -5
- pycodex/context.py +222 -212
- pycodex/doctor.py +52 -48
- pycodex/events.py +857 -0
- pycodex/feishu_card.py +217 -163
- pycodex/feishu_link.py +43 -83
- pycodex/model.py +324 -253
- pycodex/model_metadata.py +19 -7
- pycodex/portable.py +76 -45
- pycodex/portable_server.py +32 -24
- pycodex/prompts/models.json +245 -983
- pycodex/protocol.py +177 -137
- pycodex/runtime.py +579 -176
- pycodex/runtime_services.py +204 -157
- pycodex/tools/__init__.py +1 -1
- pycodex/tools/apply_patch_tool.py +69 -48
- pycodex/tools/base_tool.py +89 -42
- pycodex/tools/clock_tool.py +58 -25
- pycodex/tools/close_agent_tool.py +2 -2
- pycodex/tools/code_mode_manager.py +77 -64
- pycodex/tools/exec_command_tool.py +26 -11
- pycodex/tools/exec_tool.py +4 -4
- pycodex/tools/grep_files_tool.py +12 -10
- pycodex/tools/ipython_tool.py +10 -13
- pycodex/tools/list_dir_tool.py +13 -9
- pycodex/tools/read_file_tool.py +29 -17
- pycodex/tools/request_permissions_tool.py +15 -5
- pycodex/tools/request_user_input_tool.py +13 -104
- pycodex/tools/resume_agent_tool.py +2 -2
- pycodex/tools/send_input_tool.py +11 -8
- pycodex/tools/shell_command_tool.py +7 -5
- pycodex/tools/shell_tool.py +7 -5
- pycodex/tools/spawn_agent_tool.py +7 -4
- pycodex/tools/unified_exec_manager.py +102 -69
- pycodex/tools/update_plan_tool.py +8 -5
- pycodex/tools/view_image_tool.py +7 -5
- pycodex/tools/wait_agent_tool.py +27 -4
- pycodex/tools/wait_tool.py +5 -4
- pycodex/tools/web_search_tool.py +4 -2
- pycodex/tools/write_stdin_tool.py +12 -11
- pycodex/utils/__init__.py +2 -17
- pycodex/utils/compactor.py +41 -72
- pycodex/utils/debug.py +2 -2
- pycodex/utils/dotenv.py +6 -7
- pycodex/utils/event_helpers.py +190 -0
- pycodex/utils/get_env.py +27 -70
- pycodex/{image_utils.py → utils/image_utils.py} +8 -11
- pycodex/utils/random_ids.py +1 -2
- pycodex/utils/session_persist.py +217 -163
- pycodex/utils/truncation.py +21 -45
- python_codex-0.3.0.dist-info/METADATA +704 -0
- python_codex-0.3.0.dist-info/RECORD +90 -0
- responses_server/__init__.py +1 -5
- responses_server/__main__.py +0 -1
- responses_server/app.py +36 -31
- responses_server/config.py +23 -23
- responses_server/messages_api.py +51 -53
- responses_server/payload_processors.py +25 -20
- responses_server/server.py +11 -11
- responses_server/session_store.py +14 -11
- responses_server/stream_router.py +101 -98
- responses_server/tools/custom_adapter.py +17 -16
- responses_server/tools/web_search.py +39 -36
- responses_server/trajectory_dump.py +36 -14
- workspace_server/__main__.py +0 -1
- workspace_server/app.py +461 -375
- workspace_server/workspace.html +852 -228
- workspace_server/workspaces.html +94 -95
- workspace_server/workspaces.py +137 -79
- pycodex/collaboration.py +0 -20
- pycodex/interactive_session.py +0 -415
- pycodex/prompts/collaboration_default.md +0 -11
- pycodex/prompts/collaboration_plan.md +0 -128
- pycodex/utils/toolcall_visualize.py +0 -713
- pycodex/utils/visualize.py +0 -560
- python_codex-0.2.7.dist-info/METADATA +0 -455
- python_codex-0.2.7.dist-info/RECORD +0 -93
- {python_codex-0.2.7.dist-info → python_codex-0.3.0.dist-info}/WHEEL +0 -0
- {python_codex-0.2.7.dist-info → python_codex-0.3.0.dist-info}/entry_points.txt +0 -0
- {python_codex-0.2.7.dist-info → python_codex-0.3.0.dist-info}/licenses/LICENSE +0 -0
pycodex/protocol.py
CHANGED
|
@@ -3,45 +3,47 @@
|
|
|
3
3
|
核心抽象:
|
|
4
4
|
- Agent:内层 turn 主循环,负责维护历史、调用模型、执行工具,并在
|
|
5
5
|
`ToolCall -> ToolResult -> 下一轮模型调用` 之间反复闭环,直到得到稳定回复。
|
|
6
|
-
- AgentRuntime
|
|
7
|
-
|
|
6
|
+
- AgentRuntime:外层调度与前端接口,负责按顺序处理用户请求;
|
|
7
|
+
队列生命周期不作为请求入队。
|
|
8
8
|
- ContextManager:负责把基础指令、AGENTS.md、环境信息等上下文拼成每轮模型看到的
|
|
9
9
|
`Prompt` 前缀,但这些注入内容不会写回长期会话历史。
|
|
10
10
|
- ModelClient:模型后端抽象,接收 `Prompt`,返回 `ModelResponse`。
|
|
11
|
-
- ModelStreamEvent:模型在一次 `Prompt` 处理中途产生的流式事件,例如文本增量。
|
|
12
11
|
- ToolRegistry:工具执行抽象,接收 `ToolCall`,产出 `ToolResult`。
|
|
13
12
|
|
|
14
13
|
本文件只定义这些抽象之间传递的数据结构,不包含具体执行逻辑。
|
|
15
14
|
"""
|
|
16
15
|
|
|
17
|
-
from copy import deepcopy
|
|
18
16
|
import json
|
|
17
|
+
import typing
|
|
18
|
+
from copy import deepcopy
|
|
19
19
|
from dataclasses import dataclass, field
|
|
20
20
|
from typing import Any
|
|
21
|
+
|
|
21
22
|
from .compat import Literal, TypeAlias
|
|
22
|
-
import typing
|
|
23
23
|
|
|
24
|
-
JSONValue:
|
|
25
|
-
JSONDict:
|
|
24
|
+
JSONValue: "TypeAlias" = Any
|
|
25
|
+
JSONDict: "TypeAlias" = typing.Dict[str, Any]
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
@dataclass(
|
|
28
|
+
@dataclass(
|
|
29
|
+
frozen=True,
|
|
30
|
+
)
|
|
29
31
|
class ToolSpec:
|
|
30
32
|
"""何时:Agent 准备发起一轮模型请求时,随 `Prompt.tools` 一起发送。
|
|
31
33
|
发送方:Agent。
|
|
32
34
|
接收方:ModelClient。
|
|
33
35
|
"""
|
|
34
36
|
|
|
35
|
-
name:
|
|
36
|
-
description:
|
|
37
|
-
input_schema:
|
|
37
|
+
name: "str"
|
|
38
|
+
description: "str"
|
|
39
|
+
input_schema: "typing.Union[JSONDict, None]" = None
|
|
38
40
|
tool_type: 'Literal["function", "custom", "web_search"]' = "function"
|
|
39
|
-
format:
|
|
40
|
-
options:
|
|
41
|
-
output_schema:
|
|
42
|
-
supports_parallel:
|
|
41
|
+
format: "typing.Union[JSONDict, None]" = None
|
|
42
|
+
options: "typing.Union[JSONDict, None]" = None
|
|
43
|
+
output_schema: "typing.Union[JSONDict, None]" = None
|
|
44
|
+
supports_parallel: "bool" = True
|
|
43
45
|
|
|
44
|
-
def serialize(self) ->
|
|
46
|
+
def serialize(self) -> "JSONDict":
|
|
45
47
|
if self.tool_type == "web_search":
|
|
46
48
|
payload = {"type": "web_search"}
|
|
47
49
|
if self.options is not None:
|
|
@@ -71,101 +73,161 @@ class ToolSpec:
|
|
|
71
73
|
return payload
|
|
72
74
|
|
|
73
75
|
|
|
74
|
-
@dataclass(
|
|
76
|
+
@dataclass(
|
|
77
|
+
frozen=True,
|
|
78
|
+
)
|
|
75
79
|
class UserMessage:
|
|
76
80
|
"""何时:外部发起一个新的用户 turn 时创建,并写入会话历史。
|
|
77
81
|
发送方:外部调用方创建,Agent 转发。
|
|
78
82
|
接收方:Agent 先接收,随后 ModelClient 在 `Prompt.input` 中看到它。
|
|
79
83
|
"""
|
|
80
84
|
|
|
81
|
-
text:
|
|
85
|
+
text: "str"
|
|
82
86
|
role: 'Literal["user"]' = "user"
|
|
87
|
+
id: "typing.Union[str, None]" = None
|
|
83
88
|
|
|
84
|
-
def serialize(self) ->
|
|
85
|
-
|
|
89
|
+
def serialize(self) -> "JSONDict":
|
|
90
|
+
payload = {
|
|
86
91
|
"type": "message",
|
|
87
92
|
"role": self.role,
|
|
88
93
|
"content": [{"type": "input_text", "text": self.text}],
|
|
89
94
|
}
|
|
95
|
+
if self.id is not None:
|
|
96
|
+
payload["id"] = self.id
|
|
97
|
+
return payload
|
|
90
98
|
|
|
91
99
|
|
|
92
|
-
@dataclass(
|
|
100
|
+
@dataclass(
|
|
101
|
+
frozen=True,
|
|
102
|
+
)
|
|
93
103
|
class AssistantMessage:
|
|
94
104
|
"""何时:模型要直接输出自然语言内容时产生,可作为中间文本或最终回复。
|
|
95
105
|
发送方:ModelClient。
|
|
96
106
|
接收方:Agent。
|
|
97
107
|
"""
|
|
98
108
|
|
|
99
|
-
text:
|
|
109
|
+
text: "str"
|
|
100
110
|
role: 'Literal["assistant"]' = "assistant"
|
|
111
|
+
id: "typing.Union[str, None]" = None
|
|
112
|
+
phase: "typing.Union[str, None]" = None
|
|
113
|
+
content_items: "typing.Union[typing.Tuple[JSONDict, ...], None]" = None
|
|
114
|
+
|
|
115
|
+
@classmethod
|
|
116
|
+
def from_response_item(cls, payload: "JSONDict") -> "AssistantMessage":
|
|
117
|
+
content = tuple(
|
|
118
|
+
{"type": part["type"], "text": str(part.get("text", ""))}
|
|
119
|
+
for part in payload.get("content", [])
|
|
120
|
+
if part.get("type") == "output_text"
|
|
121
|
+
)
|
|
122
|
+
return cls(
|
|
123
|
+
text="".join(part["text"] for part in content),
|
|
124
|
+
id=payload.get("id"),
|
|
125
|
+
phase=payload.get("phase"),
|
|
126
|
+
content_items=content if len(content) != 1 else None,
|
|
127
|
+
)
|
|
101
128
|
|
|
102
|
-
def serialize(self) ->
|
|
103
|
-
|
|
129
|
+
def serialize(self) -> "JSONDict":
|
|
130
|
+
payload = {
|
|
104
131
|
"type": "message",
|
|
105
132
|
"role": self.role,
|
|
106
|
-
"content":
|
|
133
|
+
"content": (
|
|
134
|
+
deepcopy(list(self.content_items))
|
|
135
|
+
if self.content_items is not None
|
|
136
|
+
else [{"type": "output_text", "text": self.text}]
|
|
137
|
+
),
|
|
107
138
|
}
|
|
139
|
+
if self.id is not None:
|
|
140
|
+
payload["id"] = self.id
|
|
141
|
+
if self.phase is not None:
|
|
142
|
+
payload["phase"] = self.phase
|
|
143
|
+
return payload
|
|
108
144
|
|
|
109
145
|
|
|
110
|
-
@dataclass(
|
|
146
|
+
@dataclass(
|
|
147
|
+
frozen=True,
|
|
148
|
+
)
|
|
111
149
|
class ContextMessage:
|
|
112
|
-
"""
|
|
113
|
-
发送方:ContextManager。
|
|
150
|
+
"""何时:注入额外上下文或用 compact 摘要替换历史时构造。
|
|
151
|
+
发送方:ContextManager 或 compactor。
|
|
114
152
|
接收方:ModelClient。
|
|
115
153
|
"""
|
|
116
154
|
|
|
117
|
-
text:
|
|
155
|
+
text: "typing.Union[str, None]" = None
|
|
118
156
|
role: 'Literal["user", "developer"]' = "user"
|
|
119
|
-
content_items:
|
|
157
|
+
content_items: "typing.Union[typing.Tuple[JSONDict, ...], None]" = None
|
|
158
|
+
id: "typing.Union[str, None]" = None
|
|
120
159
|
|
|
121
|
-
def serialize(self) ->
|
|
160
|
+
def serialize(self) -> "JSONDict":
|
|
122
161
|
if self.content_items is not None:
|
|
123
162
|
content = list(self.content_items)
|
|
124
163
|
else:
|
|
125
164
|
if self.text is None:
|
|
126
165
|
raise ValueError("ContextMessage requires `text` or `content_items`")
|
|
127
166
|
content = [{"type": "input_text", "text": self.text}]
|
|
128
|
-
|
|
167
|
+
payload = {
|
|
129
168
|
"type": "message",
|
|
130
169
|
"role": self.role,
|
|
131
170
|
"content": content,
|
|
132
171
|
}
|
|
172
|
+
if self.id is not None:
|
|
173
|
+
payload["id"] = self.id
|
|
174
|
+
return payload
|
|
133
175
|
|
|
134
176
|
|
|
135
|
-
@dataclass(
|
|
177
|
+
@dataclass(
|
|
178
|
+
frozen=True,
|
|
179
|
+
)
|
|
136
180
|
class ToolCall:
|
|
137
181
|
"""何时:模型决定调用工具而不是只输出文本时产生。
|
|
138
182
|
发送方:ModelClient。
|
|
139
183
|
接收方:Agent,随后由它转给 ToolRegistry 执行。
|
|
140
184
|
"""
|
|
141
185
|
|
|
142
|
-
call_id:
|
|
143
|
-
name:
|
|
144
|
-
arguments:
|
|
186
|
+
call_id: "str"
|
|
187
|
+
name: "str"
|
|
188
|
+
arguments: "JSONValue"
|
|
145
189
|
tool_type: 'Literal["function", "custom"]' = "function"
|
|
146
190
|
kind: 'Literal["tool_call"]' = "tool_call"
|
|
191
|
+
id: "typing.Union[str, None]" = None
|
|
192
|
+
raw_arguments: "typing.Union[str, None]" = None
|
|
193
|
+
namespace: "typing.Union[str, None]" = None
|
|
194
|
+
status: "typing.Union[str, None]" = None
|
|
147
195
|
|
|
148
|
-
def serialize(self) ->
|
|
196
|
+
def serialize(self) -> "JSONDict":
|
|
149
197
|
if self.tool_type == "custom":
|
|
150
|
-
|
|
198
|
+
payload = {
|
|
151
199
|
"type": "custom_tool_call",
|
|
152
200
|
"name": self.name,
|
|
153
201
|
"input": str(self.arguments),
|
|
154
202
|
"call_id": self.call_id,
|
|
155
203
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
204
|
+
else:
|
|
205
|
+
payload = {
|
|
206
|
+
"type": "function_call",
|
|
207
|
+
"name": self.name,
|
|
208
|
+
"arguments": (
|
|
209
|
+
self.raw_arguments
|
|
210
|
+
if self.raw_arguments is not None
|
|
211
|
+
else json.dumps(
|
|
212
|
+
self.arguments,
|
|
213
|
+
ensure_ascii=False,
|
|
214
|
+
separators=(",", ":"),
|
|
215
|
+
)
|
|
216
|
+
),
|
|
217
|
+
"call_id": self.call_id,
|
|
218
|
+
}
|
|
219
|
+
if self.id is not None:
|
|
220
|
+
payload["id"] = self.id
|
|
221
|
+
if self.namespace is not None:
|
|
222
|
+
payload["namespace"] = self.namespace
|
|
223
|
+
if self.tool_type == "custom" and self.status is not None:
|
|
224
|
+
payload["status"] = self.status
|
|
225
|
+
return payload
|
|
166
226
|
|
|
167
227
|
|
|
168
|
-
@dataclass(
|
|
228
|
+
@dataclass(
|
|
229
|
+
frozen=True,
|
|
230
|
+
)
|
|
169
231
|
class ReasoningItem:
|
|
170
232
|
"""何时:模型在一次 Responses 采样里产出 reasoning item 时产生。
|
|
171
233
|
发送方:ModelClient。
|
|
@@ -173,30 +235,41 @@ class ReasoningItem:
|
|
|
173
235
|
ModelClient。
|
|
174
236
|
"""
|
|
175
237
|
|
|
176
|
-
payload:
|
|
238
|
+
payload: "JSONDict"
|
|
177
239
|
kind: 'Literal["reasoning"]' = "reasoning"
|
|
178
240
|
|
|
179
|
-
def serialize(self) ->
|
|
180
|
-
|
|
241
|
+
def serialize(self) -> "JSONDict":
|
|
242
|
+
payload = deepcopy(self.payload)
|
|
243
|
+
payload.setdefault("content", None)
|
|
244
|
+
payload.setdefault("encrypted_content", None)
|
|
245
|
+
if payload["content"] is not None and not any(
|
|
246
|
+
item.get("type") == "reasoning_text" for item in payload["content"]
|
|
247
|
+
):
|
|
248
|
+
del payload["content"]
|
|
249
|
+
return payload
|
|
181
250
|
|
|
182
251
|
|
|
183
|
-
@dataclass(
|
|
252
|
+
@dataclass(
|
|
253
|
+
frozen=True,
|
|
254
|
+
)
|
|
184
255
|
class ToolResult:
|
|
185
256
|
"""何时:某个 `ToolCall` 执行完成后产生,用于喂回下一轮模型调用。
|
|
186
257
|
发送方:ToolRegistry 产出,Agent 追加并转发。
|
|
187
258
|
接收方:Agent 先接收,随后 ModelClient 在下一轮 `Prompt.input` 中看到它。
|
|
188
259
|
"""
|
|
189
260
|
|
|
190
|
-
call_id:
|
|
191
|
-
name:
|
|
192
|
-
output:
|
|
193
|
-
content_items:
|
|
194
|
-
|
|
195
|
-
|
|
261
|
+
call_id: "str"
|
|
262
|
+
name: "str"
|
|
263
|
+
output: "JSONValue"
|
|
264
|
+
content_items: "typing.Union[typing.Tuple[JSONDict, ...], None]" = None
|
|
265
|
+
# Local execution metadata; not part of a Responses API input item.
|
|
266
|
+
success: "typing.Union[bool, None]" = None
|
|
267
|
+
is_error: "bool" = False
|
|
196
268
|
tool_type: 'Literal["function", "custom"]' = "function"
|
|
197
269
|
kind: 'Literal["tool_result"]' = "tool_result"
|
|
270
|
+
id: "typing.Union[str, None]" = None
|
|
198
271
|
|
|
199
|
-
def output_text(self) ->
|
|
272
|
+
def output_text(self) -> "str":
|
|
200
273
|
if self.content_items is not None:
|
|
201
274
|
text_parts = [
|
|
202
275
|
str(item.get("text", ""))
|
|
@@ -212,8 +285,8 @@ class ToolResult:
|
|
|
212
285
|
return self.output
|
|
213
286
|
return json.dumps(self.output, ensure_ascii=False)
|
|
214
287
|
|
|
215
|
-
def serialize(self) ->
|
|
216
|
-
payload_output:
|
|
288
|
+
def serialize(self) -> "JSONDict":
|
|
289
|
+
payload_output: "JSONValue"
|
|
217
290
|
if self.content_items is not None:
|
|
218
291
|
payload_output = list(self.content_items)
|
|
219
292
|
elif isinstance(self.output, str):
|
|
@@ -235,106 +308,73 @@ class ToolResult:
|
|
|
235
308
|
"call_id": self.call_id,
|
|
236
309
|
"output": payload_output,
|
|
237
310
|
}
|
|
238
|
-
if self.
|
|
239
|
-
payload["
|
|
311
|
+
if self.id is not None:
|
|
312
|
+
payload["id"] = self.id
|
|
240
313
|
if self.tool_type == "custom":
|
|
241
314
|
payload["name"] = self.name
|
|
242
315
|
return payload
|
|
243
316
|
|
|
244
317
|
|
|
245
|
-
ConversationItem:
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
318
|
+
ConversationItem: "TypeAlias" = typing.Union[
|
|
319
|
+
typing.Union[
|
|
320
|
+
typing.Union[
|
|
321
|
+
typing.Union[typing.Union[UserMessage, AssistantMessage], ContextMessage],
|
|
322
|
+
ToolCall,
|
|
323
|
+
],
|
|
324
|
+
ReasoningItem,
|
|
325
|
+
],
|
|
326
|
+
ToolResult,
|
|
327
|
+
]
|
|
328
|
+
ModelOutputItem: "TypeAlias" = typing.Union[
|
|
329
|
+
typing.Union[AssistantMessage, ToolCall], ReasoningItem
|
|
330
|
+
]
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
@dataclass(
|
|
334
|
+
frozen=True,
|
|
335
|
+
)
|
|
251
336
|
class Prompt:
|
|
252
337
|
"""何时:Agent 每发起一轮模型采样前构造。
|
|
253
338
|
发送方:Agent。
|
|
254
339
|
接收方:ModelClient。
|
|
255
340
|
"""
|
|
256
341
|
|
|
257
|
-
input:
|
|
258
|
-
tools:
|
|
259
|
-
parallel_tool_calls:
|
|
260
|
-
base_instructions:
|
|
261
|
-
turn_id:
|
|
262
|
-
turn_metadata:
|
|
342
|
+
input: "typing.List[ConversationItem]"
|
|
343
|
+
tools: "typing.List[ToolSpec]"
|
|
344
|
+
parallel_tool_calls: "bool" = True
|
|
345
|
+
base_instructions: "typing.Union[str, None]" = None
|
|
346
|
+
turn_id: "typing.Union[str, None]" = None
|
|
347
|
+
turn_metadata: "typing.Union[JSONDict, None]" = None
|
|
263
348
|
|
|
264
349
|
|
|
265
|
-
@dataclass(
|
|
350
|
+
@dataclass(
|
|
351
|
+
frozen=True,
|
|
352
|
+
)
|
|
266
353
|
class ModelResponse:
|
|
267
354
|
"""何时:ModelClient 完成一轮 `Prompt` 处理后返回。
|
|
268
355
|
发送方:ModelClient。
|
|
269
356
|
接收方:Agent。
|
|
270
357
|
"""
|
|
271
358
|
|
|
272
|
-
items:
|
|
273
|
-
|
|
359
|
+
items: "typing.List[ModelOutputItem]"
|
|
274
360
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
接收方:Agent。
|
|
280
|
-
"""
|
|
361
|
+
def __post_init__(self) -> "None":
|
|
362
|
+
for item in self.items:
|
|
363
|
+
if not isinstance(item, (AssistantMessage, ToolCall, ReasoningItem)):
|
|
364
|
+
raise TypeError(f"invalid model output item: {type(item).__name__}")
|
|
281
365
|
|
|
282
|
-
kind: 'str'
|
|
283
|
-
payload: 'JSONDict' = field(default_factory=dict)
|
|
284
366
|
|
|
285
|
-
|
|
286
|
-
|
|
367
|
+
@dataclass(
|
|
368
|
+
frozen=True,
|
|
369
|
+
)
|
|
287
370
|
class TurnResult:
|
|
288
371
|
"""何时:一个 turn 已经收敛,Agent 决定结束本轮时返回。
|
|
289
372
|
发送方:Agent。
|
|
290
373
|
接收方:外部调用方。
|
|
291
374
|
"""
|
|
292
375
|
|
|
293
|
-
turn_id:
|
|
294
|
-
output_text:
|
|
295
|
-
iterations:
|
|
296
|
-
response_items:
|
|
297
|
-
history:
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
@dataclass(frozen=True, )
|
|
301
|
-
class AgentEvent:
|
|
302
|
-
"""何时:主循环运行过程中发生阶段性事件时发出,例如模型调用、工具开始/结束。
|
|
303
|
-
发送方:Agent。
|
|
304
|
-
接收方:可选的事件观察者 / 回调。
|
|
305
|
-
"""
|
|
306
|
-
|
|
307
|
-
kind: 'str'
|
|
308
|
-
turn_id: 'str'
|
|
309
|
-
payload: 'typing.Dict[str, object]' = field(default_factory=dict)
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
@dataclass(frozen=True, )
|
|
313
|
-
class UserTurnOp:
|
|
314
|
-
"""何时:运行时要提交一个新的用户请求时创建。
|
|
315
|
-
发送方:外部运行时调用方。
|
|
316
|
-
接收方:AgentRuntime。
|
|
317
|
-
"""
|
|
318
|
-
|
|
319
|
-
texts: 'typing.List[str]'
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
@dataclass(frozen=True, )
|
|
323
|
-
class ShutdownOp:
|
|
324
|
-
"""何时:运行时要停止外层提交循环时创建。
|
|
325
|
-
发送方:外部运行时调用方。
|
|
326
|
-
接收方:AgentRuntime。
|
|
327
|
-
"""
|
|
328
|
-
|
|
329
|
-
pass
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
@dataclass(frozen=True, )
|
|
333
|
-
class Submission:
|
|
334
|
-
"""何时:任意运行时操作要进入 AgentRuntime 队列时创建。
|
|
335
|
-
发送方:外部运行时调用方。
|
|
336
|
-
接收方:AgentRuntime 的提交队列 / 外层循环。
|
|
337
|
-
"""
|
|
338
|
-
|
|
339
|
-
id: 'str'
|
|
340
|
-
op: 'Operation'
|
|
376
|
+
turn_id: "str"
|
|
377
|
+
output_text: "typing.Union[str, None]"
|
|
378
|
+
iterations: "int"
|
|
379
|
+
response_items: "typing.Tuple[ModelOutputItem, ...]"
|
|
380
|
+
history: "typing.Tuple[ConversationItem, ...]"
|