agent-builder-gateway-sdk 0.5.0__tar.gz

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 (24) hide show
  1. agent_builder_gateway_sdk-0.5.0/.github/workflows/publish.yml +52 -0
  2. agent_builder_gateway_sdk-0.5.0/.github/workflows/test.yml +48 -0
  3. agent_builder_gateway_sdk-0.5.0/.gitignore +55 -0
  4. agent_builder_gateway_sdk-0.5.0/LICENSE +22 -0
  5. agent_builder_gateway_sdk-0.5.0/PKG-INFO +528 -0
  6. agent_builder_gateway_sdk-0.5.0/README.md +508 -0
  7. agent_builder_gateway_sdk-0.5.0/RELEASE_GUIDE.md +197 -0
  8. agent_builder_gateway_sdk-0.5.0/SDK_IMPROVEMENTS.md +253 -0
  9. agent_builder_gateway_sdk-0.5.0/agent-builder-gateway-sdk-guide.md +1010 -0
  10. agent_builder_gateway_sdk-0.5.0/examples/basic_usage.py +170 -0
  11. agent_builder_gateway_sdk-0.5.0/examples/file_operations.py +199 -0
  12. agent_builder_gateway_sdk-0.5.0/examples/response_parsing.py +195 -0
  13. agent_builder_gateway_sdk-0.5.0/examples/streaming.py +193 -0
  14. agent_builder_gateway_sdk-0.5.0/examples/test_file_parsing.py +89 -0
  15. agent_builder_gateway_sdk-0.5.0/pyproject.toml +52 -0
  16. agent_builder_gateway_sdk-0.5.0/src/gateway_sdk/__init__.py +34 -0
  17. agent_builder_gateway_sdk-0.5.0/src/gateway_sdk/auth.py +49 -0
  18. agent_builder_gateway_sdk-0.5.0/src/gateway_sdk/client.py +709 -0
  19. agent_builder_gateway_sdk-0.5.0/src/gateway_sdk/exceptions.py +87 -0
  20. agent_builder_gateway_sdk-0.5.0/src/gateway_sdk/models.py +213 -0
  21. agent_builder_gateway_sdk-0.5.0/src/gateway_sdk/streaming.py +41 -0
  22. agent_builder_gateway_sdk-0.5.0/tests/__init__.py +2 -0
  23. agent_builder_gateway_sdk-0.5.0/tests/test_models.py +50 -0
  24. agent_builder_gateway_sdk-0.5.0/uv.lock +632 -0
