diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cf79f4..929af27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,20 @@ existing `0.1.0` release; earlier development prereleases are not listed. ## [Unreleased] +### Fixed + +- Align Managed Session budgets with the official decimal-string `max_credit_cost` contract, shared by Deployment budgets. The limit covers cumulative model and sandbox Credits; reaching it rejects the next user message without interrupting the current turn. +- Expose Managed and Forward Session `model_credits`, `sandbox_runtime_credits`, and `total_credits`; decode top-level `session.usage` Credits and per-call `model_usage.credits` / compaction `usage.credits`. Session usage may be absent. Legacy response token/list-cost fields remain available. +- Route Identity ownership through query parameters on existing Forward Environment, Skill/Version, Vault/Credential, and File operations, including multipart uploads and content downloads. +- Allow existing channel pairing creation with either a code or `channel_pairing_id`, and expose pairing scope details. No additional API endpoints are introduced. + +### Migration + +- **Breaking budget field change:** Replace `{ type: "limit", max_list_cost: {...} }` with `{ type: "limit", max_credit_cost: "100.00" }`. Amounts are positive decimal strings, not currency objects. Omitting a budget update preserves the limit; explicit null removes it. +- Consume the three top-level Credits fields from `session.usage` events. Replace cumulative snapshots rather than adding them; compaction Credits are already included in Session totals. +- Set `identity_id` in resource params; for methods without params, set it in the existing request-options argument. Use this only with a PAT. With a SAT, omit `identity_id`; the server infers ownership from the token and rejects explicit values (including an empty string). +- Channel pairing requests must provide exactly one of `code` or `channel_pairing_id`; existing code-based calls remain supported. + ## [0.6.0] ### Added diff --git a/docs/api/forward/README.md b/docs/api/forward/README.md index d81a5a7..ca32561 100644 --- a/docs/api/forward/README.md +++ b/docs/api/forward/README.md @@ -251,6 +251,7 @@ - [EventContentUnionParam](type-aliases/EventContentUnionParam.md) - [ForwardClientOptions](type-aliases/ForwardClientOptions.md) - [IdentityCreateParams](type-aliases/IdentityCreateParams.md) +- [IdentityScopeOptions](type-aliases/IdentityScopeOptions.md) - [MemoryStoreCreateParams](type-aliases/MemoryStoreCreateParams.md) - [MemoryStoreMemoryCreateParams](type-aliases/MemoryStoreMemoryCreateParams.md) - [ModelConfig](type-aliases/ModelConfig.md) diff --git a/docs/api/forward/classes/Environments.md b/docs/api/forward/classes/Environments.md index b98e9b2..5a49461 100644 --- a/docs/api/forward/classes/Environments.md +++ b/docs/api/forward/classes/Environments.md @@ -56,7 +56,7 @@ Archive an environment retained by historical sessions or tool calls. ##### options? -[`RequestOptions`](../../index/interfaces/RequestOptions.md) +[`IdentityScopeOptions`](../type-aliases/IdentityScopeOptions.md) #### Returns @@ -108,7 +108,7 @@ createEnvironment ##### options? -[`RequestOptions`](../../index/interfaces/RequestOptions.md) +[`IdentityScopeOptions`](../type-aliases/IdentityScopeOptions.md) #### Returns @@ -160,7 +160,7 @@ listEnvironment ##### options? -[`RequestOptions`](../../index/interfaces/RequestOptions.md) +[`IdentityScopeOptions`](../type-aliases/IdentityScopeOptions.md) #### Returns diff --git a/docs/api/forward/classes/Files.md b/docs/api/forward/classes/Files.md index c572314..db71f0a 100644 --- a/docs/api/forward/classes/Files.md +++ b/docs/api/forward/classes/Files.md @@ -56,7 +56,7 @@ ##### options? -[`RequestOptions`](../../index/interfaces/RequestOptions.md) +[`IdentityScopeOptions`](../type-aliases/IdentityScopeOptions.md) #### Returns @@ -82,7 +82,7 @@ deleteFile ##### options? -[`RequestOptions`](../../index/interfaces/RequestOptions.md) +[`IdentityScopeOptions`](../type-aliases/IdentityScopeOptions.md) #### Returns @@ -108,7 +108,7 @@ downloadFile ##### options? -[`RequestOptions`](../../index/interfaces/RequestOptions.md) +[`IdentityScopeOptions`](../type-aliases/IdentityScopeOptions.md) #### Returns diff --git a/docs/api/forward/classes/SkillVersions.md b/docs/api/forward/classes/SkillVersions.md index ea9c447..0d75a72 100644 --- a/docs/api/forward/classes/SkillVersions.md +++ b/docs/api/forward/classes/SkillVersions.md @@ -90,7 +90,7 @@ createSkillVersion ##### options? -[`RequestOptions`](../../index/interfaces/RequestOptions.md) +[`IdentityScopeOptions`](../type-aliases/IdentityScopeOptions.md) #### Returns @@ -120,7 +120,7 @@ deleteSkillVersion ##### options? -[`RequestOptions`](../../index/interfaces/RequestOptions.md) +[`IdentityScopeOptions`](../type-aliases/IdentityScopeOptions.md) #### Returns @@ -180,7 +180,7 @@ listSkillVersion ##### options? -[`RequestOptions`](../../index/interfaces/RequestOptions.md) +[`IdentityScopeOptions`](../type-aliases/IdentityScopeOptions.md) #### Returns diff --git a/docs/api/forward/classes/Skills.md b/docs/api/forward/classes/Skills.md index 767d183..32c217a 100644 --- a/docs/api/forward/classes/Skills.md +++ b/docs/api/forward/classes/Skills.md @@ -88,7 +88,7 @@ createSkill ##### options? -[`RequestOptions`](../../index/interfaces/RequestOptions.md) +[`IdentityScopeOptions`](../type-aliases/IdentityScopeOptions.md) #### Returns diff --git a/docs/api/forward/classes/VaultCredentials.md b/docs/api/forward/classes/VaultCredentials.md index cfcf7df..93209c6 100644 --- a/docs/api/forward/classes/VaultCredentials.md +++ b/docs/api/forward/classes/VaultCredentials.md @@ -90,7 +90,7 @@ createVaultCredential ##### options? -[`RequestOptions`](../../index/interfaces/RequestOptions.md) +[`IdentityScopeOptions`](../type-aliases/IdentityScopeOptions.md) #### Returns @@ -150,7 +150,7 @@ listVaultCredential ##### options? -[`RequestOptions`](../../index/interfaces/RequestOptions.md) +[`IdentityScopeOptions`](../type-aliases/IdentityScopeOptions.md) #### Returns diff --git a/docs/api/forward/classes/Vaults.md b/docs/api/forward/classes/Vaults.md index df86ba5..1ac3fb9 100644 --- a/docs/api/forward/classes/Vaults.md +++ b/docs/api/forward/classes/Vaults.md @@ -88,7 +88,7 @@ createVault ##### options? -[`RequestOptions`](../../index/interfaces/RequestOptions.md) +[`IdentityScopeOptions`](../type-aliases/IdentityScopeOptions.md) #### Returns @@ -140,7 +140,7 @@ listVault ##### options? -[`RequestOptions`](../../index/interfaces/RequestOptions.md) +[`IdentityScopeOptions`](../type-aliases/IdentityScopeOptions.md) #### Returns diff --git a/docs/api/forward/interfaces/ChannelPairing.md b/docs/api/forward/interfaces/ChannelPairing.md index 805be1c..aaa17f0 100644 --- a/docs/api/forward/interfaces/ChannelPairing.md +++ b/docs/api/forward/interfaces/ChannelPairing.md @@ -22,6 +22,12 @@ Channel ID。 *** +### created\_at? + +> `optional` **created\_at?**: `string` + +*** + ### id > **id**: `string` @@ -46,6 +52,24 @@ Pairing ID,解除配对时使用。 *** +### scope\_display\_name + +> **scope\_display\_name**: `string` + +*** + +### scope\_external\_id + +> **scope\_external\_id**: `string` + +*** + +### scope\_type + +> **scope\_type**: `string` + +*** + ### status > **status**: `string` @@ -67,3 +91,9 @@ Pairing ID,解除配对时使用。 > **type**: `string` 固定为 `channel_pairing`。 + +*** + +### updated\_at? + +> `optional` **updated\_at?**: `string` diff --git a/docs/api/forward/interfaces/ChannelPairingNewParams.md b/docs/api/forward/interfaces/ChannelPairingNewParams.md index a54e58d..94ba7d9 100644 --- a/docs/api/forward/interfaces/ChannelPairingNewParams.md +++ b/docs/api/forward/interfaces/ChannelPairingNewParams.md @@ -14,11 +14,19 @@ Additional fields are preserved verbatim by the SDK. ## Properties -### code +### channel\_pairing\_id? -> **code**: `string` +> `optional` **channel\_pairing\_id?**: `string` -Channel 消息中显示的 6 位配对码。 +Pending pairing ID. Supply exactly one of code or channel_pairing_id. + +*** + +### code? + +> `optional` **code?**: `string` + +Channel 消息中的配对码;与 channel_pairing_id 二选一。 *** diff --git a/docs/api/forward/interfaces/EnvironmentListParams.md b/docs/api/forward/interfaces/EnvironmentListParams.md index cb7aea7..ca90cf4 100644 --- a/docs/api/forward/interfaces/EnvironmentListParams.md +++ b/docs/api/forward/interfaces/EnvironmentListParams.md @@ -30,6 +30,14 @@ Additional fields are preserved verbatim by the SDK. *** +### identity\_id? + +> `optional` **identity\_id?**: `string` + +Select identity ownership with a PAT. Omit when using a SAT. + +*** + ### limit? > `optional` **limit?**: `number` \| `null` diff --git a/docs/api/forward/interfaces/EnvironmentNewParams.md b/docs/api/forward/interfaces/EnvironmentNewParams.md index df27262..ac1c2ca 100644 --- a/docs/api/forward/interfaces/EnvironmentNewParams.md +++ b/docs/api/forward/interfaces/EnvironmentNewParams.md @@ -38,6 +38,14 @@ Environment 运行时配置对象;省略时默认使用 `{"type":"cloud"}`。 *** +### identity\_id? + +> `optional` **identity\_id?**: `string` + +Select identity ownership with a PAT. Omit when using a SAT. + +*** + ### metadata? > `optional` **metadata?**: `Record`\<`string`, `unknown`\> \| `null` diff --git a/docs/api/forward/interfaces/EnvironmentUpdateParams.md b/docs/api/forward/interfaces/EnvironmentUpdateParams.md index 69ebaac..169a3a0 100644 --- a/docs/api/forward/interfaces/EnvironmentUpdateParams.md +++ b/docs/api/forward/interfaces/EnvironmentUpdateParams.md @@ -30,6 +30,14 @@ Additional fields are preserved verbatim by the SDK. *** +### identity\_id? + +> `optional` **identity\_id?**: `string` + +Select identity ownership with a PAT. Omit when using a SAT. + +*** + ### metadata? > `optional` **metadata?**: `Record`\<`string`, `unknown`\> \| `null` diff --git a/docs/api/forward/interfaces/FileListParams.md b/docs/api/forward/interfaces/FileListParams.md index 3ab8471..c68eac8 100644 --- a/docs/api/forward/interfaces/FileListParams.md +++ b/docs/api/forward/interfaces/FileListParams.md @@ -30,6 +30,14 @@ Additional fields are preserved verbatim by the SDK. *** +### identity\_id? + +> `optional` **identity\_id?**: `string` + +Select identity ownership with a PAT. Omit when using a SAT. + +*** + ### limit? > `optional` **limit?**: `number` \| `null` diff --git a/docs/api/forward/interfaces/FileUploadParams.md b/docs/api/forward/interfaces/FileUploadParams.md index 8ddeef7..91b6e3c 100644 --- a/docs/api/forward/interfaces/FileUploadParams.md +++ b/docs/api/forward/interfaces/FileUploadParams.md @@ -30,6 +30,14 @@ Additional fields are preserved verbatim by the SDK. *** +### identity\_id? + +> `optional` **identity\_id?**: `string` + +Select identity ownership with a PAT. Omit when using a SAT. + +*** + ### metadata? > `optional` **metadata?**: `Record`\<`string`, `unknown`\> \| `null` diff --git a/docs/api/forward/interfaces/Session.md b/docs/api/forward/interfaces/Session.md index 5c56550..ac54157 100644 --- a/docs/api/forward/interfaces/Session.md +++ b/docs/api/forward/interfaces/Session.md @@ -110,6 +110,6 @@ Template 摘要。 *** -### usage +### usage? -> **usage**: [`SessionUsage`](SessionUsage.md) +> `optional` **usage?**: [`SessionUsage`](SessionUsage.md) diff --git a/docs/api/forward/interfaces/SessionUsage.md b/docs/api/forward/interfaces/SessionUsage.md index 25dd5e0..4f11291 100644 --- a/docs/api/forward/interfaces/SessionUsage.md +++ b/docs/api/forward/interfaces/SessionUsage.md @@ -14,6 +14,18 @@ Additional fields are preserved verbatim by the SDK. ## Properties +### model\_credits? + +> `optional` **model\_credits?**: `number` + +*** + +### sandbox\_runtime\_credits? + +> `optional` **sandbox\_runtime\_credits?**: `number` + +*** + ### total\_credits > **total\_credits**: `number` diff --git a/docs/api/forward/interfaces/SkillGetParams.md b/docs/api/forward/interfaces/SkillGetParams.md index 41eeb0d..b52f8f8 100644 --- a/docs/api/forward/interfaces/SkillGetParams.md +++ b/docs/api/forward/interfaces/SkillGetParams.md @@ -14,6 +14,14 @@ Additional fields are preserved verbatim by the SDK. ## Properties +### identity\_id? + +> `optional` **identity\_id?**: `string` + +Select identity ownership with a PAT. Omit when using a SAT. + +*** + ### include\_content? > `optional` **include\_content?**: `boolean` \| `null` diff --git a/docs/api/forward/interfaces/SkillListParams.md b/docs/api/forward/interfaces/SkillListParams.md index 24e070b..9d8e9a2 100644 --- a/docs/api/forward/interfaces/SkillListParams.md +++ b/docs/api/forward/interfaces/SkillListParams.md @@ -38,6 +38,14 @@ Additional fields are preserved verbatim by the SDK. *** +### identity\_id? + +> `optional` **identity\_id?**: `string` + +Select identity ownership with a PAT. Omit when using a SAT. + +*** + ### limit? > `optional` **limit?**: `number` \| `null` diff --git a/docs/api/forward/interfaces/SkillNewParams.md b/docs/api/forward/interfaces/SkillNewParams.md index d8e2f37..ca5d4b4 100644 --- a/docs/api/forward/interfaces/SkillNewParams.md +++ b/docs/api/forward/interfaces/SkillNewParams.md @@ -54,6 +54,14 @@ Forward Resource icon 公开 ID。 *** +### identity\_id? + +> `optional` **identity\_id?**: `string` + +Select identity ownership with a PAT. Omit when using a SAT. + +*** + ### metadata? > `optional` **metadata?**: `Record`\<`string`, `unknown`\> \| `null` diff --git a/docs/api/forward/interfaces/SkillUpdateParams.md b/docs/api/forward/interfaces/SkillUpdateParams.md index 6810ccc..5d67a21 100644 --- a/docs/api/forward/interfaces/SkillUpdateParams.md +++ b/docs/api/forward/interfaces/SkillUpdateParams.md @@ -46,6 +46,14 @@ Additional fields are preserved verbatim by the SDK. *** +### identity\_id? + +> `optional` **identity\_id?**: `string` + +Select identity ownership with a PAT. Omit when using a SAT. + +*** + ### metadata? > `optional` **metadata?**: `Record`\<`string`, `unknown`\> \| `null` diff --git a/docs/api/forward/interfaces/SkillVersionListParams.md b/docs/api/forward/interfaces/SkillVersionListParams.md index 5eff7c6..d0ac360 100644 --- a/docs/api/forward/interfaces/SkillVersionListParams.md +++ b/docs/api/forward/interfaces/SkillVersionListParams.md @@ -14,6 +14,14 @@ Additional fields are preserved verbatim by the SDK. ## Properties +### identity\_id? + +> `optional` **identity\_id?**: `string` + +Select identity ownership with a PAT. Omit when using a SAT. + +*** + ### limit? > `optional` **limit?**: `number` \| `null` diff --git a/docs/api/forward/interfaces/SkillVersionNewParams.md b/docs/api/forward/interfaces/SkillVersionNewParams.md index 9bbd97e..7d91d9d 100644 --- a/docs/api/forward/interfaces/SkillVersionNewParams.md +++ b/docs/api/forward/interfaces/SkillVersionNewParams.md @@ -19,3 +19,11 @@ Additional fields are preserved verbatim by the SDK. > **files**: [`Uploadable`](../../index/type-aliases/Uploadable.md)[] 上传字段,可**重复**出现多次。支持两种形态: • 单个 `.zip` 包; • 裸文件树——每个 part 独立上传一个文件,`filename` 携带相对路径(如 `customer-reply/SKILL.md`、`customer-reply/scripts/run.sh`)。 压缩包本身与解压后总大小均不超过 50 MB。 + +*** + +### identity\_id? + +> `optional` **identity\_id?**: `string` + +Select identity ownership with a PAT. Omit when using a SAT. diff --git a/docs/api/forward/interfaces/VaultCredentialListParams.md b/docs/api/forward/interfaces/VaultCredentialListParams.md index 14a86d7..6eb0a62 100644 --- a/docs/api/forward/interfaces/VaultCredentialListParams.md +++ b/docs/api/forward/interfaces/VaultCredentialListParams.md @@ -30,6 +30,14 @@ Additional fields are preserved verbatim by the SDK. *** +### identity\_id? + +> `optional` **identity\_id?**: `string` + +Select identity ownership with a PAT. Omit when using a SAT. + +*** + ### limit? > `optional` **limit?**: `number` \| `null` diff --git a/docs/api/forward/interfaces/VaultCredentialNewParams.md b/docs/api/forward/interfaces/VaultCredentialNewParams.md index 0cc610b..cff4af6 100644 --- a/docs/api/forward/interfaces/VaultCredentialNewParams.md +++ b/docs/api/forward/interfaces/VaultCredentialNewParams.md @@ -38,6 +38,14 @@ Credential 认证信息,支持 `static_bearer`、`mcp_oauth`;响应只返回 *** +### identity\_id? + +> `optional` **identity\_id?**: `string` + +Select identity ownership with a PAT. Omit when using a SAT. + +*** + ### metadata? > `optional` **metadata?**: `Record`\<`string`, `unknown`\> \| `null` diff --git a/docs/api/forward/interfaces/VaultListParams.md b/docs/api/forward/interfaces/VaultListParams.md index ca81041..fd7f518 100644 --- a/docs/api/forward/interfaces/VaultListParams.md +++ b/docs/api/forward/interfaces/VaultListParams.md @@ -30,6 +30,14 @@ Additional fields are preserved verbatim by the SDK. *** +### identity\_id? + +> `optional` **identity\_id?**: `string` + +Select identity ownership with a PAT. Omit when using a SAT. + +*** + ### limit? > `optional` **limit?**: `number` \| `null` diff --git a/docs/api/forward/interfaces/VaultNewParams.md b/docs/api/forward/interfaces/VaultNewParams.md index 33997aa..d189a9b 100644 --- a/docs/api/forward/interfaces/VaultNewParams.md +++ b/docs/api/forward/interfaces/VaultNewParams.md @@ -30,6 +30,14 @@ Vault 展示名。 *** +### identity\_id? + +> `optional` **identity\_id?**: `string` + +Select identity ownership with a PAT. Omit when using a SAT. + +*** + ### metadata? > `optional` **metadata?**: `Record`\<`string`, `unknown`\> \| `null` diff --git a/docs/api/forward/type-aliases/IdentityScopeOptions.md b/docs/api/forward/type-aliases/IdentityScopeOptions.md new file mode 100644 index 0000000..816f205 --- /dev/null +++ b/docs/api/forward/type-aliases/IdentityScopeOptions.md @@ -0,0 +1,17 @@ +[**qca-sdk**](../../README.md) + +*** + +[qca-sdk](../../README.md) / [forward](../README.md) / IdentityScopeOptions + +# Type Alias: IdentityScopeOptions + +> **IdentityScopeOptions** = [`RequestOptions`](../../index/interfaces/RequestOptions.md) & `object` + +PAT identity ownership query. Omit identity_id when using a SAT. + +## Type Declaration + +### identity\_id? + +> `optional` **identity\_id?**: `string` diff --git a/docs/api/managed/interfaces/DeploymentNewParams.md b/docs/api/managed/interfaces/DeploymentNewParams.md index d67eced..b9563a7 100644 --- a/docs/api/managed/interfaces/DeploymentNewParams.md +++ b/docs/api/managed/interfaces/DeploymentNewParams.md @@ -30,8 +30,8 @@ Optional header to specify the beta version(s) you want to use. > `optional` **budget?**: [`ManagedAgentsBudgetLimitParam`](ManagedAgentsBudgetLimitParam.md) \| `null` -A hard spend ceiling. The session stops issuing new model requests once the -tracked list cost reaches `max_list_cost`. +A total model and sandbox credit limit. Reaching it rejects the next user +message without interrupting the running turn. *** diff --git a/docs/api/managed/interfaces/DeploymentUpdateParams.md b/docs/api/managed/interfaces/DeploymentUpdateParams.md index 0c0e0c2..26a4ae8 100644 --- a/docs/api/managed/interfaces/DeploymentUpdateParams.md +++ b/docs/api/managed/interfaces/DeploymentUpdateParams.md @@ -30,8 +30,8 @@ Optional header to specify the beta version(s) you want to use. > `optional` **budget?**: [`ManagedAgentsBudgetLimitParam`](ManagedAgentsBudgetLimitParam.md) \| `null` -A hard spend ceiling. The session stops issuing new model requests once the -tracked list cost reaches `max_list_cost`. +A total model and sandbox credit limit. Reaching it rejects the next user +message without interrupting the running turn. *** diff --git a/docs/api/managed/interfaces/ManagedAgentsAgentThreadContextCompactedEvent.md b/docs/api/managed/interfaces/ManagedAgentsAgentThreadContextCompactedEvent.md index 0792eed..c2d9269 100644 --- a/docs/api/managed/interfaces/ManagedAgentsAgentThreadContextCompactedEvent.md +++ b/docs/api/managed/interfaces/ManagedAgentsAgentThreadContextCompactedEvent.md @@ -31,3 +31,11 @@ A timestamp in RFC 3339 format > **type**: `"agent.thread_context_compacted"` Any of "agent.thread_context_compacted". + +*** + +### usage? + +> `optional` **usage?**: [`ManagedAgentsSpanModelUsage`](ManagedAgentsSpanModelUsage.md) + +Credits for this compaction call, already included in Session usage. diff --git a/docs/api/managed/interfaces/ManagedAgentsBudgetLimit.md b/docs/api/managed/interfaces/ManagedAgentsBudgetLimit.md index 5f29093..1284318 100644 --- a/docs/api/managed/interfaces/ManagedAgentsBudgetLimit.md +++ b/docs/api/managed/interfaces/ManagedAgentsBudgetLimit.md @@ -6,16 +6,16 @@ # Interface: ManagedAgentsBudgetLimit -A hard spend ceiling. The session stops issuing new model requests once the -tracked list cost reaches `max_list_cost`. +A total model and sandbox credit limit. Reaching it rejects the next user +message without interrupting the running turn. ## Properties -### max\_list\_cost +### max\_credit\_cost -> **max\_list\_cost**: [`MonetaryAmount`](MonetaryAmount.md) +> **max\_credit\_cost**: `string` -A monetary amount in a specific currency. +Positive decimal Credits with at most 12 integer and 2 fractional digits. *** diff --git a/docs/api/managed/interfaces/ManagedAgentsBudgetLimitParam.md b/docs/api/managed/interfaces/ManagedAgentsBudgetLimitParam.md index d553b6e..90c9847 100644 --- a/docs/api/managed/interfaces/ManagedAgentsBudgetLimitParam.md +++ b/docs/api/managed/interfaces/ManagedAgentsBudgetLimitParam.md @@ -6,16 +6,16 @@ # Interface: ManagedAgentsBudgetLimitParam -A hard spend ceiling. The session stops issuing new model requests once the -tracked list cost reaches `max_list_cost`. +A total model and sandbox credit limit. Reaching it rejects the next user +message without interrupting the running turn. ## Properties -### max\_list\_cost +### max\_credit\_cost -> **max\_list\_cost**: [`MonetaryAmountParam`](MonetaryAmountParam.md) +> **max\_credit\_cost**: `string` -A monetary amount in a specific currency. +Positive decimal Credits with at most 12 integer and 2 fractional digits. *** diff --git a/docs/api/managed/interfaces/ManagedAgentsDeployment.md b/docs/api/managed/interfaces/ManagedAgentsDeployment.md index 7696519..6520629 100644 --- a/docs/api/managed/interfaces/ManagedAgentsDeployment.md +++ b/docs/api/managed/interfaces/ManagedAgentsDeployment.md @@ -32,8 +32,8 @@ A timestamp in RFC 3339 format > `optional` **budget?**: [`ManagedAgentsBudgetLimit`](ManagedAgentsBudgetLimit.md) \| `null` -A hard spend ceiling. The session stops issuing new model requests once the -tracked list cost reaches `max_list_cost`. +A total model and sandbox credit limit. Reaching it rejects the next user +message without interrupting the running turn. *** diff --git a/docs/api/managed/interfaces/ManagedAgentsSession.md b/docs/api/managed/interfaces/ManagedAgentsSession.md index 34cb417..6d41ba3 100644 --- a/docs/api/managed/interfaces/ManagedAgentsSession.md +++ b/docs/api/managed/interfaces/ManagedAgentsSession.md @@ -27,12 +27,12 @@ A timestamp in RFC 3339 format *** -### budget +### budget? -> **budget**: [`ManagedAgentsBudgetLimit`](ManagedAgentsBudgetLimit.md) +> `optional` **budget?**: [`ManagedAgentsBudgetLimit`](ManagedAgentsBudgetLimit.md) \| `null` -A hard spend ceiling. The session stops issuing new model requests once the -tracked list cost reaches `max_list_cost`. +A total model and sandbox credit limit. Reaching it rejects the next user +message without interrupting the running turn. *** @@ -132,11 +132,11 @@ A timestamp in RFC 3339 format *** -### usage +### usage? -> **usage**: [`ManagedAgentsSessionUsage`](ManagedAgentsSessionUsage.md) +> `optional` **usage?**: [`ManagedAgentsSessionUsage`](ManagedAgentsSessionUsage.md) -Cumulative token usage for a session across all turns. +Cumulative Credits snapshot. Legacy token and list-cost fields may appear in older responses. *** diff --git a/docs/api/managed/interfaces/ManagedAgentsSessionEventUnionUsage.md b/docs/api/managed/interfaces/ManagedAgentsSessionEventUnionUsage.md index 2a8ebf4..ef19011 100644 --- a/docs/api/managed/interfaces/ManagedAgentsSessionEventUnionUsage.md +++ b/docs/api/managed/interfaces/ManagedAgentsSessionEventUnionUsage.md @@ -38,6 +38,12 @@ This field is from variant `ManagedAgentsSpanModelUsage`. *** +### credits? + +> `optional` **credits?**: `number` + +*** + ### input\_tokens? > `optional` **input\_tokens?**: `number` diff --git a/docs/api/managed/interfaces/ManagedAgentsSessionUpdatedEvent.md b/docs/api/managed/interfaces/ManagedAgentsSessionUpdatedEvent.md index f57c74c..750d040 100644 --- a/docs/api/managed/interfaces/ManagedAgentsSessionUpdatedEvent.md +++ b/docs/api/managed/interfaces/ManagedAgentsSessionUpdatedEvent.md @@ -25,8 +25,8 @@ Resolved `agent` definition for a `session`. Snapshot of the `agent` at > `optional` **budget?**: [`ManagedAgentsBudgetLimit`](ManagedAgentsBudgetLimit.md) \| `null` -A hard spend ceiling. The session stops issuing new model requests once the -tracked list cost reaches `max_list_cost`. +A total model and sandbox credit limit. Reaching it rejects the next user +message without interrupting the running turn. *** diff --git a/docs/api/managed/interfaces/ManagedAgentsSessionUsage.md b/docs/api/managed/interfaces/ManagedAgentsSessionUsage.md index ff532ea..0c3efe7 100644 --- a/docs/api/managed/interfaces/ManagedAgentsSessionUsage.md +++ b/docs/api/managed/interfaces/ManagedAgentsSessionUsage.md @@ -6,7 +6,7 @@ # Interface: ManagedAgentsSessionUsage -Cumulative token usage for a session across all turns. +Cumulative Credits snapshot. Legacy token and list-cost fields may appear in older responses. ## Properties @@ -53,6 +53,14 @@ A monetary amount in a specific currency. *** +### model\_credits + +> **model\_credits**: `number` + +Cumulative Credits. Replace the previous snapshot instead of adding it. + +*** + ### output\_tokens? > `optional` **output\_tokens?**: `number` @@ -61,8 +69,20 @@ Total output tokens generated across all turns. *** +### sandbox\_runtime\_credits + +> **sandbox\_runtime\_credits**: `number` + +*** + ### server\_tool\_use? > `optional` **server\_tool\_use?**: [`ManagedAgentsServerToolUsage`](ManagedAgentsServerToolUsage.md) \| `null` Cumulative count of server-executed tool invocations, broken down by tool. + +*** + +### total\_credits + +> **total\_credits**: `number` diff --git a/docs/api/managed/interfaces/ManagedAgentsSessionUsageEvent.md b/docs/api/managed/interfaces/ManagedAgentsSessionUsageEvent.md index cc2c953..87687dc 100644 --- a/docs/api/managed/interfaces/ManagedAgentsSessionUsageEvent.md +++ b/docs/api/managed/interfaces/ManagedAgentsSessionUsageEvent.md @@ -6,7 +6,7 @@ # Interface: ManagedAgentsSessionUsageEvent -Periodic snapshot of the session's cumulative usage and tracked list cost. +Cumulative Credits emitted before session.status_idle when usage is available. ## Properties @@ -14,8 +14,8 @@ Periodic snapshot of the session's cumulative usage and tracked list cost. > `optional` **budget?**: [`ManagedAgentsBudgetLimit`](ManagedAgentsBudgetLimit.md) \| `null` -A hard spend ceiling. The session stops issuing new model requests once the -tracked list cost reaches `max_list_cost`. +A total model and sandbox credit limit. Reaching it rejects the next user +message without interrupting the running turn. *** @@ -27,6 +27,14 @@ Unique identifier for this event. *** +### model\_credits + +> **model\_credits**: `number` + +Cumulative Credits. Replace the previous snapshot instead of adding it. + +*** + ### processed\_at > **processed\_at**: `string` @@ -35,6 +43,18 @@ A timestamp in RFC 3339 format *** +### sandbox\_runtime\_credits + +> **sandbox\_runtime\_credits**: `number` + +*** + +### total\_credits + +> **total\_credits**: `number` + +*** + ### type > **type**: `"session.usage"` @@ -43,8 +63,10 @@ Any of "session.usage". *** -### usage +### ~~usage?~~ + +> `optional` **usage?**: [`ManagedAgentsSessionUsageSnapshot`](ManagedAgentsSessionUsageSnapshot.md) -> **usage**: [`ManagedAgentsSessionUsageSnapshot`](ManagedAgentsSessionUsageSnapshot.md) +#### Deprecated -Point-in-time snapshot of a session's cumulative usage. +Legacy nested usage; current events carry Credits at the top level. diff --git a/docs/api/managed/interfaces/ManagedAgentsSpanModelRequestEndEvent.md b/docs/api/managed/interfaces/ManagedAgentsSpanModelRequestEndEvent.md index 4e66e09..4f58d33 100644 --- a/docs/api/managed/interfaces/ManagedAgentsSpanModelRequestEndEvent.md +++ b/docs/api/managed/interfaces/ManagedAgentsSpanModelRequestEndEvent.md @@ -34,11 +34,11 @@ The id of the corresponding `span.model_request_start` event. *** -### model\_usage +### model\_usage? -> **model\_usage**: [`ManagedAgentsSpanModelUsage`](ManagedAgentsSpanModelUsage.md) +> `optional` **model\_usage?**: [`ManagedAgentsSpanModelUsage`](ManagedAgentsSpanModelUsage.md) -Token usage for a single model request. +Credits for a single model request; legacy token fields may appear in older responses. *** diff --git a/docs/api/managed/interfaces/ManagedAgentsSpanModelUsage.md b/docs/api/managed/interfaces/ManagedAgentsSpanModelUsage.md index d681ca2..98568b0 100644 --- a/docs/api/managed/interfaces/ManagedAgentsSpanModelUsage.md +++ b/docs/api/managed/interfaces/ManagedAgentsSpanModelUsage.md @@ -6,37 +6,43 @@ # Interface: ManagedAgentsSpanModelUsage -Token usage for a single model request. +Credits for a single model request; legacy token fields may appear in older responses. ## Properties -### cache\_creation\_input\_tokens +### cache\_creation\_input\_tokens? -> **cache\_creation\_input\_tokens**: `number` +> `optional` **cache\_creation\_input\_tokens?**: `number` Tokens used to create prompt cache in this request. *** -### cache\_read\_input\_tokens +### cache\_read\_input\_tokens? -> **cache\_read\_input\_tokens**: `number` +> `optional` **cache\_read\_input\_tokens?**: `number` Tokens read from prompt cache in this request. *** -### input\_tokens +### credits -> **input\_tokens**: `number` +> **credits**: `number` + +*** + +### input\_tokens? + +> `optional` **input\_tokens?**: `number` Input tokens consumed by this request. *** -### output\_tokens +### output\_tokens? -> **output\_tokens**: `number` +> `optional` **output\_tokens?**: `number` Output tokens generated by this request. diff --git a/docs/api/managed/interfaces/ManagedAgentsSpanOutcomeEvaluationEndEvent.md b/docs/api/managed/interfaces/ManagedAgentsSpanOutcomeEvaluationEndEvent.md index 538b047..588338b 100644 --- a/docs/api/managed/interfaces/ManagedAgentsSpanOutcomeEvaluationEndEvent.md +++ b/docs/api/managed/interfaces/ManagedAgentsSpanOutcomeEvaluationEndEvent.md @@ -89,4 +89,4 @@ Any of "span.outcome_evaluation_end". > **usage**: [`ManagedAgentsSpanModelUsage`](ManagedAgentsSpanModelUsage.md) -Token usage for a single model request. +Credits for a single model request; legacy token fields may appear in older responses. diff --git a/docs/api/managed/interfaces/ManagedAgentsStreamSessionEventsUnionUsage.md b/docs/api/managed/interfaces/ManagedAgentsStreamSessionEventsUnionUsage.md index b0762fc..74ce780 100644 --- a/docs/api/managed/interfaces/ManagedAgentsStreamSessionEventsUnionUsage.md +++ b/docs/api/managed/interfaces/ManagedAgentsStreamSessionEventsUnionUsage.md @@ -38,6 +38,12 @@ This field is from variant `ManagedAgentsSpanModelUsage`. *** +### credits? + +> `optional` **credits?**: `number` + +*** + ### input\_tokens? > `optional` **input\_tokens?**: `number` diff --git a/docs/api/managed/interfaces/ManagedAgentsStreamSessionThreadEventsUnionUsage.md b/docs/api/managed/interfaces/ManagedAgentsStreamSessionThreadEventsUnionUsage.md index 1d63f0b..80500ce 100644 --- a/docs/api/managed/interfaces/ManagedAgentsStreamSessionThreadEventsUnionUsage.md +++ b/docs/api/managed/interfaces/ManagedAgentsStreamSessionThreadEventsUnionUsage.md @@ -38,6 +38,12 @@ This field is from variant `ManagedAgentsSpanModelUsage`. *** +### credits? + +> `optional` **credits?**: `number` + +*** + ### input\_tokens? > `optional` **input\_tokens?**: `number` diff --git a/docs/api/managed/interfaces/SessionNewParams.md b/docs/api/managed/interfaces/SessionNewParams.md index 1c58420..b219bec 100644 --- a/docs/api/managed/interfaces/SessionNewParams.md +++ b/docs/api/managed/interfaces/SessionNewParams.md @@ -29,8 +29,8 @@ Optional header to specify the beta version(s) you want to use. > `optional` **budget?**: [`ManagedAgentsBudgetLimitParam`](ManagedAgentsBudgetLimitParam.md) \| `null` -A hard spend ceiling. The session stops issuing new model requests once the -tracked list cost reaches `max_list_cost`. +A total model and sandbox credit limit. Reaching it rejects the next user +message without interrupting the running turn. *** diff --git a/docs/api/managed/interfaces/SessionUpdateParams.md b/docs/api/managed/interfaces/SessionUpdateParams.md index 1f9bb16..c9d9ecb 100644 --- a/docs/api/managed/interfaces/SessionUpdateParams.md +++ b/docs/api/managed/interfaces/SessionUpdateParams.md @@ -30,8 +30,8 @@ Optional header to specify the beta version(s) you want to use. > `optional` **budget?**: [`ManagedAgentsBudgetLimitParam`](ManagedAgentsBudgetLimitParam.md) \| `null` -A hard spend ceiling. The session stops issuing new model requests once the -tracked list cost reaches `max_list_cost`. +A total model and sandbox credit limit. Reaching it rejects the next user +message without interrupting the running turn. *** diff --git a/src/forward/_utils.ts b/src/forward/_utils.ts index 62b2184..f8db065 100644 --- a/src/forward/_utils.ts +++ b/src/forward/_utils.ts @@ -1,4 +1,5 @@ // Shared transport details for the Forward resources. +import type { IdentityScopeOptions } from './types.js'; import type { RequestOptions } from '../core/client.js'; /** Validate before invoking fetch, then escape the value as one path segment. */ @@ -27,3 +28,9 @@ export function requestHeaders(base: Record, } return headers; } + +/** Route identity ownership through query while preserving request overrides. */ +export function identityScopeOptions(options?: IdentityScopeOptions): RequestOptions { + const { identity_id, ...rest } = options ?? {}; + return { ...rest, query: { identity_id, ...rest.query } }; +} diff --git a/src/forward/api-inventory.json b/src/forward/api-inventory.json index b04a304..2a070d0 100644 --- a/src/forward/api-inventory.json +++ b/src/forward/api-inventory.json @@ -505,7 +505,7 @@ "name": "code", "wireName": "code", "location": "body", - "required": true, + "required": false, "type": "string" }, { @@ -528,6 +528,13 @@ "location": "header", "required": false, "type": "string | null" + }, + { + "name": "channel_pairing_id", + "wireName": "channel_pairing_id", + "location": "body", + "required": false, + "type": "string" } ] }, @@ -646,6 +653,13 @@ "location": "query", "required": false, "type": "string | null" + }, + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" } ] }, @@ -697,6 +711,13 @@ "location": "header", "required": false, "type": "string | null" + }, + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" } ] }, @@ -720,7 +741,15 @@ "pagination": "cursor", "itemType": "Environment", "path": "/environments/{id}", - "parameterFields": [] + "parameterFields": [ + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" + } + ] }, { "operationId": "updateEnvironment", @@ -770,6 +799,13 @@ "location": "body", "required": false, "type": "Record | null" + }, + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" } ] }, @@ -793,7 +829,15 @@ "pagination": "cursor", "itemType": "Environment", "path": "/environments/{id}/archive", - "parameterFields": [] + "parameterFields": [ + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" + } + ] }, { "operationId": "deleteEnvironment", @@ -815,7 +859,15 @@ "pagination": "cursor", "itemType": "void", "path": "/environments/{id}", - "parameterFields": [] + "parameterFields": [ + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" + } + ] }, { "operationId": "listFile", @@ -872,6 +924,13 @@ "location": "query", "required": false, "type": "string | null" + }, + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" } ] }, @@ -923,6 +982,13 @@ "location": "header", "required": false, "type": "string | null" + }, + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" } ] }, @@ -946,7 +1012,15 @@ "pagination": "cursor", "itemType": "FileMetadata", "path": "/files/{file_id}", - "parameterFields": [] + "parameterFields": [ + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" + } + ] }, { "operationId": "deleteFile", @@ -968,7 +1042,15 @@ "pagination": "cursor", "itemType": "void", "path": "/files/{file_id}", - "parameterFields": [] + "parameterFields": [ + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" + } + ] }, { "operationId": "downloadFile", @@ -990,7 +1072,15 @@ "pagination": "cursor", "itemType": "Response", "path": "/files/{file_id}/content", - "parameterFields": [] + "parameterFields": [ + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" + } + ] }, { "operationId": "listIdentities", @@ -3472,6 +3562,13 @@ "location": "query", "required": false, "type": "string | null" + }, + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" } ] }, @@ -3544,6 +3641,13 @@ "location": "header", "required": false, "type": "string | null" + }, + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" } ] }, @@ -3574,6 +3678,13 @@ "location": "query", "required": false, "type": "boolean | null" + }, + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" } ] }, @@ -3639,6 +3750,13 @@ "location": "body", "required": false, "type": "string | null" + }, + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" } ] }, @@ -3662,7 +3780,15 @@ "pagination": "cursor", "itemType": "void", "path": "/skills/{id}", - "parameterFields": [] + "parameterFields": [ + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" + } + ] }, { "operationId": "listSkillVersion", @@ -3698,6 +3824,13 @@ "location": "query", "required": false, "type": "string | null" + }, + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" } ] }, @@ -3728,6 +3861,13 @@ "location": "body", "required": true, "type": "Array" + }, + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" } ] }, @@ -3757,7 +3897,15 @@ "pagination": "cursor", "itemType": "SkillVersion", "path": "/skills/{id}/versions/{version}", - "parameterFields": [] + "parameterFields": [ + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" + } + ] }, { "operationId": "deleteSkillVersion", @@ -3785,7 +3933,15 @@ "pagination": "cursor", "itemType": "DeletedSkillVersion", "path": "/skills/{id}/versions/{version}", - "parameterFields": [] + "parameterFields": [ + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" + } + ] }, { "operationId": "downloadSkillVersion", @@ -3813,7 +3969,15 @@ "pagination": "cursor", "itemType": "Response", "path": "/skills/{id}/versions/{version}/content", - "parameterFields": [] + "parameterFields": [ + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" + } + ] }, { "operationId": "listTemplates", @@ -4280,6 +4444,13 @@ "location": "query", "required": false, "type": "string | null" + }, + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" } ] }, @@ -4317,6 +4488,13 @@ "location": "header", "required": false, "type": "string | null" + }, + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" } ] }, @@ -4340,7 +4518,15 @@ "pagination": "cursor", "itemType": "Vault", "path": "/vaults/{id}", - "parameterFields": [] + "parameterFields": [ + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" + } + ] }, { "operationId": "deleteVault", @@ -4362,7 +4548,15 @@ "pagination": "cursor", "itemType": "void", "path": "/vaults/{id}", - "parameterFields": [] + "parameterFields": [ + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" + } + ] }, { "operationId": "listVaultCredential", @@ -4419,6 +4613,13 @@ "location": "query", "required": false, "type": "string | null" + }, + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" } ] }, @@ -4470,6 +4671,13 @@ "location": "header", "required": false, "type": "string | null" + }, + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" } ] }, @@ -4499,7 +4707,15 @@ "pagination": "cursor", "itemType": "VaultCredential", "path": "/vaults/{id}/credentials/{cred_id}", - "parameterFields": [] + "parameterFields": [ + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" + } + ] }, { "operationId": "deleteVaultCredential", @@ -4527,7 +4743,15 @@ "pagination": "cursor", "itemType": "void", "path": "/vaults/{id}/credentials/{cred_id}", - "parameterFields": [] + "parameterFields": [ + { + "name": "identity_id", + "wireName": "identity_id", + "location": "query", + "required": false, + "type": "string" + } + ] }, { "operationId": "updateVaultCredential", diff --git a/src/forward/environment.ts b/src/forward/environment.ts index 4adbc9f..8d71393 100644 --- a/src/forward/environment.ts +++ b/src/forward/environment.ts @@ -1,9 +1,10 @@ // Generated code, verified against the API contracts. import { APIResource } from '../core/resource.js'; import type { RequestOptions } from '../core/client.js'; +import type { IdentityScopeOptions } from './types.js'; import type { APIPromise } from '../core/api-promise.js'; import type { PagePromise } from '../core/pagination.js'; -import { pathParam, requestHeaders } from './_utils.js'; +import { pathParam, requestHeaders, identityScopeOptions } from './_utils.js'; import type { Environment, EnvironmentCreateParams, EnvironmentListParams, EnvironmentUpdateParams } from './types.js'; export class Environments extends APIResource { @@ -24,12 +25,13 @@ export class Environments extends APIResource { */ create(params: EnvironmentCreateParams, options?: RequestOptions): APIPromise { const path = "environments"; - const { idempotency_key, ...payload } = params; + const { identity_id, idempotency_key, ...payload } = params; return this._client.request({ method: "POST", path, body: payload, ...options, + query: { identity_id, ...options?.query }, headers: requestHeaders({ "Idempotency-Key": idempotency_key }, options?.headers), }); } @@ -39,12 +41,12 @@ export class Environments extends APIResource { * * @operation getEnvironment */ - retrieve(id: string, options?: RequestOptions): APIPromise { + retrieve(id: string, options?: IdentityScopeOptions): APIPromise { const path = `environments/${pathParam(id, "id")}`; return this._client.request({ method: "GET", path, - ...options, + ...identityScopeOptions(options), }); } @@ -59,11 +61,13 @@ export class Environments extends APIResource { options?: RequestOptions, ): APIPromise { const path = `environments/${pathParam(id, "id")}`; + const { identity_id, ...payload } = params; return this._client.request({ method: "POST", path, - body: params, + body: payload, ...options, + query: { identity_id, ...options?.query }, }); } @@ -72,12 +76,12 @@ export class Environments extends APIResource { * * @operation archiveEnvironment */ - archive(id: string, options?: RequestOptions): APIPromise { + archive(id: string, options?: IdentityScopeOptions): APIPromise { const path = `environments/${pathParam(id, "id")}/archive`; return this._client.request({ method: "POST", path, - ...options, + ...identityScopeOptions(options), }); } @@ -86,13 +90,13 @@ export class Environments extends APIResource { * * @operation deleteEnvironment */ - delete(id: string, options?: RequestOptions): APIPromise { + delete(id: string, options?: IdentityScopeOptions): APIPromise { const path = `environments/${pathParam(id, "id")}`; return this._client.request({ method: "DELETE", path, responseType: "void", - ...options, + ...identityScopeOptions(options), }); } diff --git a/src/forward/file.ts b/src/forward/file.ts index b50459f..c3fbf9c 100644 --- a/src/forward/file.ts +++ b/src/forward/file.ts @@ -1,10 +1,11 @@ // Generated code, verified against the API contracts. import { APIResource } from '../core/resource.js'; import type { RequestOptions } from '../core/client.js'; +import type { IdentityScopeOptions } from './types.js'; import type { APIPromise } from '../core/api-promise.js'; import type { PagePromise } from '../core/pagination.js'; import { toMultipartForm } from '../core/uploads.js'; -import { pathParam, requestHeaders } from './_utils.js'; +import { pathParam, requestHeaders, identityScopeOptions } from './_utils.js'; import type { FileListParams, FileMetadata, FileUploadParams } from './types.js'; export class Files extends APIResource { @@ -25,12 +26,13 @@ export class Files extends APIResource { */ upload(params: FileUploadParams, options?: RequestOptions): APIPromise { const path = "files"; - const { idempotency_key, ...payload } = params; + const { identity_id, idempotency_key, ...payload } = params; return this._client.request({ method: "POST", path, body: toMultipartForm(payload), ...options, + query: { identity_id, ...options?.query }, headers: requestHeaders({ "Idempotency-Key": idempotency_key }, options?.headers), }); } @@ -40,12 +42,12 @@ export class Files extends APIResource { * * @operation getFile */ - getMetadata(fileID: string, options?: RequestOptions): APIPromise { + getMetadata(fileID: string, options?: IdentityScopeOptions): APIPromise { const path = `files/${pathParam(fileID, "file_id")}`; return this._client.request({ method: "GET", path, - ...options, + ...identityScopeOptions(options), }); } @@ -54,13 +56,13 @@ export class Files extends APIResource { * * @operation deleteFile */ - delete(fileID: string, options?: RequestOptions): APIPromise { + delete(fileID: string, options?: IdentityScopeOptions): APIPromise { const path = `files/${pathParam(fileID, "file_id")}`; return this._client.request({ method: "DELETE", path, responseType: "void", - ...options, + ...identityScopeOptions(options), }); } @@ -69,9 +71,9 @@ export class Files extends APIResource { * * @operation downloadFile */ - download(fileID: string, options?: RequestOptions): APIPromise { + download(fileID: string, options?: IdentityScopeOptions): APIPromise { const path = `files/${pathParam(fileID, "file_id")}/content`; - return this._client.downloadFile(path, options); + return this._client.downloadFile(path, identityScopeOptions(options)); } } diff --git a/src/forward/skill-version.ts b/src/forward/skill-version.ts index e9304c6..0ee53f6 100644 --- a/src/forward/skill-version.ts +++ b/src/forward/skill-version.ts @@ -1,10 +1,11 @@ // Generated code, verified against the API contracts. import { APIResource } from '../core/resource.js'; import type { RequestOptions } from '../core/client.js'; +import type { IdentityScopeOptions } from './types.js'; import type { APIPromise } from '../core/api-promise.js'; import type { PagePromise } from '../core/pagination.js'; import { toMultipartForm } from '../core/uploads.js'; -import { pathParam, requestHeaders } from './_utils.js'; +import { pathParam, requestHeaders, identityScopeOptions } from './_utils.js'; import type { DeletedSkillVersion, SkillVersion, SkillVersionCreateParams, SkillVersionListParams } from './types.js'; export class SkillVersions extends APIResource { @@ -25,11 +26,13 @@ export class SkillVersions extends APIResource { */ create(id: string, params: SkillVersionCreateParams, options?: RequestOptions): APIPromise { const path = `skills/${pathParam(id, "id")}/versions`; + const { identity_id, ...payload } = params; return this._client.request({ method: "POST", path, - body: toMultipartForm(params), + body: toMultipartForm(payload), ...options, + query: { identity_id, ...options?.query }, }); } @@ -38,12 +41,12 @@ export class SkillVersions extends APIResource { * * @operation getSkillVersion */ - retrieve(id: string, version: string, options?: RequestOptions): APIPromise { + retrieve(id: string, version: string, options?: IdentityScopeOptions): APIPromise { const path = `skills/${pathParam(id, "id")}/versions/${pathParam(version, "version")}`; return this._client.request({ method: "GET", path, - ...options, + ...identityScopeOptions(options), }); } @@ -52,12 +55,12 @@ export class SkillVersions extends APIResource { * * @operation deleteSkillVersion */ - delete(id: string, version: string, options?: RequestOptions): APIPromise { + delete(id: string, version: string, options?: IdentityScopeOptions): APIPromise { const path = `skills/${pathParam(id, "id")}/versions/${pathParam(version, "version")}`; return this._client.request({ method: "DELETE", path, - ...options, + ...identityScopeOptions(options), }); } @@ -66,13 +69,13 @@ export class SkillVersions extends APIResource { * * @operation downloadSkillVersion */ - download(id: string, version: string, options?: RequestOptions): APIPromise { + download(id: string, version: string, options?: IdentityScopeOptions): APIPromise { const path = `skills/${pathParam(id, "id")}/versions/${pathParam(version, "version")}/content`; return this._client.request({ method: "GET", path, responseType: "response", - ...options, + ...identityScopeOptions(options), }); } diff --git a/src/forward/skill.ts b/src/forward/skill.ts index 5f1e162..f2e8c20 100644 --- a/src/forward/skill.ts +++ b/src/forward/skill.ts @@ -1,10 +1,11 @@ // Generated code, verified against the API contracts. import { APIResource } from '../core/resource.js'; import type { RequestOptions } from '../core/client.js'; +import type { IdentityScopeOptions } from './types.js'; import type { APIPromise } from '../core/api-promise.js'; import type { PagePromise } from '../core/pagination.js'; import { toMultipartForm } from '../core/uploads.js'; -import { pathParam, requestHeaders } from './_utils.js'; +import { pathParam, requestHeaders, identityScopeOptions } from './_utils.js'; import type { Skill, SkillCreateParams, SkillListParams, SkillRetrieveParams, SkillUpdateParams } from './types.js'; import { SkillVersions } from './skill-version.js'; @@ -28,12 +29,13 @@ export class Skills extends APIResource { */ create(params: SkillCreateParams = {}, options?: RequestOptions): APIPromise { const path = "skills"; - const { idempotency_key, ...payload } = params; + const { identity_id, idempotency_key, ...payload } = params; return this._client.request({ method: "POST", path, body: toMultipartForm(payload), ...options, + query: { identity_id, ...options?.query }, headers: requestHeaders({ "Idempotency-Key": idempotency_key }, options?.headers), }); } @@ -48,8 +50,8 @@ export class Skills extends APIResource { return this._client.request({ method: "GET", path, - query: params, ...options, + query: { ...params, ...options?.query }, }); } @@ -60,11 +62,13 @@ export class Skills extends APIResource { */ update(id: string, params: SkillUpdateParams = {}, options?: RequestOptions): APIPromise { const path = `skills/${pathParam(id, "id")}`; + const { identity_id, ...payload } = params; return this._client.request({ method: "PUT", path, - body: params, + body: payload, ...options, + query: { identity_id, ...options?.query }, }); } @@ -73,13 +77,13 @@ export class Skills extends APIResource { * * @operation deleteSkill */ - delete(id: string, options?: RequestOptions): APIPromise { + delete(id: string, options?: IdentityScopeOptions): APIPromise { const path = `skills/${pathParam(id, "id")}`; return this._client.request({ method: "DELETE", path, responseType: "void", - ...options, + ...identityScopeOptions(options), }); } diff --git a/src/forward/types.ts b/src/forward/types.ts index e33d55f..595e004 100644 --- a/src/forward/types.ts +++ b/src/forward/types.ts @@ -1,3 +1,8 @@ +import type { RequestOptions } from '../core/client.js'; + +/** PAT identity ownership query. Omit identity_id when using a SAT. */ +export type IdentityScopeOptions = RequestOptions & { identity_id?: string }; + // Generated wire types, verified against the API contracts. // Wire names and required/nullable fields follow the API's JSON, query and header contracts. import type { Uploadable } from '../core/uploads.js'; @@ -429,10 +434,12 @@ export interface ChannelIdentityResolution { } export interface ChannelPairingNewParams { + /** Pending pairing ID. Supply exactly one of code or channel_pairing_id. */ + channel_pairing_id?: string; /** - * Channel 消息中显示的 6 位配对码。 + * Channel 消息中的配对码;与 channel_pairing_id 二选一。 */ - code: string; + code?: string; /** * 要绑定的 Forward Identity ID。 */ @@ -463,6 +470,12 @@ export interface DeletedChannelPairing { } export interface ChannelPairing { + scope_type: string; + scope_external_id: string; + scope_display_name: string; + created_at?: string; + updated_at?: string; + /** * Pairing ID,解除配对时使用。 */ @@ -869,6 +882,8 @@ export interface SessionEventParam { } export interface EnvironmentListParams { + /** Select identity ownership with a PAT. Omit when using a SAT. */ + identity_id?: string; /** * 分页大小,最大 100。 */ @@ -890,6 +905,8 @@ export interface EnvironmentListParams { } export interface EnvironmentNewParams { + /** Select identity ownership with a PAT. Omit when using a SAT. */ + identity_id?: string; /** * Environment 名称;去除首尾空白后不能为空。 */ @@ -915,6 +932,8 @@ export interface EnvironmentNewParams { } export interface EnvironmentUpdateParams { + /** Select identity ownership with a PAT. Omit when using a SAT. */ + identity_id?: string; /** * 新名称。 */ @@ -970,6 +989,8 @@ export interface EnvironmentConfigPackages { } export interface FileListParams { + /** Select identity ownership with a PAT. Omit when using a SAT. */ + identity_id?: string; /** * 分页大小,最大 100。 */ @@ -999,6 +1020,8 @@ export interface FileListParams { } export interface FileUploadParams { + /** Select identity ownership with a PAT. Omit when using a SAT. */ + identity_id?: string; /** * 待上传文件内容。支持类型见[支持上传的文件类型](./schemas.md#支持上传的文件类型)。 */ @@ -2322,7 +2345,7 @@ export interface Session { config: SessionConfig; resources: Array; stats: SessionStats; - usage: SessionUsage; + usage?: SessionUsage; archived_at: string | null; created_at: string; updated_at: string; @@ -2331,6 +2354,8 @@ export interface Session { } export interface SessionUsage { + model_credits?: number; + sandbox_runtime_credits?: number; total_credits: number; /** Additional fields are preserved verbatim by the SDK. */ [key: string]: unknown; @@ -2602,6 +2627,8 @@ export interface SessionThreadEventStreamParams { } export interface SkillListParams { + /** Select identity ownership with a PAT. Omit when using a SAT. */ + identity_id?: string; /** * 分页大小,最大 100。 */ @@ -2635,6 +2662,8 @@ export interface SkillListParams { } export interface SkillNewParams { + /** Select identity ownership with a PAT. Omit when using a SAT. */ + identity_id?: string; /** * 推荐上传字段,可**重复出现**多次。支持两种形态: ① 单个 `.zip` 包; ② 裸文件树——每个 part 独立上传一个文件,`filename` 携带相对路径(如 `code-review/SKILL.md`、`code-review/scripts/run.sh`)。 压缩包本身与解压后总大小均不超过 50 MB。 */ @@ -2672,6 +2701,8 @@ export interface SkillNewParams { } export interface SkillGetParams { + /** Select identity ownership with a PAT. Omit when using a SAT. */ + identity_id?: string; /** * ⚠️ **已弃用**:为 `true` 时随响应返回 `content` 与 `content_encoding`(base64 zip)。命中时响应头会返回 `Deprecation: true`。请改用 [下载 Skill 版本内容](./Versions/download.md)。 */ @@ -2681,6 +2712,8 @@ export interface SkillGetParams { } export interface SkillUpdateParams { + /** Select identity ownership with a PAT. Omit when using a SAT. */ + identity_id?: string; /** * 新描述。 */ @@ -2727,6 +2760,8 @@ export interface Skill { } export interface SkillVersionListParams { + /** Select identity ownership with a PAT. Omit when using a SAT. */ + identity_id?: string; /** * 分页大小,最大 100,默认 20。 */ @@ -2740,6 +2775,8 @@ export interface SkillVersionListParams { } export interface SkillVersionNewParams { + /** Select identity ownership with a PAT. Omit when using a SAT. */ + identity_id?: string; /** * 上传字段,可**重复**出现多次。支持两种形态: • 单个 `.zip` 包; • 裸文件树——每个 part 独立上传一个文件,`filename` 携带相对路径(如 `customer-reply/SKILL.md`、`customer-reply/scripts/run.sh`)。 压缩包本身与解压后总大小均不超过 50 MB。 */ @@ -3018,6 +3055,8 @@ export interface Template { } export interface VaultListParams { + /** Select identity ownership with a PAT. Omit when using a SAT. */ + identity_id?: string; /** * 分页大小,最大 100。 */ @@ -3043,6 +3082,8 @@ export interface VaultListParams { } export interface VaultNewParams { + /** Select identity ownership with a PAT. Omit when using a SAT. */ + identity_id?: string; /** * Vault 展示名。 */ @@ -3093,6 +3134,8 @@ export interface Vault { } export interface VaultCredentialListParams { + /** Select identity ownership with a PAT. Omit when using a SAT. */ + identity_id?: string; /** * 分页大小,最大 100。 */ @@ -3118,6 +3161,8 @@ export interface VaultCredentialListParams { } export interface VaultCredentialNewParams { + /** Select identity ownership with a PAT. Omit when using a SAT. */ + identity_id?: string; /** * Credential 认证信息,支持 `static_bearer`、`mcp_oauth`;响应只返回脱敏后的非密文字段。 */ diff --git a/src/forward/vault-credential.ts b/src/forward/vault-credential.ts index b8ca42d..7520552 100644 --- a/src/forward/vault-credential.ts +++ b/src/forward/vault-credential.ts @@ -1,9 +1,10 @@ // Generated code, verified against the API contracts. import { APIResource } from '../core/resource.js'; import type { RequestOptions } from '../core/client.js'; +import type { IdentityScopeOptions } from './types.js'; import type { APIPromise } from '../core/api-promise.js'; import type { PagePromise } from '../core/pagination.js'; -import { pathParam, requestHeaders } from './_utils.js'; +import { pathParam, requestHeaders, identityScopeOptions } from './_utils.js'; import type { VaultCredential, VaultCredentialCreateParams, VaultCredentialListParams, VaultCredentialUpdateParams } from './types.js'; export class VaultCredentials extends APIResource { @@ -41,12 +42,13 @@ export class VaultCredentials extends APIResource { options?: RequestOptions, ): APIPromise { const path = `vaults/${pathParam(id, "id")}/credentials`; - const { idempotency_key, ...payload } = params; + const { identity_id, idempotency_key, ...payload } = params; return this._client.request({ method: "POST", path, body: payload, ...options, + query: { identity_id, ...options?.query }, headers: requestHeaders({ "Idempotency-Key": idempotency_key }, options?.headers), }); } @@ -56,12 +58,12 @@ export class VaultCredentials extends APIResource { * * @operation getVaultCredential */ - retrieve(id: string, credID: string, options?: RequestOptions): APIPromise { + retrieve(id: string, credID: string, options?: IdentityScopeOptions): APIPromise { const path = `vaults/${pathParam(id, "id")}/credentials/${pathParam(credID, "cred_id")}`; return this._client.request({ method: "GET", path, - ...options, + ...identityScopeOptions(options), }); } @@ -70,13 +72,13 @@ export class VaultCredentials extends APIResource { * * @operation deleteVaultCredential */ - delete(id: string, credID: string, options?: RequestOptions): APIPromise { + delete(id: string, credID: string, options?: IdentityScopeOptions): APIPromise { const path = `vaults/${pathParam(id, "id")}/credentials/${pathParam(credID, "cred_id")}`; return this._client.request({ method: "DELETE", path, responseType: "void", - ...options, + ...identityScopeOptions(options), }); } diff --git a/src/forward/vault.ts b/src/forward/vault.ts index 32e189b..4398062 100644 --- a/src/forward/vault.ts +++ b/src/forward/vault.ts @@ -1,9 +1,10 @@ // Generated code, verified against the API contracts. import { APIResource } from '../core/resource.js'; import type { RequestOptions } from '../core/client.js'; +import type { IdentityScopeOptions } from './types.js'; import type { APIPromise } from '../core/api-promise.js'; import type { PagePromise } from '../core/pagination.js'; -import { pathParam, requestHeaders } from './_utils.js'; +import { pathParam, requestHeaders, identityScopeOptions } from './_utils.js'; import type { Vault, VaultCreateParams, VaultListParams } from './types.js'; import { VaultCredentials } from './vault-credential.js'; @@ -27,12 +28,13 @@ export class Vaults extends APIResource { */ create(params: VaultCreateParams, options?: RequestOptions): APIPromise { const path = "vaults"; - const { idempotency_key, ...payload } = params; + const { identity_id, idempotency_key, ...payload } = params; return this._client.request({ method: "POST", path, body: payload, ...options, + query: { identity_id, ...options?.query }, headers: requestHeaders({ "Idempotency-Key": idempotency_key }, options?.headers), }); } @@ -42,12 +44,12 @@ export class Vaults extends APIResource { * * @operation getVault */ - retrieve(id: string, options?: RequestOptions): APIPromise { + retrieve(id: string, options?: IdentityScopeOptions): APIPromise { const path = `vaults/${pathParam(id, "id")}`; return this._client.request({ method: "GET", path, - ...options, + ...identityScopeOptions(options), }); } @@ -56,13 +58,13 @@ export class Vaults extends APIResource { * * @operation deleteVault */ - delete(id: string, options?: RequestOptions): APIPromise { + delete(id: string, options?: IdentityScopeOptions): APIPromise { const path = `vaults/${pathParam(id, "id")}`; return this._client.request({ method: "DELETE", path, responseType: "void", - ...options, + ...identityScopeOptions(options), }); } diff --git a/src/managed/types.ts b/src/managed/types.ts index 51e3d2d..e936027 100644 --- a/src/managed/types.ts +++ b/src/managed/types.ts @@ -1668,8 +1668,8 @@ export interface ManagedAgentsDeployment { */ vault_ids: Array; /** - * A hard spend ceiling. The session stops issuing new model requests once the - * tracked list cost reaches `max_list_cost`. + * A total model and sandbox credit limit. Reaching it rejects the next user + * message without interrupting the running turn. */ budget?: ManagedAgentsBudgetLimit | null; } @@ -2160,8 +2160,8 @@ export interface DeploymentNewParams { description?: string | null; workspace_id?: string; /** - * A hard spend ceiling. The session stops issuing new model requests once the - * tracked list cost reaches `max_list_cost`. + * A total model and sandbox credit limit. Reaching it rejects the next user + * message without interrupting the running turn. */ budget?: ManagedAgentsBudgetLimitParam | null; /** @@ -2240,8 +2240,8 @@ export interface DeploymentUpdateParams { */ agent?: DeploymentUpdateParamsAgentUnion; /** - * A hard spend ceiling. The session stops issuing new model requests once the - * tracked list cost reaches `max_list_cost`. + * A total model and sandbox credit limit. Reaching it rejects the next user + * message without interrupting the running turn. */ budget?: ManagedAgentsBudgetLimitParam | null; /** @@ -6503,14 +6503,14 @@ export interface ManagedAgentsBranchCheckoutParam { } /** - * A hard spend ceiling. The session stops issuing new model requests once the - * tracked list cost reaches `max_list_cost`. + * A total model and sandbox credit limit. Reaching it rejects the next user + * message without interrupting the running turn. */ export interface ManagedAgentsBudgetLimit { /** - * A monetary amount in a specific currency. + * Positive decimal Credits with at most 12 integer and 2 fractional digits. */ - max_list_cost: MonetaryAmount; + max_credit_cost: string; /** * Any of "limit". */ @@ -6520,14 +6520,14 @@ export interface ManagedAgentsBudgetLimit { export type ManagedAgentsBudgetLimitType = "limit"; /** - * A hard spend ceiling. The session stops issuing new model requests once the - * tracked list cost reaches `max_list_cost`. + * A total model and sandbox credit limit. Reaching it rejects the next user + * message without interrupting the running turn. */ export interface ManagedAgentsBudgetLimitParam { /** - * A monetary amount in a specific currency. + * Positive decimal Credits with at most 12 integer and 2 fractional digits. */ - max_list_cost: MonetaryAmountParam; + max_credit_cost: string; /** * Any of "limit". */ @@ -6836,10 +6836,10 @@ export interface ManagedAgentsSession { */ archived_at: string | null; /** - * A hard spend ceiling. The session stops issuing new model requests once the - * tracked list cost reaches `max_list_cost`. + * A total model and sandbox credit limit. Reaching it rejects the next user + * message without interrupting the running turn. */ - budget: ManagedAgentsBudgetLimit; + budget?: ManagedAgentsBudgetLimit | null; /** * A timestamp in RFC 3339 format */ @@ -6872,9 +6872,9 @@ export interface ManagedAgentsSession { */ updated_at: string; /** - * Cumulative token usage for a session across all turns. + * Cumulative Credits snapshot. Legacy token and list-cost fields may appear in older responses. */ - usage: ManagedAgentsSessionUsage; + usage?: ManagedAgentsSessionUsage; /** * Vault IDs attached to the session at creation. Empty when no vaults were * supplied. @@ -7056,8 +7056,8 @@ export interface ManagedAgentsSessionUpdatedEvent { */ agent?: ManagedAgentsSessionAgent | null; /** - * A hard spend ceiling. The session stops issuing new model requests once the - * tracked list cost reaches `max_list_cost`. + * A total model and sandbox credit limit. Reaching it rejects the next user + * message without interrupting the running turn. */ budget?: ManagedAgentsBudgetLimit | null; /** @@ -7074,9 +7074,13 @@ export interface ManagedAgentsSessionUpdatedEvent { export type ManagedAgentsSessionUpdatedEventType = "session.updated"; /** - * Cumulative token usage for a session across all turns. + * Cumulative Credits snapshot. Legacy token and list-cost fields may appear in older responses. */ export interface ManagedAgentsSessionUsage { + /** Cumulative Credits. Replace the previous snapshot instead of adding it. */ + model_credits: number; + sandbox_runtime_credits: number; + total_credits: number; /** * Cumulative time in seconds during which the session had at least one thread in * running status. Overlapping activity from concurrent threads is counted once, @@ -7111,9 +7115,13 @@ export interface ManagedAgentsSessionUsage { } /** - * Periodic snapshot of the session's cumulative usage and tracked list cost. + * Cumulative Credits emitted before session.status_idle when usage is available. */ export interface ManagedAgentsSessionUsageEvent { + /** Cumulative Credits. Replace the previous snapshot instead of adding it. */ + model_credits: number; + sandbox_runtime_credits: number; + total_credits: number; /** * Unique identifier for this event. */ @@ -7126,13 +7134,11 @@ export interface ManagedAgentsSessionUsageEvent { * Any of "session.usage". */ type: ManagedAgentsSessionUsageEventType; + /** @deprecated Legacy nested usage; current events carry Credits at the top level. */ + usage?: ManagedAgentsSessionUsageSnapshot; /** - * Point-in-time snapshot of a session's cumulative usage. - */ - usage: ManagedAgentsSessionUsageSnapshot; - /** - * A hard spend ceiling. The session stops issuing new model requests once the - * tracked list cost reaches `max_list_cost`. + * A total model and sandbox credit limit. Reaching it rejects the next user + * message without interrupting the running turn. */ budget?: ManagedAgentsBudgetLimit | null; } @@ -7295,8 +7301,8 @@ export interface SessionNewParams { title?: string | null; workspace_id?: string; /** - * A hard spend ceiling. The session stops issuing new model requests once the - * tracked list cost reaches `max_list_cost`. + * A total model and sandbox credit limit. Reaching it rejects the next user + * message without interrupting the running turn. */ budget?: ManagedAgentsBudgetLimitParam | null; /** @@ -7356,8 +7362,8 @@ export interface SessionUpdateParams { */ agent?: ManagedAgentsSessionAgentUpdateParam | null; /** - * A hard spend ceiling. The session stops issuing new model requests once the - * tracked list cost reaches `max_list_cost`. + * A total model and sandbox credit limit. Reaching it rejects the next user + * message without interrupting the running turn. */ budget?: ManagedAgentsBudgetLimitParam | null; /** @@ -7650,6 +7656,8 @@ export type ManagedAgentsAgentThinkingEventType = "agent.thinking"; * Indicates that context compaction (summarization) occurred during the session. */ export interface ManagedAgentsAgentThreadContextCompactedEvent { + /** Credits for this compaction call, already included in Session usage. */ + usage?: ManagedAgentsSpanModelUsage; /** * Unique identifier for this event. */ @@ -8650,6 +8658,7 @@ export interface ManagedAgentsSessionEventUnionStopReason { } export interface ManagedAgentsSessionEventUnionUsage { + credits?: number; /** * This field is from variant `ManagedAgentsSpanModelUsage`. */ @@ -9017,9 +9026,9 @@ export interface ManagedAgentsSpanModelRequestEndEvent { */ model_request_start_id: string; /** - * Token usage for a single model request. + * Credits for a single model request; legacy token fields may appear in older responses. */ - model_usage: ManagedAgentsSpanModelUsage; + model_usage?: ManagedAgentsSpanModelUsage; /** * A timestamp in RFC 3339 format */ @@ -9053,25 +9062,26 @@ export interface ManagedAgentsSpanModelRequestStartEvent { export type ManagedAgentsSpanModelRequestStartEventType = "span.model_request_start"; /** - * Token usage for a single model request. + * Credits for a single model request; legacy token fields may appear in older responses. */ export interface ManagedAgentsSpanModelUsage { + credits: number; /** * Tokens used to create prompt cache in this request. */ - cache_creation_input_tokens: number; + cache_creation_input_tokens?: number; /** * Tokens read from prompt cache in this request. */ - cache_read_input_tokens: number; + cache_read_input_tokens?: number; /** * Input tokens consumed by this request. */ - input_tokens: number; + input_tokens?: number; /** * Output tokens generated by this request. */ - output_tokens: number; + output_tokens?: number; /** * Inference speed mode. `fast` provides significantly faster output token * generation at premium pricing. Not all models support `fast`; invalid @@ -9137,7 +9147,7 @@ export interface ManagedAgentsSpanOutcomeEvaluationEndEvent { */ type: ManagedAgentsSpanOutcomeEvaluationEndEventType; /** - * Token usage for a single model request. + * Credits for a single model request; legacy token fields may appear in older responses. */ usage: ManagedAgentsSpanModelUsage; } @@ -9220,6 +9230,7 @@ export interface ManagedAgentsStreamSessionEventsUnionStopReason { } export interface ManagedAgentsStreamSessionEventsUnionUsage { + credits?: number; /** * This field is from variant `ManagedAgentsSpanModelUsage`. */ @@ -10231,6 +10242,7 @@ export interface ManagedAgentsStreamSessionThreadEventsUnionStopReason { } export interface ManagedAgentsStreamSessionThreadEventsUnionUsage { + credits?: number; /** * This field is from variant `ManagedAgentsSpanModelUsage`. */ diff --git a/tests/identity-pairing-contract.test.mjs b/tests/identity-pairing-contract.test.mjs new file mode 100644 index 0000000..5122c32 --- /dev/null +++ b/tests/identity-pairing-contract.test.mjs @@ -0,0 +1,88 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { testClient, response } from './helpers.mjs'; +import { toFile } from '../dist/index.js'; + +// Official Forward resource ownership and pairing contracts (2026-10-20). +const operations = [ + ["GET", "environments", (c, scope, file) => c.environments.list({ ...scope })], + ["POST", "environments", (c, scope, file) => c.environments.create({ name: 'env', ...scope })], + ["GET", "environments/env", (c, scope, file) => c.environments.retrieve('env', scope)], + ["POST", "environments/env", (c, scope, file) => c.environments.update('env', { name: 'renamed', ...scope })], + ["POST", "environments/env/archive", (c, scope, file) => c.environments.archive('env', scope)], + ["DELETE", "environments/env", (c, scope, file) => c.environments.delete('env', scope)], + ["GET", "skills", (c, scope, file) => c.skills.list(scope)], + ["POST", "skills", (c, scope, file) => c.skills.create({ files: [file], ...scope })], + ["GET", "skills/skill", (c, scope, file) => c.skills.retrieve('skill', scope)], + ["PUT", "skills/skill", (c, scope, file) => c.skills.update('skill', { description: 'desc', ...scope })], + ["DELETE", "skills/skill", (c, scope, file) => c.skills.delete('skill', scope)], + ["GET", "skills/skill/versions", (c, scope, file) => c.skills.versions.list('skill', scope)], + ["POST", "skills/skill/versions", (c, scope, file) => c.skills.versions.create('skill', { files: [file], ...scope })], + ["GET", "skills/skill/versions/1", (c, scope, file) => c.skills.versions.retrieve('skill', '1', scope)], + ["DELETE", "skills/skill/versions/1", (c, scope, file) => c.skills.versions.delete('skill', '1', scope)], + ["GET", "skills/skill/versions/1/content", (c, scope, file) => c.skills.versions.download('skill', '1', scope)], + ["GET", "vaults", (c, scope, file) => c.vaults.list(scope)], + ["POST", "vaults", (c, scope, file) => c.vaults.create({ display_name: 'vault', ...scope })], + ["GET", "vaults/vault", (c, scope, file) => c.vaults.retrieve('vault', scope)], + ["DELETE", "vaults/vault", (c, scope, file) => c.vaults.delete('vault', scope)], + ["GET", "vaults/vault/credentials", (c, scope, file) => c.vaults.credentials.list('vault', scope)], + ["POST", "vaults/vault/credentials", (c, scope, file) => c.vaults.credentials.create('vault', { auth: { type: 'static_bearer', token: 'secret' }, ...scope })], + ["GET", "vaults/vault/credentials/cred", (c, scope, file) => c.vaults.credentials.retrieve('vault', 'cred', scope)], + ["POST", "vaults/vault/credentials/cred", (c, scope, file) => c.vaults.credentials.update('vault', 'cred', { metadata: { note: 'rotation' }, ...scope })], + ["DELETE", "vaults/vault/credentials/cred", (c, scope, file) => c.vaults.credentials.delete('vault', 'cred', scope)], + ["GET", "files", (c, scope, file) => c.files.list(scope)], + ["POST", "files", (c, scope, file) => c.files.upload({ file, ...scope })], + ["GET", "files/file", (c, scope, file) => c.files.getMetadata('file', scope)], + ["DELETE", "files/file", (c, scope, file) => c.files.delete('file', scope)], + ["GET", "files/file/content", (c, scope, file) => c.files.download('file', scope)], + ]; +for (const [method, path, call] of operations) { + for (const identity of ['idn_ /?&', '', undefined]) test(`${method} ${path} identity=${identity}`, async () => { + let apiCalls = 0; + const c = testClient('forward', async req => { + const url = new URL(req.url); + if (url.hostname === 'storage.test') { + assert.equal(url.search, '?signature=ok'); + assert.equal(req.headers.get('authorization'), null); + return new Response('content'); + } + apiCalls++; + assert.equal(req.method, method); + assert.equal(url.pathname, `/api/v1/forward/${path}`); + assert.equal(url.searchParams.get('identity_id'), identity ?? null); + assert.deepEqual([...url.searchParams.keys()], identity === undefined ? [] : ['identity_id']); + assert.ok(!(await req.text()).includes('identity_id')); + if (path === 'files/file/content') return response({ url: 'https://storage.test/content?signature=ok' }); + if (path.endsWith('/content')) return new Response('archive'); + return response({ id: 'resource', data: [], has_more: false }); + }); + const result = await call(c, identity === undefined ? {} : { identity_id: identity }, await toFile('# skill', 'SKILL.md')); + if (result instanceof Response) await result.arrayBuffer(); + assert.equal(apiCalls, 1); + }); +} + +test('Identity options keep explicit query overrides and pagination scope', async () => { + let calls = 0; + const c = testClient('forward', req => { + const url = new URL(req.url); + assert.equal(url.searchParams.get('identity_id'), 'idn_override'); + calls++; + return response({ data: [{ id: `env_${calls}` }], has_more: calls === 1, next_page: calls === 1 ? 'cursor' : null }); + }); + const items = []; for await (const e of c.environments.list({ identity_id: 'idn_typed' }, { query: { identity_id: 'idn_override' } })) items.push(e); + assert.equal(items.length, 2); + await c.environments.retrieve('env', { identity_id: 'idn_typed', query: { identity_id: 'idn_override' } }); + await c.environments.create({ name: 'env', identity_id: 'idn_typed' }, { query: { identity_id: 'idn_override' } }); +}); +const pairing = {"id": "pair_one", "type": "channel_pairing", "channel_id": "channel_one", "scope_type": "room", "scope_external_id": "room_one", "scope_display_name": "Team", "identity_id": "idn_one", "template_id": "tmpl_one", "status": "active", "paired_at": "2026-10-20T01:00:00Z"}; +for (const selector of [{ code: 'K7MP92' }, { channel_pairing_id: 'pair_one' }]) test(`Pair channel with ${Object.keys(selector)[0]}`, async () => { + const c = testClient('forward', async req => { + assert.equal(new URL(req.url).search, ''); + assert.equal(req.headers.get('idempotency-key'), 'pair-once'); + assert.deepEqual(await req.json(), { ...selector, identity_id: 'idn_one', template_id: 'tmpl_one' }); + return response(pairing); + }); + const result = await c.channelPairings.create({ ...selector, identity_id: 'idn_one', template_id: 'tmpl_one', idempotency_key: 'pair-once' }); + assert.deepEqual(result, pairing); +}); diff --git a/tests/managed-field-parity.test.mjs b/tests/managed-field-parity.test.mjs index 3984070..4814c01 100644 --- a/tests/managed-field-parity.test.mjs +++ b/tests/managed-field-parity.test.mjs @@ -72,7 +72,9 @@ test('Managed wire parity: all 695 pinned types keep their 2569 wire properties, const type = declared(name); for (const wire of spec.properties ?? []) { properties++; - if (!explicitProperty(type, wire).length) failures.push(`${name}: explicit property ${wire} missing`); + // QCA budget uses decimal Credits: /cloud-agents/api/sessions/schemas#session-budget. + const currentWire = ["ManagedAgentsBudgetLimit", "ManagedAgentsBudgetLimitParam"].includes(name) && wire === "max_list_cost" ? "max_credit_cost" : wire; + if (!explicitProperty(type, currentWire).length) failures.push(`${name}: explicit property ${wire} missing`); } for (const notation of spec.variants ?? []) { variants++; diff --git a/tests/managed-types.ts b/tests/managed-types.ts index c39a342..6e89721 100644 --- a/tests/managed-types.ts +++ b/tests/managed-types.ts @@ -33,3 +33,17 @@ const customToolJSONSchema: M.ManagedAgentsCustomToolInputSchemaParam = { $defs: { label: { type: 'string', minLength: 1 } }, patternProperties: { '^x-': { $ref: '#/$defs/label' } }, }; + +// Official Credits contracts: no currency object or nested session.usage required. +const creditBudget: M.ManagedAgentsBudgetLimitParam = { type: 'limit', max_credit_cost: '100.00' }; +// @ts-expect-error Credits limits are decimal strings, not the former currency object. +const oldCreditBudget: M.ManagedAgentsBudgetLimitParam = { type: 'limit', max_list_cost: { amount: '100', currency: 'USD' } }; +const creditSnapshot: M.ManagedAgentsSessionUsage = { model_credits: 7.66, sandbox_runtime_credits: 0.34, total_credits: 8 }; +const creditEvent: M.ManagedAgentsSessionUsageEvent = { id: 'evt_one', processed_at: '2026-10-20T01:00:00Z', type: 'session.usage', ...creditSnapshot }; +const creditModelUsage: M.ManagedAgentsSpanModelUsage = { credits: 1.25 }; +const creditCompaction: M.ManagedAgentsAgentThreadContextCompactedEvent = { id: 'evt_two', processed_at: '2026-10-20T01:00:00Z', type: 'agent.thread_context_compacted', usage: { credits: 0 } }; +void [creditBudget, oldCreditBudget, creditSnapshot, creditEvent, creditModelUsage, creditCompaction]; + +const absentSessionBudget: Pick = {}; +const clearedSessionBudget: Pick = { budget: null }; +void [absentSessionBudget, clearedSessionBudget]; diff --git a/tests/session-credit-contract.test.mjs b/tests/session-credit-contract.test.mjs new file mode 100644 index 0000000..6d959b9 --- /dev/null +++ b/tests/session-credit-contract.test.mjs @@ -0,0 +1,36 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { testClient, response } from './helpers.mjs'; + +// https://docs.qoder.com/cloud-agents/api/sessions/schemas, 2026-10-20. +for (const body of [{ budget: { type: 'limit', max_credit_cost: '100.00' } }, {}, { budget: null }]) { + test(`Session budget preserves decimal/omission/null: ${JSON.stringify(body)}`, async () => { + const client = testClient('managed', async req => { + assert.deepEqual(await req.json(), body); + return response({ id: 'sess_one', ...body }); + }); + const session = await client.sessions.update('sess_one', body); + assert.deepEqual(session.budget, body.budget); + }); +} +for (const mode of ['managed', 'forward']) test(`${mode} cumulative Credits snapshot`, async () => { + const usage = { model_credits: 7.66, sandbox_runtime_credits: 0.34, total_credits: 8 }; + const client = testClient(mode, req => response({ id: 'sess_one', ...(req.url.endsWith('sess_one') ? { usage } : {}) })); + assert.deepEqual((await client.sessions.retrieve('sess_one')).usage, usage); + assert.equal((await client.sessions.retrieve('sess_empty')).usage, undefined); +}); +test('Managed history and SSE preserve top-level and per-call Credits', async () => { + const events = [ + { id: 'evt_1', type: 'session.usage', model_credits: 7.66, sandbox_runtime_credits: 0.34, total_credits: 8 }, + { id: 'evt_2', type: 'agent.thread_context_compacted', usage: { credits: 0 } }, + { id: 'evt_3', type: 'span.model_request_end', model_usage: { credits: 1.25 } }, + ]; + const client = testClient('managed', req => req.url.endsWith('/stream') + ? new Response(events.map(e => `id: ${e.id}\nevent: ${e.type}\ndata: ${JSON.stringify(e)}\n\n`).join(''), { headers: { 'content-type': 'text/event-stream' } }) + : response({ data: events, has_more: false, next_page: null })); + assert.deepEqual((await client.sessions.events.list('sess_one')).data, events); + for (const stream of [await client.sessions.events.streamEvents('sess_one'), await client.sessions.threads.events.streamEvents('thread_one', { session_id: 'sess_one' })]) { + const actual = []; for await (const e of stream) actual.push(e); + assert.deepEqual(actual, events); + } +}); diff --git a/tests/types-smoke.ts b/tests/types-smoke.ts index 996c737..b87579f 100644 --- a/tests/types-smoke.ts +++ b/tests/types-smoke.ts @@ -216,3 +216,22 @@ forward.drives.listEntries({}); forward.drives.listEntries({ identity_id: 'idn', page: 'cursor' }); // @ts-expect-error Managed does not expose Forward Drive. managed.drives; + +async function ownershipAndPairingTypes() { + await forward.environments.create({ name: 'env', identity_id: 'idn_one' }); + await forward.environments.retrieve('env', { identity_id: 'idn_one', timeout: 1000 }); + await forward.environments.archive('env', { identity_id: 'idn_one' }); + await forward.skills.versions.retrieve('skill', '1', { identity_id: 'idn_one' }); + await forward.vaults.credentials.delete('vault', 'cred', { identity_id: 'idn_one' }); + await forward.files.download('file', { identity_id: 'idn_one' }); + // @ts-expect-error Identity scope is a string, not a number. + forward.files.download('file', { identity_id: 123 }); + const pairing = await forward.channelPairings.create({ channel_pairing_id: 'pair_one', identity_id: 'idn_one', template_id: 'tmpl_one' }); + const scope: string = pairing.scope_external_id; + const display: string = pairing.scope_display_name; + void [scope, display]; + const session = await forward.sessions.retrieve('sess_one'); + const credits: number | undefined = session.usage?.model_credits; + void credits; +} +void ownershipAndPairingTypes;