Skip to content

Commit def9b92

Browse files
jerannclaude
andcommitted
docs(readme): document file-download return shape from tool execution
Add a "File Downloads" section covering the bytes-plus-metadata dict that execute()/call() return for non-JSON responses, the Content-Type detection rule, and the not-JSON-serializable caveat for LLM-facing re-serialization. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 67199ed commit def9b92

1 file changed

Lines changed: 29 additions & 0 deletions

File tree

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,35 @@ tools = toolset.fetch_tools(providers=["hibob"])
114114
- Glob pattern: `["*_list_employees"]` matches all tools ending with `_list_employees`
115115
- Provider prefix: `["workday_*"]` matches all Workday tools
116116

117+
## File Downloads
118+
119+
Actions that return a file — e.g. `googledrive_unified_download_file`, `documents_download_file`, any `*_unified_download_file` — resolve to **raw bytes plus metadata**, not parsed JSON. The SDK decides this from the response `Content-Type`: a JSON content type is parsed as before; anything else is treated as a file download. This applies to both `tool.execute()` and `tool.call()`.
120+
121+
```python
122+
tools = toolset.fetch_tools(actions=["googledrive_*"], account_ids=[account_id])
123+
download = tools.get_tool("googledrive_unified_download_file")
124+
125+
result = download.execute({"id": "file-id"})
126+
127+
# `result` is a dict describing the file — write the bytes straight to disk:
128+
with open(result["file_name"] or "download.bin", "wb") as f:
129+
f.write(result["content"])
130+
```
131+
132+
The returned dict:
133+
134+
| Key | Type | Description |
135+
| -------------- | ------------- | -------------------------------------------------------------------------------------------- |
136+
| `content` | `bytes` | Raw file bytes. **Not JSON-serializable** — see the caveat below. |
137+
| `content_type` | `str` | The file's MIME type (e.g. `application/pdf`), or `application/octet-stream` if unspecified. |
138+
| `status_code` | `int` | HTTP status of the download response. |
139+
| `headers` | `dict` | Response headers. |
140+
| `file_name` | `str \| None` | Filename from the `Content-Disposition` header (handles RFC 5987 `filename*`), else `None`. |
141+
142+
> **Caveat:** `content` holds raw bytes, which are not JSON-serializable. If you forward tool results to an LLM — or anywhere that re-serializes them to JSON — handle or strip the `content` key (for example, base64-encode it on the LLM-facing path).
143+
144+
JSON responses are unchanged: any action returning `application/json` (or a `…+json` type) is parsed and returned as a dict exactly as before.
145+
117146
## Implicit Feedback (Beta)
118147

119148
The Python SDK can emit implicit behavioral feedback to LangSmith so you can triage low-quality tool results without manually tagging runs.

0 commit comments

Comments
 (0)