@@ -0,0 +1,52 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ permissions:
9
+ contents: write
10
+
11
+ jobs:
12
+ build-and-publish:
13
+ runs-on: ubuntu-latest
14
+
15
+ steps:
16
+ - name: Checkout code
17
+ uses: actions/checkout@v4
18
+
19
+ - name: Set up Python
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: '3.11'
23
+
24
+ - name: Install uv
25
+ run: |
26
+ curl -LsSf https://astral.sh/uv/install.sh | sh
27
+ echo "$HOME/.cargo/bin" >> $GITHUB_PATH
28
+
29
+ - name: Install dependencies
30
+ run: |
31
+ uv sync --dev
32
+
33
+ - name: Build package
34
+ run: |
35
+ uv build
36
+
37
+ - name: Publish to PyPI
38
+ env:
39
+ TWINE_USERNAME: __token__
40
+ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
41
+ run: |
42
+ uv pip install twine
43
+ uv run twine upload dist/*
44
+
45
+ - name: Create GitHub Release
46
+ uses: softprops/action-gh-release@v1
47
+ with:
48
+ files: dist/*
49
+ generate_release_notes: true
50
+ env:
51
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
52
+
@@ -0,0 +1,48 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [ main, master ]
6
+ pull_request:
7
+ branches: [ main, master ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ['3.11', '3.12']
15
+
16
+ steps:
17
+ - name: Checkout code
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Set up Python ${{ matrix.python-version }}
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: ${{ matrix.python-version }}
24
+
25
+ - name: Install uv
26
+ run: |
27
+ curl -LsSf https://astral.sh/uv/install.sh | sh
28
+ echo "$HOME/.cargo/bin" >> $GITHUB_PATH
29
+
30
+ - name: Install dependencies
31
+ run: |
32
+ uv sync --dev
33
+
34
+ - name: Run linters
35
+ run: |
36
+ uv run ruff check src/
37
+ uv run mypy src/
38
+
39
+ - name: Run tests
40
+ run: |
41
+ uv run pytest tests/ -v --cov=gateway_sdk --cov-report=xml
42
+
43
+ - name: Upload coverage
44
+ uses: codecov/codecov-action@v3
45
+ with:
46
+ file: ./coverage.xml
47
+ fail_ci_if_error: false
48
+
@@ -0,0 +1,55 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+ MANIFEST
23
+
24
+ # Virtual Environment
25
+ venv/
26
+ ENV/
27
+ env/
28
+ .venv
29
+
30
+ # IDEs
31
+ .vscode/
32
+ .idea/
33
+ *.swp
34
+ *.swo
35
+ *~
36
+ .DS_Store
37
+
38
+ # Testing
39
+ .pytest_cache/
40
+ .coverage
41
+ htmlcov/
42
+ .tox/
43
+
44
+ # Type checking
45
+ .mypy_cache/
46
+ .dmypy.json
47
+ dmypy.json
48
+
49
+ # uv
50
+ .uv/
51
+
52
+ # Distribution
53
+ *.whl
54
+ *.tar.gz
55
+
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Agent Builder Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,528 @@
1
+ Metadata-Version: 2.4
2
+ Name: agent-builder-gateway-sdk
3
+ Version: 0.5.0
4
+ Summary: Python SDK for Agent Builder Gateway - 用于 AI 构建的程序调用预制件
5
+ Author: Agent Builder Team
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.11
9
+ Requires-Dist: httpx>=0.27.0
10
+ Requires-Dist: pydantic>=2.0.0
11
+ Requires-Dist: python-dotenv>=1.0.0
12
+ Provides-Extra: dev
13
+ Requires-Dist: black>=24.0.0; extra == 'dev'
14
+ Requires-Dist: mypy>=1.8.0; extra == 'dev'
15
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
16
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
17
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
18
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
19
+ Description-Content-Type: text/markdown
20
+
21
+ # Gateway SDK
22
+
23
+ Python SDK for Gateway - 用于调用预制件
24
+
25
+ ## 概述
26
+
27
+ Gateway SDK 是一个用于调用预制件的 Python SDK。
28
+
29
+ ### 核心特性
30
+
31
+ - ✅ 简洁的 API
32
+ - ✅ 支持 JWT Token 和 API Key 认证
33
+ - ✅ 流式响应支持(SSE)
34
+ - ✅ 完整的类型提示
35
+ - ✅ 完善的错误处理
36
+
37
+ ## 安装
38
+
39
+ ```bash
40
+ pip install agent-builder-gateway-sdk
41
+ ```
42
+
43
+ ## 快速开始
44
+
45
+ ### 初始化客户端
46
+
47
+ ```python
48
+ from gateway_sdk import GatewayClient
49
+
50
+ # 使用 JWT Token
51
+ client = GatewayClient(jwt_token="your-jwt-token")
52
+
53
+ # 或使用 API Key
54
+ client = GatewayClient(api_key="sk-xxx")
55
+
56
+ # 白名单模式(适用于 OpenHands 等白名单环境)
57
+ client = GatewayClient() # 无需提供认证信息
58
+ ```
59
+
60
+ **白名单模式说明**:
61
+ - 如果你的环境已配置白名单(如 OpenHands、内部开发环境),可以直接创建客户端而无需提供认证信息
62
+ - SDK 会以无鉴权模式发送请求,由 Gateway 基于 IP 白名单进行验证
63
+ - 这种模式简化了开发流程,无需管理 token
64
+
65
+ ### 调用预制件
66
+
67
+ ```python
68
+ result = client.run(
69
+ prefab_id="llm-client",
70
+ version="1.0.0",
71
+ function_name="chat",
72
+ parameters={"messages": [{"role": "user", "content": "Hello"}]}
73
+ )
74
+
75
+ if result.is_success():
76
+ print(result.get_result())
77
+ else:
78
+ print(f"Error: {result.error}")
79
+ ```
80
+
81
+ ### 链式调用
82
+
83
+ ```python
84
+ llm = client.prefab("llm-client", "1.0.0")
85
+ result = llm.call("chat", messages=[...], model="gpt-4")
86
+ ```
87
+
88
+ ### 流式响应
89
+
90
+ ```python
91
+ for event in client.run(..., stream=True):
92
+ if event.type == "content":
93
+ print(event.data, end="", flush=True)
94
+ elif event.type == "done":
95
+ print("\n完成")
96
+ ```
97
+
98
+ ### 批量调用
99
+
100
+ ```python
101
+ from gateway_sdk import PrefabCall
102
+
103
+ calls = [
104
+ PrefabCall(
105
+ prefab_id="translator",
106
+ version="1.0.0",
107
+ function_name="translate",
108
+ parameters={"text": "Hello", "target": "zh"}
109
+ ),
110
+ PrefabCall(
111
+ prefab_id="translator",
112
+ version="1.0.0",
113
+ function_name="translate",
114
+ parameters={"text": "World", "target": "zh"}
115
+ )
116
+ ]
117
+
118
+ result = client.run_batch(calls)
119
+ for r in result.results:
120
+ if r.is_success():
121
+ print(r.get_result())
122
+ ```
123
+
124
+ ### 文件处理
125
+
126
+ **重要**: SDK 只接收 S3 URL,不负责文件上传/下载。
127
+
128
+ ```python
129
+ # 传递 S3 URL 作为文件输入
130
+ result = client.run(
131
+ prefab_id="video-processor",
132
+ version="1.0.0",
133
+ function_name="extract_audio",
134
+ parameters={"format": "mp3"},
135
+ files={"video": ["s3://bucket/input.mp4"]}
136
+ )
137
+
138
+ # 输出文件也是 S3 URL
139
+ output_files = result.get_files()
140
+ # {"audio": ["s3://bucket/output.mp3"]}
141
+ ```
142
+
143
+ **文件处理流程**:
144
+ 1. 📤 使用 S3 客户端上传文件,获取 S3 URL
145
+ 2. 📝 将 S3 URL 传递给 SDK
146
+ 3. 📥 从返回的 S3 URL 下载结果文件
147
+
148
+ ---
149
+
150
+ ## 🆕 Agent 文件操作(新特性)
151
+
152
+ **适用场景**: Agent 内部需要上传、下载、管理文件。
153
+
154
+ **核心特性**:
155
+ - ✅ 永久文件存储(agent-outputs)
156
+ - ✅ 临时文件支持(agent-workspace,自动删除)
157
+ - ✅ Session 管理(批量清理中间文件)
158
+ - ✅ 预签名 URL(直接下载)
159
+
160
+ ### 初始化(Agent 专用)
161
+
162
+ ```python
163
+ from gateway_sdk import GatewayClient
164
+ import os
165
+
166
+ # Agent 从请求头获取 internal_token
167
+ internal_token = os.environ.get("X_INTERNAL_TOKEN")
168
+
169
+ # 初始化客户端(internal_token 已包含 user_id 和 agent_id)
170
+ client = GatewayClient(internal_token=internal_token)
171
+ ```
172
+
173
+ ### 上传永久文件
174
+
175
+ ```python
176
+ # 上传最终输出文件到 agent-outputs
177
+ result = client.upload_file("/tmp/result.pdf")
178
+
179
+ print(result["s3_url"]) # s3://bucket/agent-outputs/{user_id}/{agent_id}/...
180
+ print(result["filename"]) # result.pdf
181
+ print(result["size"]) # 文件大小(字节)
182
+ ```
183
+
184
+ ### 上传临时文件
185
+
186
+ ```python
187
+ import uuid
188
+
189
+ # 创建 session ID(用于批量管理)
190
+ session_id = str(uuid.uuid4())
191
+
192
+ # 上传中间文件(默认 24 小时后自动删除)
193
+ result = client.upload_temp_file(
194
+ "/tmp/intermediate.jpg",
195
+ ttl=3600, # 1 小时后删除
196
+ session_id=session_id # 关联到 session
197
+ )
198
+
199
+ print(result["s3_url"]) # s3://bucket/agent-workspace/{user_id}/{agent_id}/{session_id}/...
200
+ ```
201
+
202
+ ### 下载文件
203
+
204
+ ```python
205
+ # 下载文件(支持所有 S3 URL)
206
+ client.download_file(
207
+ "s3://bucket/agent-outputs/user123/agent456/result.pdf",
208
+ "/tmp/downloaded_result.pdf"
209
+ )
210
+
211
+ # 或获取预签名 URL(推荐,适合大文件)
212
+ presigned_url = client.get_presigned_url(
213
+ "s3://bucket/agent-outputs/...",
214
+ expires_in=3600 # 1 小时有效期
215
+ )
216
+ # 可以直接用 presigned_url 下载
217
+ ```
218
+
219
+ ### 列出文件
220
+
221
+ ```python
222
+ # 列出永久文件
223
+ result = client.list_files(limit=100)
224
+ for file in result["files"]:
225
+ print(file["s3_url"], file["size"], file["last_modified"])
226
+
227
+ # 翻页
228
+ if "next_token" in result:
229
+ next_page = client.list_files(limit=100, continuation_token=result["next_token"])
230
+ ```
231
+
232
+ ### 列出临时文件
233
+
234
+ ```python
235
+ # 列出指定 session 的临时文件
236
+ result = client.list_temp_files(session_id=session_id)
237
+ for file in result["files"]:
238
+ print(file["s3_url"])
239
+ ```
240
+
241
+ ### 清理临时文件
242
+
243
+ ```python
244
+ # 任务完成后立即清理 session 的所有临时文件
245
+ deleted_count = client.cleanup_temp_files(session_id=session_id)
246
+ print(f"清理了 {deleted_count} 个临时文件")
247
+ ```
248
+
249
+ ### 完整工作流示例
250
+
251
+ ```python
252
+ import uuid
253
+ from gateway_sdk import GatewayClient
254
+
255
+ # 1. 初始化
256
+ client = GatewayClient(internal_token=os.environ["X_INTERNAL_TOKEN"])
257
+
258
+ # 2. 创建 session
259
+ session_id = str(uuid.uuid4())
260
+
261
+ try:
262
+ # 3. 下载输入文件(前端上传或其他 Agent 传入)
263
+ client.download_file("s3://bucket/agent-inputs/.../input.mp4", "/tmp/input.mp4")
264
+
265
+ # 4. 处理并上传中间文件(临时)
266
+ # 假设提取音频
267
+ extract_audio("/tmp/input.mp4", "/tmp/audio.wav")
268
+ audio_result = client.upload_temp_file("/tmp/audio.wav", session_id=session_id)
269
+
270
+ # 假设提取帧
271
+ extract_frame("/tmp/input.mp4", "/tmp/frame.jpg")
272
+ frame_result = client.upload_temp_file("/tmp/frame.jpg", session_id=session_id)
273
+
274
+ # 5. 处理完成,上传最终结果(永久)
275
+ process_video("/tmp/input.mp4", "/tmp/output.mp4")
276
+ output_result = client.upload_file("/tmp/output.mp4")
277
+
278
+ # 6. 清理临时文件
279
+ client.cleanup_temp_files(session_id=session_id)
280
+
281
+ # 7. 返回结果 S3 URL
282
+ return {"output_url": output_result["s3_url"]}
283
+
284
+ except Exception as e:
285
+ # 出错时也要清理临时文件
286
+ client.cleanup_temp_files(session_id=session_id)
287
+ raise
288
+ ```
289
+
290
+ **最佳实践**:
291
+ 1. 🗑️ 使用 `session_id` 管理临时文件,任务完成后立即清理
292
+ 2. ⏰ 根据文件大小合理设置 `ttl`(避免浪费存储)
293
+ 3. 📦 最终输出文件使用 `upload_file()`(永久存储)
294
+ 4. 🔒 中间文件使用 `upload_temp_file()`(自动清理)
295
+
296
+ ---
297
+
298
+ ## 🌐 第三方集成(使用 API Key)
299
+
300
+ **适用场景**: 外部应用集成预制件生态(网站、脚本、CI/CD 等)
301
+
302
+ ### 快速开始
303
+
304
+ ```python
305
+ from gateway_sdk import GatewayClient
306
+
307
+ # 使用 API Key 初始化(自动转换为 internal_token)
308
+ client = GatewayClient.from_api_key("sk-xxx")
309
+
310
+ # 上传输入文件
311
+ s3_url = client.upload_input_file("/tmp/video.mp4", content_type="video/mp4")
312
+
313
+ # 调用 Prefab
314
+ result = client.run(
315
+ prefab_id="video-processor",
316
+ version="1.0.0",
317
+ function_name="extract_audio",
318
+ parameters={"format": "mp3"},
319
+ files={"video": [s3_url]}
320
+ )
321
+
322
+ print(result.get_result())
323
+ ```
324
+
325
+ ### 完整示例
326
+
327
+ ```python
328
+ from gateway_sdk import GatewayClient, AgentContextRequiredError
329
+
330
+ # 初始化
331
+ client = GatewayClient.from_api_key("sk-xxx")
332
+
333
+ try:
334
+ # 1. 上传输入文件
335
+ video_url = client.upload_input_file("/tmp/input.mp4", content_type="video/mp4")
336
+ print(f"Uploaded: {video_url}")
337
+
338
+ # 2. 调用 Prefab 处理
339
+ result = client.run(
340
+ prefab_id="video-processor",
341
+ version="1.0.0",
342
+ function_name="extract_audio",
343
+ parameters={"format": "mp3"},
344
+ files={"video": [video_url]}
345
+ )
346
+
347
+ # 3. 获取输出文件
348
+ if result.is_success():
349
+ output_files = result.get_files()
350
+ print(f"Output: {output_files}")
351
+ else:
352
+ print(f"Error: {result.error}")
353
+
354
+ except AgentContextRequiredError as e:
355
+ # 文件操作需要 Agent context(第三方集成不支持)
356
+ print(f"不支持的操作: {e}")
357
+ print("请使用 upload_input_file() 上传输入文件")
358
+ ```
359
+
360
+ ### 注意事项
361
+
362
+ **第三方集成的限制**:
363
+ - ✅ 可以调用任何 Prefab
364
+ - ✅ 可以上传输入文件(`upload_input_file()`)
365
+ - ❌ 不能使用 Agent 文件操作(`upload_file()`, `upload_temp_file()` 等)
366
+ - 这些操作需要 Agent context,仅在生产环境(Agent invoke)中可用
367
+
368
+ **与 Agent 开发的区别**:
369
+
370
+ | 特性 | 第三方集成 | Agent 开发 |
371
+ |------|-----------|-----------|
372
+ | 初始化 | `from_api_key()` | `GatewayClient(internal_token)` |
373
+ | 调用 Prefab | ✅ 支持 | ✅ 支持 |
374
+ | 上传输入 | `upload_input_file()` | ✅ 任意上传 |
375
+ | Agent 文件操作 | ❌ 不支持 | ✅ 支持 |
376
+
377
+ ---
378
+
379
+ ## API 参考
380
+
381
+ ### GatewayClient
382
+
383
+ #### 初始化
384
+
385
+ ```python
386
+ GatewayClient(
387
+ base_url: str = "http://nodeport.sensedeal.vip:30566",
388
+ api_key: Optional[str] = None,
389
+ jwt_token: Optional[str] = None,
390
+ timeout: int = 60
391
+ )
392
+ ```
393
+
394
+ **参数**:
395
+ - `api_key`: API Key
396
+ - `jwt_token`: JWT Token
397
+ - `timeout`: 请求超时时间(秒)
398
+
399
+ **注意**:必须提供 `api_key` 或 `jwt_token` 之一。
400
+
401
+ #### 方法
402
+
403
+ **run()** - 执行单个预制件
404
+
405
+ ```python
406
+ run(
407
+ prefab_id: str,
408
+ version: str,
409
+ function_name: str,
410
+ parameters: Dict[str, Any],
411
+ files: Optional[Dict[str, List[str]]] = None, # 仅接受 S3 URL
412
+ stream: bool = False
413
+ ) -> Union[PrefabResult, Iterator[StreamEvent]]
414
+ ```
415
+
416
+ 参数:
417
+ - `files`: 文件输入,格式为 `{"参数名": ["s3://url1", "s3://url2"]}`,**仅接受 S3 URL**
418
+
419
+ **run_batch()** - 批量执行
420
+
421
+ ```python
422
+ run_batch(calls: List[PrefabCall]) -> BatchResult
423
+ ```
424
+
425
+ **prefab()** - 获取预制件对象
426
+
427
+ ```python
428
+ prefab(prefab_id: str, version: str) -> Prefab
429
+ ```
430
+
431
+ **list_prefabs()** - 列出预制件
432
+
433
+ ```python
434
+ list_prefabs(status: Optional[str] = None) -> List[PrefabInfo]
435
+ ```
436
+
437
+ **get_prefab_spec()** - 获取预制件规格
438
+
439
+ ```python
440
+ get_prefab_spec(prefab_id: str, version: Optional[str] = None) -> Dict[str, Any]
441
+ ```
442
+
443
+ ### PrefabResult
444
+
445
+ 预制件执行结果。
446
+
447
+ **属性**:
448
+ - `status`: 调用状态(SUCCESS / FAILED)
449
+ - `output`: 输出数据
450
+ - `error`: 错误信息
451
+ - `job_id`: 任务 ID
452
+
453
+ **方法**:
454
+ - `is_success()`: 判断是否成功
455
+ - `get(key, default)`: 获取输出字段
456
+ - `get_result()`: 获取业务结果
457
+ - `get_files()`: 获取输出文件
458
+
459
+ ### StreamEvent
460
+
461
+ 流式事件。
462
+
463
+ **属性**:
464
+ - `type`: 事件类型(start / content / progress / done / error)
465
+ - `data`: 事件数据
466
+
467
+ ## 错误处理
468
+
469
+ ```python
470
+ from gateway_sdk.exceptions import (
471
+ GatewayError,
472
+ AuthenticationError,
473
+ PrefabNotFoundError,
474
+ ValidationError,
475
+ QuotaExceededError,
476
+ ServiceUnavailableError,
477
+ MissingSecretError,
478
+ )
479
+
480
+ try:
481
+ result = client.run(...)
482
+ except AuthenticationError as e:
483
+ print(f"认证失败: {e}")
484
+ except PrefabNotFoundError as e:
485
+ print(f"预制件不存在: {e}")
486
+ except MissingSecretError as e:
487
+ print(f"缺少密钥: {e.secret_name}")
488
+ except QuotaExceededError as e:
489
+ print(f"配额超限: {e.used}/{e.limit}")
490
+ except GatewayError as e:
491
+ print(f"错误: {e}")
492
+ ```
493
+
494
+ ## 示例代码
495
+
496
+ - `examples/basic_usage.py` - 基础用法
497
+ - `examples/streaming.py` - 流式响应
498
+ - `examples/file_operations.py` - 文件操作(Agent 专用)
499
+
500
+ ## 常见问题
501
+
502
+ **Q: 如何处理超时?**
503
+
504
+ A: 设置 `timeout` 参数:
505
+ ```python
506
+ client = GatewayClient(jwt_token="...", timeout=120)
507
+ ```
508
+
509
+ **Q: 如何调试?**
510
+
511
+ A: 启用日志:
512
+ ```python
513
+ import logging
514
+ logging.basicConfig(level=logging.DEBUG)
515
+ ```
516
+
517
+ **Q: 如何停止流式响应?**
518
+
519
+ A: 使用 `break` 跳出循环:
520
+ ```python
521
+ for event in client.run(..., stream=True):
522
+ if some_condition:
523
+ break
524
+ ```
525
+
526
+ ## 许可证
527
+
528
+ MIT License