@soat/cli 0.44.0 → 0.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.mjs +158 -26
  2. package/package.json +2 -2
package/dist/index.mjs CHANGED
@@ -13,7 +13,7 @@ import * as os from "node:os";
13
13
  import { createHmac, timingSafeEqual } from "node:crypto";
14
14
 
15
15
  //#region package.json
16
- var version = "0.44.0";
16
+ var version = "0.46.0";
17
17
 
18
18
  //#endregion
19
19
  //#region src/cli-wrappers/wrappers/formations.ts
@@ -481,7 +481,7 @@ var routes = {
481
481
  moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/actors",
482
482
  httpMethod: "get",
483
483
  pathParams: [],
484
- queryParams: ["project_id", "external_id", "agent_id", "chat_id", "conversation_id", "limit", "offset"],
484
+ queryParams: ["project_id", "external_id", "name", "agent_id", "chat_id", "conversation_id", "limit", "offset"],
485
485
  flags: [{
486
486
  "name": "project_id",
487
487
  "description": "Project ID (optional)",
@@ -494,6 +494,12 @@ var routes = {
494
494
  "required": false,
495
495
  "type": "string",
496
496
  "in": "query"
497
+ }, {
498
+ "name": "name",
499
+ "description": "Case-insensitive substring match on the actor name",
500
+ "required": false,
501
+ "type": "string",
502
+ "in": "query"
497
503
  }, {
498
504
  "name": "agent_id",
499
505
  "description": "Return only actors linked to this agent",
@@ -1695,7 +1701,7 @@ var routes = {
1695
1701
  "list-api-keys": {
1696
1702
  serviceClass: "APIKeys",
1697
1703
  operationId: "listApiKeys",
1698
- description: "Lists API keys accessible to the caller. - JWT admin: returns all API keys. - JWT regular user: returns only the user's own API keys. - Project-scoped credential (API key or OAuth token): returns only API keys scoped to that project.",
1704
+ description: "Lists API keys accessible to the caller. - JWT admin: returns all API keys. - JWT regular user: returns only the user's own API keys. - Project-scoped credential (API key or OAuth token): returns the caller's own keys scoped to that project, or every key scoped to it when the credential holds `api-keys:ListApiKeys` on the project. Confinement to a project is not authority over it, and a key's metadata names its owner, prefix and attached policies.",
1699
1705
  moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/api-keys",
1700
1706
  httpMethod: "get",
1701
1707
  pathParams: [],
@@ -1926,7 +1932,7 @@ var routes = {
1926
1932
  "in": "path"
1927
1933
  }, {
1928
1934
  "name": "arguments",
1929
- "description": "Edited arguments to execute instead of the proposed ones",
1935
+ "description": "Edited arguments to execute instead of the proposed ones. Editing composes a new call, so it additionally requires permission to make that call: `tools:CallTool` on the tool, and for a `builtin` proposal the action's own IAM action.",
1930
1936
  "required": false,
1931
1937
  "type": "object",
1932
1938
  "in": "body"
@@ -3006,7 +3012,7 @@ var routes = {
3006
3012
  "in": "body"
3007
3013
  }, {
3008
3014
  "name": "inputs",
3009
- "description": "Batch of texts to embed.",
3015
+ "description": "Batch of texts to embed. At most 256 per request — each input is one call to the embedding model, so a larger batch is refused (`VALIDATION_FAILED`) rather than queued. Split it across requests.",
3010
3016
  "required": false,
3011
3017
  "type": "array",
3012
3018
  "in": "body"
@@ -3933,13 +3939,19 @@ var routes = {
3933
3939
  moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/files",
3934
3940
  httpMethod: "get",
3935
3941
  pathParams: ["file_id"],
3936
- queryParams: [],
3942
+ queryParams: ["token"],
3937
3943
  flags: [{
3938
3944
  "name": "file_id",
3939
3945
  "description": "File ID",
3940
3946
  "required": true,
3941
3947
  "type": "string",
3942
3948
  "in": "path"
3949
+ }, {
3950
+ "name": "token",
3951
+ "description": "Signed single-file download token, an alternative to a bearer credential (issued for ingestion-rule converters).",
3952
+ "required": false,
3953
+ "type": "string",
3954
+ "in": "query"
3943
3955
  }]
3944
3956
  },
3945
3957
  "update-file-metadata": {
@@ -3983,13 +3995,19 @@ var routes = {
3983
3995
  moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/files",
3984
3996
  httpMethod: "get",
3985
3997
  pathParams: ["file_id"],
3986
- queryParams: [],
3998
+ queryParams: ["token"],
3987
3999
  flags: [{
3988
4000
  "name": "file_id",
3989
4001
  "description": "File ID",
3990
4002
  "required": true,
3991
4003
  "type": "string",
3992
4004
  "in": "path"
4005
+ }, {
4006
+ "name": "token",
4007
+ "description": "Signed single-file download token, an alternative to a bearer credential (issued for ingestion-rule converters).",
4008
+ "required": false,
4009
+ "type": "string",
4010
+ "in": "query"
3993
4011
  }]
3994
4012
  },
3995
4013
  "get-file-tags": {
@@ -4265,7 +4283,7 @@ var routes = {
4265
4283
  moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/generations",
4266
4284
  httpMethod: "get",
4267
4285
  pathParams: [],
4268
- queryParams: ["agent_id", "trace_id", "initiator_generation_id", "chain_id", "orchestration_run_id", "node_id", "status", "limit", "offset"],
4286
+ queryParams: ["agent_id", "trace_id", "session_id", "actor_id", "initiator_generation_id", "chain_id", "orchestration_run_id", "node_id", "status", "limit", "offset"],
4269
4287
  flags: [{
4270
4288
  "name": "agent_id",
4271
4289
  "description": "Filter by agent public ID",
@@ -4278,6 +4296,18 @@ var routes = {
4278
4296
  "required": false,
4279
4297
  "type": "string",
4280
4298
  "in": "query"
4299
+ }, {
4300
+ "name": "session_id",
4301
+ "description": "Return only the generations dispatched through one session — the turns behind that conversation's spend. A session that does not exist in scope yields an empty page.\n",
4302
+ "required": false,
4303
+ "type": "string",
4304
+ "in": "query"
4305
+ }, {
4306
+ "name": "actor_id",
4307
+ "description": "Return only the generations one end user started, across every session they appear in. An actor that does not exist in scope yields an empty page.\n",
4308
+ "required": false,
4309
+ "type": "string",
4310
+ "in": "query"
4281
4311
  }, {
4282
4312
  "name": "initiator_generation_id",
4283
4313
  "description": "Filter by the public ID of the parent generation. Returns all generations triggered by that generation — sub-agent invocations. Null-initiated (top-level) generations are not returned.\n",
@@ -4712,7 +4742,7 @@ var routes = {
4712
4742
  "in": "body"
4713
4743
  }, {
4714
4744
  "name": "content_type_glob",
4715
- "description": "MIME type glob matched against a file's content_type",
4745
+ "description": "MIME type glob matched against a file's content_type. At most 4 wildcards and 255 characters — a MIME glob needs one on each side of the slash at most.",
4716
4746
  "required": true,
4717
4747
  "type": "string",
4718
4748
  "in": "body"
@@ -4810,7 +4840,7 @@ var routes = {
4810
4840
  "in": "path"
4811
4841
  }, {
4812
4842
  "name": "content_type_glob",
4813
- "description": "",
4843
+ "description": "MIME type glob matched against a file's content_type. At most 4 wildcards and 255 characters.",
4814
4844
  "required": false,
4815
4845
  "type": "string",
4816
4846
  "in": "body"
@@ -4920,7 +4950,7 @@ var routes = {
4920
4950
  "in": "body"
4921
4951
  }, {
4922
4952
  "name": "limit",
4923
- "description": "Maximum number of results to return (default 10)",
4953
+ "description": "Maximum number of results to return (default 10). A value above 100 is clamped to 100 — the ceiling bounds the vector scan this one request performs, so a larger `limit` returns everything there is up to that many rows rather than being refused.",
4924
4954
  "required": false,
4925
4955
  "type": "integer",
4926
4956
  "in": "body"
@@ -5499,7 +5529,7 @@ var routes = {
5499
5529
  "get-queue-stats": {
5500
5530
  serviceClass: "Orchestrations",
5501
5531
  operationId: "getQueueStats",
5502
- description: "Returns a point-in-time snapshot of the orchestration run queue: how many tasks are waiting to be claimed (`queue_depth`), how many are currently claimed with a valid lease (`claimed_tasks`), the age of the oldest waiting task, recent claim-latency percentiles over a rolling in-process window, and a per-project breakdown. Intended for admin/operator policies; guarded by `orchestrations:GetQueueStats`. A project-scoped caller sees only their own projects under `per_project`.",
5532
+ description: "Returns a point-in-time snapshot of the orchestration run queue: how many tasks are waiting to be claimed (`queue_depth`), how many are currently claimed with a valid lease (`claimed_tasks`), the age of the oldest waiting task, recent claim-latency percentiles over a rolling in-process window, and a per-project breakdown. Intended for admin/operator policies; guarded by `orchestrations:GetQueueStats`. Every figure is scoped to what the caller may see. A project-scoped caller gets `per_project` for their own projects only, `queue_depth` and `claimed_tasks` summed over those same projects, and `null` for `oldest_queued_age_seconds` and the `claim_latency_ms` percentiles — both describe the whole deployment and cannot be narrowed, so they are withheld rather than approximated. An unrestricted caller (the action granted on every project) gets the deployment-wide figures.",
5503
5533
  moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/orchestrations",
5504
5534
  httpMethod: "get",
5505
5535
  pathParams: [],
@@ -6429,13 +6459,19 @@ var routes = {
6429
6459
  moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/secrets",
6430
6460
  httpMethod: "delete",
6431
6461
  pathParams: ["secret_id"],
6432
- queryParams: [],
6462
+ queryParams: ["force"],
6433
6463
  flags: [{
6434
6464
  "name": "secret_id",
6435
6465
  "description": "Secret ID",
6436
6466
  "required": true,
6437
6467
  "type": "string",
6438
6468
  "in": "path"
6469
+ }, {
6470
+ "name": "force",
6471
+ "description": "Delete the secret even when AI providers reference it, destroying those providers too. Without it a referenced secret answers SECRET_HAS_DEPENDENTS.",
6472
+ "required": false,
6473
+ "type": "boolean",
6474
+ "in": "query"
6439
6475
  }]
6440
6476
  },
6441
6477
  "list-sessions": {
@@ -6533,7 +6569,7 @@ var routes = {
6533
6569
  "get-session": {
6534
6570
  serviceClass: "Sessions",
6535
6571
  operationId: "getSession",
6536
- description: "Returns details of a single session.",
6572
+ description: "Returns details of a single session, including a `usage` roll-up of what its generations cost. The listing omits `usage`; for a window, a split by day or model, or one end user across every session, narrow the usage aggregate with `session_id` / `actor_id` instead.",
6537
6573
  moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/sessions",
6538
6574
  httpMethod: "get",
6539
6575
  pathParams: ["session_id"],
@@ -7176,13 +7212,13 @@ var routes = {
7176
7212
  "in": "body"
7177
7213
  }, {
7178
7214
  "name": "execute",
7179
- "description": "Execution config for http tools. Supported fields: `url` (required), `method` (default `POST`), `headers`, and `body_mode`. The `url` may contain `{paramName}` placeholders (e.g. `/users/{userId}`) that are replaced at call time with the corresponding tool argument value (URL-encoded). Arguments consumed as path parameters are excluded from the query string and request body. `body_mode` is `json` (default) or `multipart`. In `multipart` mode the merged tool arguments are sent as a `multipart/form-data` body: scalar fields become plain form fields and a field shaped like `{ content_type, filename, data_base64 }` is decoded from base64 and attached as a file part (the hardcoded `Content-Type: application/json` is dropped so `fetch` sets the multipart boundary itself).\n\n`auth` adds a computed request credential, for targets whose `Authorization` value cannot be expressed as a static header. Supported `auth.type` values:\n\n- `aws_sigv4` — signs the request with AWS Signature Version 4. Requires `region`, `service`, `access_key_id` and `secret_access_key`; `session_token` is optional (temporary credentials). Incompatible with `body_mode: multipart`, whose body bytes are not known at signing time.\n- `gcp_service_account` — mints a Google OAuth 2.0 access token from a signed service account assertion and sends it as a bearer token. Requires `credentials` (the service account key file JSON, as a string) and `scopes` (a non-empty array). Tokens are cached per service account and scope set until shortly before they expire.\n\nCredential fields accept `{{secret:...}}` references and should use them — a tool is readable by anyone who can `GET /tools`, and the stored reference is what is echoed back, never the resolved value.\n\n`headers` values additionally accept `{{context:<key>}}` references, resolved per call from the caller's `tool_context`, so a per-user credential can be placed in the real header the target expects (`Authorization: Bearer {{context:ocaToken}}`) instead of only in an `X-Soat-Context-<key>` header. Valid **only** inside `headers` — a context value is caller-supplied, so it may not steer the `url` — and a key missing from the `tool_context` at call time fails the tool call with `MISSING_TOOL_CONTEXT_KEY` rather than sending an empty credential. See the Tool Context reference.\n",
7215
+ "description": "Execution config for http tools. Supported fields: `url` (required), `method` (default `POST`), `headers`, and `body_mode`. The `url` may contain `{paramName}` placeholders (e.g. `/users/{userId}`) that are replaced at call time with the corresponding tool argument value (URL-encoded). Arguments consumed as path parameters are excluded from the query string and request body. `body_mode` is `json` (default) or `multipart`. In `multipart` mode the merged tool arguments are sent as a `multipart/form-data` body: scalar fields become plain form fields and a field shaped like `{ content_type, filename, data_base64 }` is decoded from base64 and attached as a file part (the hardcoded `Content-Type: application/json` is dropped so `fetch` sets the multipart boundary itself).\n\n`auth` adds a computed request credential, for targets whose `Authorization` value cannot be expressed as a static header. Supported `auth.type` values:\n\n- `aws_sigv4` — signs the request with AWS Signature Version 4. Requires `region`, `service`, `access_key_id` and `secret_access_key`; `session_token` is optional (temporary credentials). Incompatible with `body_mode: multipart`, whose body bytes are not known at signing time.\n- `gcp_service_account` — mints a Google OAuth 2.0 access token from a signed service account assertion and sends it as a bearer token. Requires `credentials` (the service account key file JSON, as a string) and `scopes` (a non-empty array). Tokens are cached per service account and scope set until shortly before they expire.\n\nCredential fields accept `{{secret:...}}` references and should use them — a tool is readable by anyone who can `GET /tools`, and the stored reference is what is echoed back, never the resolved value.\n\nA credential written as a **literal** is stored and still sent on every call, but it is masked on every read: `secret_access_key`, `session_token` and `credentials` under `auth`, and any credential-named `headers` value (`Authorization`, `Cookie`, or a name containing `api-key`/`token`/`secret`/`password`), come back as `{\"no_echo\": true}`. The mask is an object rather than a string so a read-edit-write round trip fails the schema check instead of writing the placeholder in as the credential. A value carrying a `{{secret:...}}` reference is the wiring, not the credential, and stays readable.\n\n`headers` values additionally accept `{{context:<key>}}` references, resolved per call from the caller's `tool_context`, so a per-user credential can be placed in the real header the target expects (`Authorization: Bearer {{context:ocaToken}}`) instead of only in an `X-Soat-Context-<key>` header. Valid **only** inside `headers` — a context value is caller-supplied, so it may not steer the `url` — and a key missing from the `tool_context` at call time fails the tool call with `MISSING_TOOL_CONTEXT_KEY` rather than sending an empty credential. See the Tool Context reference.\n",
7180
7216
  "required": false,
7181
7217
  "type": "object",
7182
7218
  "in": "body"
7183
7219
  }, {
7184
7220
  "name": "mcp",
7185
- "description": "MCP server config (`url`, `headers`). `headers` values accept `{{secret:...}}` and `{{context:<key>}}` references, resolved right before the outbound MCP request; `url` accepts `{{secret:...}}` only.",
7221
+ "description": "MCP server config (`url`, `headers`). `headers` values accept `{{secret:...}}` and `{{context:<key>}}` references, resolved right before the outbound MCP request; `url` accepts `{{secret:...}}` only. A literal credential in `headers` is masked on read, exactly as in `execute`.",
7186
7222
  "required": false,
7187
7223
  "type": "object",
7188
7224
  "in": "body"
@@ -7286,13 +7322,13 @@ var routes = {
7286
7322
  "in": "body"
7287
7323
  }, {
7288
7324
  "name": "execute",
7289
- "description": "Execution config for http tools. Supported fields: `url` (required), `method` (default `POST`), `headers`, and `body_mode`. The `url` may contain `{paramName}` placeholders (e.g. `/users/{userId}`) that are replaced at call time with the corresponding tool argument value (URL-encoded). Arguments consumed as path parameters are excluded from the query string and request body. `body_mode` is `json` (default) or `multipart`. In `multipart` mode the merged tool arguments are sent as a `multipart/form-data` body: scalar fields become plain form fields and a field shaped like `{ content_type, filename, data_base64 }` is decoded from base64 and attached as a file part (the hardcoded `Content-Type: application/json` is dropped so `fetch` sets the multipart boundary itself).\n\n`auth` adds a computed request credential, for targets whose `Authorization` value cannot be expressed as a static header. Supported `auth.type` values:\n\n- `aws_sigv4` — signs the request with AWS Signature Version 4. Requires `region`, `service`, `access_key_id` and `secret_access_key`; `session_token` is optional (temporary credentials). Incompatible with `body_mode: multipart`, whose body bytes are not known at signing time.\n- `gcp_service_account` — mints a Google OAuth 2.0 access token from a signed service account assertion and sends it as a bearer token. Requires `credentials` (the service account key file JSON, as a string) and `scopes` (a non-empty array). Tokens are cached per service account and scope set until shortly before they expire.\n\nCredential fields accept `{{secret:...}}` references and should use them — a tool is readable by anyone who can `GET /tools`, and the stored reference is what is echoed back, never the resolved value.\n\n`headers` values additionally accept `{{context:<key>}}` references, resolved per call from the caller's `tool_context`, so a per-user credential can be placed in the real header the target expects (`Authorization: Bearer {{context:ocaToken}}`) instead of only in an `X-Soat-Context-<key>` header. Valid **only** inside `headers` — a context value is caller-supplied, so it may not steer the `url` — and a key missing from the `tool_context` at call time fails the tool call with `MISSING_TOOL_CONTEXT_KEY` rather than sending an empty credential. See the Tool Context reference.\n",
7325
+ "description": "Execution config for http tools. Supported fields: `url` (required), `method` (default `POST`), `headers`, and `body_mode`. The `url` may contain `{paramName}` placeholders (e.g. `/users/{userId}`) that are replaced at call time with the corresponding tool argument value (URL-encoded). Arguments consumed as path parameters are excluded from the query string and request body. `body_mode` is `json` (default) or `multipart`. In `multipart` mode the merged tool arguments are sent as a `multipart/form-data` body: scalar fields become plain form fields and a field shaped like `{ content_type, filename, data_base64 }` is decoded from base64 and attached as a file part (the hardcoded `Content-Type: application/json` is dropped so `fetch` sets the multipart boundary itself).\n\n`auth` adds a computed request credential, for targets whose `Authorization` value cannot be expressed as a static header. Supported `auth.type` values:\n\n- `aws_sigv4` — signs the request with AWS Signature Version 4. Requires `region`, `service`, `access_key_id` and `secret_access_key`; `session_token` is optional (temporary credentials). Incompatible with `body_mode: multipart`, whose body bytes are not known at signing time.\n- `gcp_service_account` — mints a Google OAuth 2.0 access token from a signed service account assertion and sends it as a bearer token. Requires `credentials` (the service account key file JSON, as a string) and `scopes` (a non-empty array). Tokens are cached per service account and scope set until shortly before they expire.\n\nCredential fields accept `{{secret:...}}` references and should use them — a tool is readable by anyone who can `GET /tools`, and the stored reference is what is echoed back, never the resolved value.\n\nA credential written as a **literal** is stored and still sent on every call, but it is masked on every read: `secret_access_key`, `session_token` and `credentials` under `auth`, and any credential-named `headers` value (`Authorization`, `Cookie`, or a name containing `api-key`/`token`/`secret`/`password`), come back as `{\"no_echo\": true}`. The mask is an object rather than a string so a read-edit-write round trip fails the schema check instead of writing the placeholder in as the credential. A value carrying a `{{secret:...}}` reference is the wiring, not the credential, and stays readable.\n\n`headers` values additionally accept `{{context:<key>}}` references, resolved per call from the caller's `tool_context`, so a per-user credential can be placed in the real header the target expects (`Authorization: Bearer {{context:ocaToken}}`) instead of only in an `X-Soat-Context-<key>` header. Valid **only** inside `headers` — a context value is caller-supplied, so it may not steer the `url` — and a key missing from the `tool_context` at call time fails the tool call with `MISSING_TOOL_CONTEXT_KEY` rather than sending an empty credential. See the Tool Context reference.\n",
7290
7326
  "required": false,
7291
7327
  "type": "object",
7292
7328
  "in": "body"
7293
7329
  }, {
7294
7330
  "name": "mcp",
7295
- "description": "MCP server config (`url`, `headers`). `headers` values accept `{{secret:...}}` and `{{context:<key>}}` references, resolved right before the outbound MCP request; `url` accepts `{{secret:...}}` only.",
7331
+ "description": "MCP server config (`url`, `headers`). `headers` values accept `{{secret:...}}` and `{{context:<key>}}` references, resolved right before the outbound MCP request; `url` accepts `{{secret:...}}` only. A literal credential in `headers` is masked on read, exactly as in `execute`.",
7296
7332
  "required": false,
7297
7333
  "type": "object",
7298
7334
  "in": "body"
@@ -7359,7 +7395,7 @@ var routes = {
7359
7395
  "call-tool": {
7360
7396
  serviceClass: "Tools",
7361
7397
  operationId: "callTool",
7362
- description: "Directly invokes a tool and returns its output. Supported for `http`, `builtin`, `mcp`, and `pipeline` tools. `client` tools cannot be invoked server-side and will return 422. A `pipeline` tool runs its declared steps in order and returns the mapped `output` (or the last step's output); `action` is ignored and `input` is the pipeline input. For `builtin` and `mcp` tools the `action` field is required and identifies which action (SOAT) or tool name (MCP) to invoke. For `http` tools `action` is ignored. When a `builtin` or `mcp` tool declares an `actions` allowlist, an action outside it is rejected with `400 VALIDATION_FAILED` (\"not available on this tool\") before any outbound request is made. `preset_parameters` stored on the tool are pinned over the caller-supplied `input` before execution: a key the tool presets keeps its preset value even when `input` sets it. Keys the presets do not name are taken from `input` as sent.",
7398
+ description: "Directly invokes a tool and returns its output. Supported for `http`, `builtin`, `mcp`, and `pipeline` tools. `client` tools cannot be invoked server-side and will return 422. A `pipeline` tool runs its declared steps in order and returns the mapped `output` (or the last step's output); `action` is ignored and `input` is the pipeline input. For `builtin` and `mcp` tools the `action` field is required and identifies which action (SOAT) or tool name (MCP) to invoke. For `http` tools `action` is ignored. When a `builtin` or `mcp` tool declares an `actions` allowlist, an action outside it is rejected with `400 VALIDATION_FAILED` (\"not available on this tool\") before any outbound request is made. `preset_parameters` stored on the tool are pinned over the caller-supplied `input` before execution: a key the tool presets keeps its preset value even when `input` sets it. Keys the presets do not name are taken from `input` as sent. Guardrails attached to the tool or to its project adjudicate the call before dispatch, composing project + tool scope. A call this route cannot await a decision on — class C (human sign-off), class D, or a class-B tripwire — is refused with `422 TOOL_DISPATCH_FAILED`, whose `meta` carries the `tool_id` and the `outcome`. A `pipeline` tool is adjudicated before its first step runs, and every step is adjudicated as the call of that tool it is.",
7363
7399
  moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/tools",
7364
7400
  httpMethod: "post",
7365
7401
  pathParams: ["tool_id"],
@@ -7613,7 +7649,7 @@ var routes = {
7613
7649
  "update-trigger": {
7614
7650
  serviceClass: "Triggers",
7615
7651
  operationId: "updateTrigger",
7616
- description: "Updates an existing trigger's configuration. The type is immutable.",
7652
+ description: "Updates an existing trigger's configuration. The type is immutable. Changing `target_type` or `target_id` re-checks the target-start action (`orchestrations:StartRun`, `agents:CreateAgentGeneration` or `tools:CallTool`) against the resulting target, because a firing runs with the trigger creator's authority rather than the updater's. A caller who could not start the new target is answered `403` and the trigger keeps the target it had.",
7617
7653
  moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/triggers",
7618
7654
  httpMethod: "patch",
7619
7655
  pathParams: ["trigger_id"],
@@ -7803,11 +7839,11 @@ var routes = {
7803
7839
  "list-usage-events": {
7804
7840
  serviceClass: "Usage",
7805
7841
  operationId: "listUsageEvents",
7806
- description: "Returns the raw usage events the caller can access, most recent first, optionally filtered by agent, generation, trace, actor, session, or `source`. Each event is the per-generation token usage as reported by the provider, for audit and reconciliation.",
7842
+ description: "Returns the raw usage events the caller can access, most recent first, narrowed by any combination of the same filters the aggregate takes — agent, generation, trace, actor, session, AI provider, orchestration run, orchestration, trigger, action, meter type, model or `source` — so a rollup and the events behind it are addressed the same way. Each event is the per-generation token usage as reported by the provider, for audit and reconciliation. An id naming nothing in scope yields an empty page rather than dropping the filter, so a mistyped narrowing can never widen the list past what was asked for.",
7807
7843
  moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/usage",
7808
7844
  httpMethod: "get",
7809
7845
  pathParams: [],
7810
- queryParams: ["agent_id", "generation_id", "trace_id", "actor_id", "session_id", "trigger_id", "action_id", "meter_type", "source", "limit", "offset"],
7846
+ queryParams: ["agent_id", "generation_id", "trace_id", "actor_id", "session_id", "ai_provider_id", "orchestration_run_id", "orchestration_id", "model", "trigger_id", "action_id", "meter_type", "source", "limit", "offset"],
7811
7847
  flags: [{
7812
7848
  "name": "agent_id",
7813
7849
  "description": "Filter by agent public ID",
@@ -7838,6 +7874,30 @@ var routes = {
7838
7874
  "required": false,
7839
7875
  "type": "string",
7840
7876
  "in": "query"
7877
+ }, {
7878
+ "name": "ai_provider_id",
7879
+ "description": "Filter by the provider record the spend was billed against. A provider that does not exist in scope yields an empty page.\n",
7880
+ "required": false,
7881
+ "type": "string",
7882
+ "in": "query"
7883
+ }, {
7884
+ "name": "orchestration_run_id",
7885
+ "description": "Filter by the orchestration run that metered the event. A run that does not exist in scope yields an empty page.\n",
7886
+ "required": false,
7887
+ "type": "string",
7888
+ "in": "query"
7889
+ }, {
7890
+ "name": "orchestration_id",
7891
+ "description": "Filter by orchestration — the events of the runs it started itself, not the subtree its `loop` or `sub_orchestration` nodes started. An orchestration that does not exist in scope yields an empty page.\n",
7892
+ "required": false,
7893
+ "type": "string",
7894
+ "in": "query"
7895
+ }, {
7896
+ "name": "model",
7897
+ "description": "Filter by the as-billed SKU the event recorded. Matched as recorded, so it still selects events whose provider has since been deleted.\n",
7898
+ "required": false,
7899
+ "type": "string",
7900
+ "in": "query"
7841
7901
  }, {
7842
7902
  "name": "trigger_id",
7843
7903
  "description": "Filter by the trigger that initiated the generation",
@@ -7879,11 +7939,11 @@ var routes = {
7879
7939
  "get-usage-aggregate": {
7880
7940
  serviceClass: "Usage",
7881
7941
  operationId: "getUsageAggregate",
7882
- description: "Returns a project's usage rolled up over an optional `[from, to]` time window, bucketed by a single dimension and optionally narrowed to one `meter_type`. Each group and the grand total carry an `event_count`, summed token counts, a measured `quantity` per component (so infra meters report their real amount, not zeros), and `cost_usd` (null when no event in the bucket was priced). This is the per-project cost-by-range/by-category query — a monthly figure without scanning raw usage events client-side. `groups` is paginated. Its `total` is the number of distinct buckets in the window — bucket cardinality, including a null bucket for the events the dimension does not apply to, and never a count of entities. To count entities, send `include=distinct` and read `totals.distinct`. `totals` always describes the whole window — never the page above it.",
7942
+ description: "Returns a project's usage rolled up over an optional `[from, to]` time window, optionally bucketed by a single dimension and narrowed by any combination of thirteen filters — session, actor, agent, AI provider, orchestration run, orchestration, generation, trace, meter type, model, source, trigger and action. That is how \"what did this conversation cost\", \"what has this end user cost\" and \"what did this agent cost\" are answered. Each group and the grand total carry an `event_count`, summed token counts, a measured `quantity` per component (so infra meters report their real amount, not zeros), and `cost_usd` (null when no event in the bucket was priced). This is the per-project cost-by-range/by-category query — a monthly figure without scanning raw usage events client-side. Narrowings intersect and apply to the whole rollup — every bucket, `totals` and `totals.distinct` alike — so each composes with any `group_by`, and all thirteen are echoed back under `filters`. The eight naming a resource are resolved against the project, and one naming nothing there empties the rollup rather than being dropped: a mistyped id must never read back as the project's whole spend. The other five are matched against the value the event recorded. `groups` is paginated. Its `total` is the number of distinct buckets in the window — bucket cardinality, including a null bucket for the events the dimension does not apply to, and never a count of entities. To count entities, send `include=distinct` and read `totals.distinct`. `totals` always describes the whole window — never the page above it, and never the bucketing: omit `group_by` and `totals` is unchanged while `groups` is empty.",
7883
7943
  moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/usage",
7884
7944
  httpMethod: "get",
7885
7945
  pathParams: [],
7886
- queryParams: ["project_id", "group_by", "include", "from", "to", "meter_type", "limit", "offset"],
7946
+ queryParams: ["project_id", "group_by", "include", "from", "to", "meter_type", "session_id", "actor_id", "agent_id", "ai_provider_id", "orchestration_run_id", "orchestration_id", "generation_id", "trace_id", "model", "source", "trigger_id", "action_id", "limit", "offset"],
7887
7947
  flags: [{
7888
7948
  "name": "project_id",
7889
7949
  "description": "Project public ID to aggregate usage for",
@@ -7892,8 +7952,8 @@ var routes = {
7892
7952
  "in": "query"
7893
7953
  }, {
7894
7954
  "name": "group_by",
7895
- "description": "Dimension to bucket by. `day` buckets on the event's UTC calendar day; the others bucket on the matching column. `ai_provider` buckets on the provider the spend was billed against — a routed generation's serving target, or the agent's pinned provider. `model` buckets on the model id *and* the provider that served it, so one model name served by two providers is two groups (see `ai_provider_id`). `source` buckets by what the spend was incurred for (`eval`, `eval_judge`), which is how verification spend is priced apart from the traffic serving real users; unlabelled traffic collapses into the single `null` bucket. `orchestration_run` buckets on the orchestration run the event belongs to — a standalone generation runs no orchestration and collapses into the single `null` bucket, so the bucket count under this dimension is not a count of runs.\n",
7896
- "required": true,
7955
+ "description": "Dimension to bucket by. Omit it to skip bucketing entirely: `totals` still describes the whole window and `groups` is an empty page, which is what \"what did this one thing cost\" wants. A value naming no dimension is a `400`. `day` buckets on the event's UTC calendar day; the others bucket on the matching column. `ai_provider` buckets on the provider the spend was billed against — a routed generation's serving target, or the agent's pinned provider. `model` buckets on the model id *and* the provider that served it, so one model name served by two providers is two groups (see `ai_provider_id`). `source` buckets by what the spend was incurred for (`eval`, `eval_judge`), which is how verification spend is priced apart from the traffic serving real users; unlabelled traffic collapses into the single `null` bucket. `orchestration_run` buckets on the orchestration run the event belongs to — a standalone generation runs no orchestration and collapses into the single `null` bucket, so the bucket count under this dimension is not a count of runs.\n",
7956
+ "required": false,
7897
7957
  "type": "string",
7898
7958
  "in": "query"
7899
7959
  }, {
@@ -7920,6 +7980,78 @@ var routes = {
7920
7980
  "required": false,
7921
7981
  "type": "string",
7922
7982
  "in": "query"
7983
+ }, {
7984
+ "name": "session_id",
7985
+ "description": "Narrow the whole rollup — every bucket, `totals` and `totals.distinct` alike — to one session's traffic. Combines with `group_by`: `group_by=day&session_id=…` is a conversation's spend per day, `group_by=model` is the same spend split by model. An id naming no session in this project yields an empty rollup, never the project total.\n",
7986
+ "required": false,
7987
+ "type": "string",
7988
+ "in": "query"
7989
+ }, {
7990
+ "name": "actor_id",
7991
+ "description": "The same narrowing, for one end user across every session they appear in. This is the figure behind a `scope: actor`, `metric: cost_usd` quota — what that actor has spent, against the cap it is held to.\n",
7992
+ "required": false,
7993
+ "type": "string",
7994
+ "in": "query"
7995
+ }, {
7996
+ "name": "agent_id",
7997
+ "description": "Narrow to one agent's traffic, across every session, run and trigger that dispatched it.\n",
7998
+ "required": false,
7999
+ "type": "string",
8000
+ "in": "query"
8001
+ }, {
8002
+ "name": "ai_provider_id",
8003
+ "description": "Narrow to the spend billed against one provider record — a routed generation's serving target, or the agent's pinned provider.\n",
8004
+ "required": false,
8005
+ "type": "string",
8006
+ "in": "query"
8007
+ }, {
8008
+ "name": "orchestration_run_id",
8009
+ "description": "Narrow to the events one orchestration run metered.",
8010
+ "required": false,
8011
+ "type": "string",
8012
+ "in": "query"
8013
+ }, {
8014
+ "name": "orchestration_id",
8015
+ "description": "Narrow to the runs of one orchestration — the runs it started itself, never the subtree a `loop` or `sub_orchestration` node started under it, which is metered against the child orchestration where it was incurred. Additive: summed across a project's orchestrations the figures reach the project total exactly once. For the subtree figure of a single invocation, read `usage` on the run.\n",
8016
+ "required": false,
8017
+ "type": "string",
8018
+ "in": "query"
8019
+ }, {
8020
+ "name": "generation_id",
8021
+ "description": "Narrow to one generation's events. A generation writes more than one when it meters several dimensions (tokens and compute).\n",
8022
+ "required": false,
8023
+ "type": "string",
8024
+ "in": "query"
8025
+ }, {
8026
+ "name": "trace_id",
8027
+ "description": "Narrow to the events recorded under one trace.",
8028
+ "required": false,
8029
+ "type": "string",
8030
+ "in": "query"
8031
+ }, {
8032
+ "name": "model",
8033
+ "description": "Narrow to one model, matched against the as-billed SKU the event recorded. A value naming no model yields an empty rollup, not an error. Under `group_by=model` this is a single-bucket rollup; under any other dimension it is that model's spend split by the dimension.\n",
8034
+ "required": false,
8035
+ "type": "string",
8036
+ "in": "query"
8037
+ }, {
8038
+ "name": "source",
8039
+ "description": "Narrow by what the spend was incurred for — `eval` and `eval_judge` are verification spend. Ordinary traffic carries no source, so it cannot be selected by this filter; omit the filter for everything.\n",
8040
+ "required": false,
8041
+ "type": "string",
8042
+ "in": "query"
8043
+ }, {
8044
+ "name": "trigger_id",
8045
+ "description": "Narrow to the spend one trigger initiated. Matched as recorded rather than resolved, so it still selects the spend of a trigger that has since been deleted.\n",
8046
+ "required": false,
8047
+ "type": "string",
8048
+ "in": "query"
8049
+ }, {
8050
+ "name": "action_id",
8051
+ "description": "Narrow to one caller-supplied action label, for per-action spend. Matched as recorded, like `trigger_id`.\n",
8052
+ "required": false,
8053
+ "type": "string",
8054
+ "in": "query"
7923
8055
  }, {
7924
8056
  "name": "limit",
7925
8057
  "description": "Maximum number of `groups` entries to return. Clamped to 100. Does not affect `totals` or `groups.total`, which describe the whole window.\n",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soat/cli",
3
- "version": "0.44.0",
3
+ "version": "0.46.0",
4
4
  "description": "CLI for SOAT — open-source infrastructure for production-ready AI agents.",
5
5
  "keywords": [
6
6
  "ai-agents",
@@ -22,7 +22,7 @@
22
22
  "dependencies": {
23
23
  "@inquirer/input": "^5.1.2",
24
24
  "@inquirer/password": "^5.1.1",
25
- "@soat/sdk": "0.44.0",
25
+ "@soat/sdk": "0.46.0",
26
26
  "@ttoss/logger": "^0.8.19",
27
27
  "commander": "^15.0.0",
28
28
  "js-yaml": "^5.2.1"