Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .env.live.example
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,8 @@ QODER_REALTIME_GLOBAL_SAT=
# Optional raw PCM16 input (16 kHz mono little-endian); otherwise sends short text.
# QODER_REALTIME_CN_PCM_FILE=
# QODER_REALTIME_GLOBAL_PCM_FILE=

# Forward Drive Beta lifecycle (creates isolated Identities; no model execution).
# Uses QODER_FORWARD_CN_PAT, QODER_FORWARD_GLOBAL_PAT, QODER_SA_CN_KEY,
# and QODER_SA_GLOBAL_KEY. Never point clear at a shared Identity.
QODER_DRIVE_LIVE_ALLOW_WRITE=false
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ existing `0.1.0` release; earlier development prereleases are not listed.

## [Unreleased]

### Added

- Forward Drive Beta: typed directory listing, upload/download signed URLs, entry deletion and Drive clearing, with required Identity scope, independent cursor pagination, service ordering and canonical directory query encoding.
- Template `managed_tool_config.enabled_tools` in create/update requests and responses, including omission, empty-list and null semantics. Runnable Drive examples keep storage requests separate from QCA authentication; opt-in CN/Global lifecycle tests cover PAT, admin SAT and Identity SAT.

## [0.5.0]

### Added
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,7 @@ test-live-realtime:

test-live-sa-tokens:
QODER_LIVE_ENV_FILE="$(LIVE_ENV_FILE)" $(PYTHON) -m pytest tests/sa/test_tokens_live.py -m integration -v -s

.PHONY: test-live-drive
test-live-drive:
QODER_DRIVE_RUN_LIVE=1 QODER_LIVE_ENV_FILE="$(LIVE_ENV_FILE)" $(PYTHON) -m pytest tests/integration/test_drive.py -m integration -v -s
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,57 @@ credential = client.vaults.credentials.retrieve("credential-id", vault_id="vault
memory = client.memory_stores.memories.retrieve("memory-id", memory_store_id="store-id")
```

## Forward Drive (Beta)

Drive is a Beta API. It uses `entries` / `next_page_token`, not the ordinary
resource paginator. Pass `identity_id` even with an Identity SAT, preserve the
server order, and reuse a cursor only within the same Identity, directory and
authentication scope. Paths are relative; the SDK preserves slashes when encoding
the list query and leaves path validation to the service.

Upload/download methods return a signed URL, method, headers and expiry. Send the
storage request with a separate HTTP client using only those returned headers;
do not attach QCA credentials or log signed URLs. Replaying an `Idempotency-Key`
does not renew the URL: use a new key or omit it when requesting a fresh URL.

Deleting a nonempty directory requires `recursive=true`; `clear` deletes the
entire selected Identity Drive. Partial failures retain `drive_delete_partial`
and `deleted_count` in the standard API error body. Direct Drive APIs do not
require Template tool configuration.

```python
page = client.drives.list_entries(identity_id=identity_id, path="reports", limit=20)
for entry in page.entries:
print(entry.path)
if page.next_page_token:
page = client.drives.list_entries(
identity_id=identity_id, path="reports", page_token=page.next_page_token,
)
# Replace the complete managed-tool list, retaining any other tools you need.
client.templates.update(template_id, managed_tool_config={"enabled_tools": ["drive"]})
```

`AsyncForward` exposes the same methods with `await`. Run the
[file lifecycle example](examples/forward/drive.py) with
`python -m examples.forward.drive --region cn` (or `global`); it uses the shared
PAT/SA configuration and creates a fresh Identity. A directory has `size=None`;
a zero-byte file has `size=0`.
For maintainers, `uv run make test-live-drive` tests CN/Global × PAT/admin
SAT/Identity SAT with both sync and async clients.

To enable Agent-managed Drive tools, use Template `managed_tool_config.enabled_tools`.
It is separate from `tools[].enabled_tools` and replaces the entire list; an empty
list disables managed tools, omission preserves the setting, and `null` clears it.
Full Agent Drive usage also requires the DeliverArtifacts tool. Internal
`/forward-mcp` routes are invoked by the runtime and are not public SDK methods.

The Drive live suite requires `QODER_DRIVE_LIVE_ALLOW_WRITE=true`,
`QODER_FORWARD_CN_PAT`, `QODER_FORWARD_GLOBAL_PAT`, `QODER_SA_CN_KEY`, and
`QODER_SA_GLOBAL_KEY` in `.env.live` (or `LIVE_ENV_FILE`). It creates isolated
Identities, verifies storage transfers, pagination, deletion, Identity isolation,
and Template configuration, then clears only those new Identities. It does not
run Agent/model tool execution.

## File uploads and downloads

Uploads accept `bytes`, a binary file object, a `Path`, or a `(filename, content[, content type])` tuple. Content is buffered so it can be replayed on retry; a file object you open stays yours to close.
Expand Down
Loading
Loading