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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ existing `0.1.0` release; earlier development prereleases are not listed.

## [Unreleased]

### Added

- Forward Vault Credential updates for secret rotation and metadata merge patches, with automatic retries disabled for write-only updates.
- Forward Usage aggregation by Identity and Template using hourly `start_at` / `end_at` windows in Asia/Shanghai, with fractional `active_seconds` and multi-ID filters. Legacy timestamp parameters are not exposed.
- Managed Session cancellation with the lightweight acknowledgement for both active and idle sessions, plus deployment-scoped Run listing and retrieval.

## [0.2.0] - 2026-09-24

### Added
Expand Down
14 changes: 14 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,20 @@ The default test command excludes account-backed integration tests and must not

Never commit `.env.live`, tokens, credentials, generated logs, or test output. Integration scenarios must register cleanup immediately after creating a resource. Run them explicitly with `QODER_RUN_LIVE=1`; they are not part of public pull-request CI.

`tests/integration/test_api_expansion.py` adds Forward hourly Usage, Credential
merge patches and secret redaction, and Managed Session cancellation before and
after sending a turn. The existing Managed deployment scenario also checks
scoped Run listing/retrieval. These are part of `test-live-all`; cancellation
after sending a turn and deployment scenarios can execute models. Select a
separate `QODER_LIVE_ENV_FILE` with matching URL and PAT for each CN/Global run.

Usage queries the last 24 completed whole hours in Asia/Shanghai in both regions;
empty pages verify only the collection. A Session may finish before cancellation
and return HTTP 200 instead of 202; tests record which response occurred. Those
responses do not prove active cancellation occurred. Cleanup failures remain
failures; offline replay exercises assertions and cleanup without account
credentials.

The Forward and Managed integration files also include six `strict_response_contract` checks using a separate client with `_strict_response_validation=True`: model, template/agent, and session lists. They send only GET requests, inspect the first page with `limit=1` where supported, and allow empty lists. An empty list checks the response envelope; item schemas are checked when items exist. Returned items must have a non-empty string ID, and `data` must be present even when empty. Existing business scenarios continue to use the default lenient response parsing.

To run only these read-only checks:
Expand Down
37 changes: 36 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

The Qoder Cloud Agents Python SDK provides access to the Qoder Cloud Agents API from Python 3.10+. It ships synchronous and natively asynchronous clients, typed request parameters and response models, automatic pagination, SSE streaming, and file transfer.

The API is exposed in two modes, and each has its own client, resources, and types. Forward is multi-tenant: sessions are created from an Identity and a Template, and it adds Schedule, Batch, and Channel. Managed is single-tenant: sessions are created from an Agent and an Environment, and it adds Deployment, Dream, and the Work API for self-hosted environments.
The API is exposed in two modes, and each has its own client, resources, and types. Forward is multi-tenant: sessions are created from an Identity and a Template, and it adds Schedule, Batch, Channel, and Usage. Managed is single-tenant: sessions are created from an Agent and an Environment, and it adds Deployment, Dream, and the Work API for self-hosted environments.

## Installation

Expand Down Expand Up @@ -104,6 +104,41 @@ asyncio.run(main())

Every method shown in this document has an async counterpart with the same name and signature. Async streams are opened with `async with await client.sessions.events.stream(...)`.

## Usage and cancellation

Forward Usage requires PAT or Admin SAT.

```python
with Forward() as client:
for row in client.usage.list_identities(
start_at="2026-09-14T09:00:00", end_at="2026-09-14T12:00:00",
identity_ids=["idn_one", "idn_two"],
):
print(row.identity_id, row.active_seconds, row.credits)

with Managed() as client:
acknowledgement = client.sessions.cancel("sess_one")
for run in client.deployments.runs.list("dep_one", limit=20):
print(run.id)
run = client.deployments.runs.retrieve("drun_one", deployment_id="dep_one")
```

`usage.list_templates` accepts the same filters. Bounds are whole hours in
Asia/Shanghai for CN and Global, with an inclusive start, exclusive end, and a
maximum 744-hour span. Multi-ID filters accept lists or comma-separated strings.
`active_seconds` preserves fractions. Legacy timestamp parameters and
`duration_seconds` are not exposed.

`client.vaults.credentials.update("cred_one", vault_id="vault_one", auth={...})`
rotates write-only secrets; only auth and metadata are patched, and omitted fields
are preserved. `metadata=None` clears metadata; `metadata={"key": None}` deletes a
key. This operation never retries automatically, even if client retries are enabled.

Session cancellation returns the lightweight `canceling` acknowledgement for
active (HTTP 202) and idle (HTTP 200) sessions. The global `deployment_runs` resource
remains available. All new methods also exist on `AsyncForward` / `AsyncManaged`;
await requests or iterate pages with `async for`.

## Sessions

A session is the unit of agent execution. Forward materializes one from an Identity and a Template:
Expand Down
Loading
Loading