@soat/cli 0.36.0 → 0.37.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 +31 -25
  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.36.0";
16
+ var version = "0.37.0";
17
17
 
18
18
  //#endregion
19
19
  //#region src/cli-wrappers/wrappers/formations.ts
@@ -790,13 +790,13 @@ var routes = {
790
790
  "in": "body"
791
791
  }, {
792
792
  "name": "tool_choice",
793
- "description": "Tool choice strategy. Accepts a string (`\"auto\"`, `\"required\"`) or an object (`{ \"type\": \"tool\", \"tool_name\": \"my_tool\" }`). A forcing value (`\"required\"` or the object form) forbids a final assistant message on every step of every turn, including a resumed or continued one, so it requires a `hasToolCall` entry in `stop_conditions` — otherwise the write is refused with `FORCED_TOOL_CHOICE_CANNOT_STOP`.",
793
+ "description": "Tool choice strategy. Accepts a string (`\"auto\"`, `\"required\"`) or an object (`{ \"type\": \"tool\", \"tool_name\": \"my_tool\" }`). A forcing value (`\"required\"` or the object form) forbids a final assistant message on every step of every turn, including a resumed or continued one, so it requires a `has_tool_call` entry in `stop_conditions` — otherwise the write is refused with `FORCED_TOOL_CHOICE_CANNOT_STOP`.",
794
794
  "required": false,
795
795
  "type": "any",
796
796
  "in": "body"
797
797
  }, {
798
798
  "name": "stop_conditions",
799
- "description": "Conditions that end the agent's work early, on top of `max_steps`. Two scopes:\n\n`{\"type\": \"hasToolCall\", \"tool_name\": \"<resolved tool name>\"}` ends the **turn** after the step that calls the named tool. It narrows when the loop ends — it never lets it run past `max_steps`.\n\n`{\"type\": \"maxChainGenerations\", \"max_generations\": <n>}` bounds the **continuation chain** instead: once the chain has spawned that many generations, further resumptions stop with `chain_limit` rather than extending it. It never shortens a turn. The effective ceiling is the smaller of this and the deployment's `MAX_CONTINUATION_CHAIN_GENERATIONS`, so an agent can be stricter than the platform but never looser.\n\nAn unknown `type`, a `hasToolCall` without a `tool_name`, a `maxChainGenerations` whose `max_generations` is not a positive integer, or a non-object entry is rejected with 400.",
799
+ "description": "Conditions that end the agent's work early, on top of `max_steps`. Two scopes:\n\n`{\"type\": \"has_tool_call\", \"tool_name\": \"<resolved tool name>\"}` ends the **turn** after the step that calls the named tool. It narrows when the loop ends — it never lets it run past `max_steps`.\n\n`{\"type\": \"max_chain_generations\", \"max_generations\": <n>}` bounds the **continuation chain** instead: once the chain has spawned that many generations, further resumptions stop with `chain_limit` rather than extending it. It never shortens a turn. The effective ceiling is the smaller of this and the deployment's `MAX_CONTINUATION_CHAIN_GENERATIONS`, so an agent can be stricter than the platform but never looser.\n\nAn unknown `type`, a `has_tool_call` without a `tool_name`, a `max_chain_generations` whose `max_generations` is not a positive integer, or a non-object entry is rejected with 400.",
800
800
  "required": false,
801
801
  "type": "array",
802
802
  "in": "body"
@@ -948,13 +948,13 @@ var routes = {
948
948
  "in": "body"
949
949
  }, {
950
950
  "name": "tool_choice",
951
- "description": "Tool choice strategy. Accepts a string (`\"auto\"`, `\"required\"`) or an object (`{ \"type\": \"tool\", \"tool_name\": \"my_tool\" }`). A forcing value (`\"required\"` or the object form) forbids a final assistant message on every step of every turn, including a resumed or continued one, so it requires a `hasToolCall` entry in `stop_conditions` — otherwise the write is refused with `FORCED_TOOL_CHOICE_CANNOT_STOP`.",
951
+ "description": "Tool choice strategy. Accepts a string (`\"auto\"`, `\"required\"`) or an object (`{ \"type\": \"tool\", \"tool_name\": \"my_tool\" }`). A forcing value (`\"required\"` or the object form) forbids a final assistant message on every step of every turn, including a resumed or continued one, so it requires a `has_tool_call` entry in `stop_conditions` — otherwise the write is refused with `FORCED_TOOL_CHOICE_CANNOT_STOP`.",
952
952
  "required": false,
953
953
  "type": "any",
954
954
  "in": "body"
955
955
  }, {
956
956
  "name": "stop_conditions",
957
- "description": "Conditions that end the agent's work early, on top of `max_steps`. Two scopes:\n\n`{\"type\": \"hasToolCall\", \"tool_name\": \"<resolved tool name>\"}` ends the **turn** after the step that calls the named tool. It narrows when the loop ends — it never lets it run past `max_steps`.\n\n`{\"type\": \"maxChainGenerations\", \"max_generations\": <n>}` bounds the **continuation chain** instead: once the chain has spawned that many generations, further resumptions stop with `chain_limit` rather than extending it. It never shortens a turn. The effective ceiling is the smaller of this and the deployment's `MAX_CONTINUATION_CHAIN_GENERATIONS`, so an agent can be stricter than the platform but never looser.\n\nAn unknown `type`, a `hasToolCall` without a `tool_name`, a `maxChainGenerations` whose `max_generations` is not a positive integer, or a non-object entry is rejected with 400.",
957
+ "description": "Conditions that end the agent's work early, on top of `max_steps`. Two scopes:\n\n`{\"type\": \"has_tool_call\", \"tool_name\": \"<resolved tool name>\"}` ends the **turn** after the step that calls the named tool. It narrows when the loop ends — it never lets it run past `max_steps`.\n\n`{\"type\": \"max_chain_generations\", \"max_generations\": <n>}` bounds the **continuation chain** instead: once the chain has spawned that many generations, further resumptions stop with `chain_limit` rather than extending it. It never shortens a turn. The effective ceiling is the smaller of this and the deployment's `MAX_CONTINUATION_CHAIN_GENERATIONS`, so an agent can be stricter than the platform but never looser.\n\nAn unknown `type`, a `has_tool_call` without a `tool_name`, a `max_chain_generations` whose `max_generations` is not a positive integer, or a non-object entry is rejected with 400.",
958
958
  "required": false,
959
959
  "type": "array",
960
960
  "in": "body"
@@ -1090,13 +1090,13 @@ var routes = {
1090
1090
  "in": "body"
1091
1091
  }, {
1092
1092
  "name": "tool_choice",
1093
- "description": "Tool choice strategy. Accepts a string (`\"auto\"`, `\"required\"`) or an object (`{ \"type\": \"tool\", \"tool_name\": \"my_tool\" }`). A forcing value (`\"required\"` or the object form) forbids a final assistant message on every step of every turn, including a resumed or continued one, so it requires a `hasToolCall` entry in `stop_conditions` — otherwise the write is refused with `FORCED_TOOL_CHOICE_CANNOT_STOP`.",
1093
+ "description": "Tool choice strategy. Accepts a string (`\"auto\"`, `\"required\"`) or an object (`{ \"type\": \"tool\", \"tool_name\": \"my_tool\" }`). A forcing value (`\"required\"` or the object form) forbids a final assistant message on every step of every turn, including a resumed or continued one, so it requires a `has_tool_call` entry in `stop_conditions` — otherwise the write is refused with `FORCED_TOOL_CHOICE_CANNOT_STOP`.",
1094
1094
  "required": false,
1095
1095
  "type": "any",
1096
1096
  "in": "body"
1097
1097
  }, {
1098
1098
  "name": "stop_conditions",
1099
- "description": "Conditions that end the agent's work early, on top of `max_steps`. Two scopes:\n\n`{\"type\": \"hasToolCall\", \"tool_name\": \"<resolved tool name>\"}` ends the **turn** after the step that calls the named tool. It narrows when the loop ends — it never lets it run past `max_steps`.\n\n`{\"type\": \"maxChainGenerations\", \"max_generations\": <n>}` bounds the **continuation chain** instead: once the chain has spawned that many generations, further resumptions stop with `chain_limit` rather than extending it. It never shortens a turn. The effective ceiling is the smaller of this and the deployment's `MAX_CONTINUATION_CHAIN_GENERATIONS`, so an agent can be stricter than the platform but never looser.\n\nAn unknown `type`, a `hasToolCall` without a `tool_name`, a `maxChainGenerations` whose `max_generations` is not a positive integer, or a non-object entry is rejected with 400.",
1099
+ "description": "Conditions that end the agent's work early, on top of `max_steps`. Two scopes:\n\n`{\"type\": \"has_tool_call\", \"tool_name\": \"<resolved tool name>\"}` ends the **turn** after the step that calls the named tool. It narrows when the loop ends — it never lets it run past `max_steps`.\n\n`{\"type\": \"max_chain_generations\", \"max_generations\": <n>}` bounds the **continuation chain** instead: once the chain has spawned that many generations, further resumptions stop with `chain_limit` rather than extending it. It never shortens a turn. The effective ceiling is the smaller of this and the deployment's `MAX_CONTINUATION_CHAIN_GENERATIONS`, so an agent can be stricter than the platform but never looser.\n\nAn unknown `type`, a `has_tool_call` without a `tool_name`, a `max_chain_generations` whose `max_generations` is not a positive integer, or a non-object entry is rejected with 400.",
1100
1100
  "required": false,
1101
1101
  "type": "array",
1102
1102
  "in": "body"
@@ -1673,7 +1673,7 @@ var routes = {
1673
1673
  "update-ai-provider-prices": {
1674
1674
  serviceClass: "AIProviders",
1675
1675
  operationId: "updateAiProviderPrices",
1676
- description: "Upserts price overrides for this AI provider instance, keyed on (model, effective_from). The provider slug is taken from the AI provider itself, so only the model, rates, and effective_from are supplied. Authorized by the caller's access to the provider's project. `effective_from` must be in the future — past prices are immutable, so ship corrections as new future-dated rows.",
1676
+ description: "Upserts price overrides for this AI provider instance, keyed on (model, effective_from). The provider slug is taken from the AI provider itself, so only the model, rates, and effective_from are supplied. Authorized by the caller's access to the provider's project. `effective_from` must be in the future once the (model, component) has a price row — past prices are immutable, so corrections ship as new future-dated rows. A first price for a (model, component) nothing prices yet may be dated now or earlier, so a new provider is never live and unpriced.",
1677
1677
  moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/ai-providers",
1678
1678
  httpMethod: "put",
1679
1679
  pathParams: ["ai_provider_id"],
@@ -3500,7 +3500,7 @@ var routes = {
3500
3500
  "in": "body"
3501
3501
  }, {
3502
3502
  "name": "tool_context",
3503
- "description": "Key/value context forwarded to every item's generation, so an agent whose tools authorize through `tool_context` is scored against the configuration it runs in production rather than with an empty bag. Each key is forwarded as one `X-Soat-Context-<key>` header and resolves any `{{context:<key>}}` token in a bound tool's headers or `preset_parameters`.\n\nStored on the run and re-read per item, since a queued run (the default) is driven by a worker with no request behind it. **Write-only**: no read of the run returns it, unlike `metadata` — a run is a report other people read, and a credential in it is not theirs to see. Cleared once the run reaches a terminal state.\n\nAn eval generation has no session, so the reserved keys `sessionId`, `actorId` and `actorExternalId` are dropped (in any casing) rather than forwarded. Every other key becomes an HTTP header name and must match that grammar, or the request is rejected with `400 INVALID_TOOL_CONTEXT_KEY` and no run is created.",
3503
+ "description": "Key/value context forwarded to every item's generation, so an agent whose tools authorize through `tool_context` is scored against the configuration it runs in production rather than with an empty bag. Each key is forwarded as one `X-Soat-Context-<key>` header and resolves any `{{context:<key>}}` token in a bound tool's headers or `preset_parameters`.\n\nStored on the run and re-read per item, since a queued run (the default) is driven by a worker with no request behind it. **Write-only**: no read of the run returns it, unlike `metadata` — a run is a report other people read, and a credential in it is not theirs to see. Cleared once the run reaches a terminal state.\n\nAn eval generation has no session, so the reserved keys `session_id`, `actor_id` and `actor_external_id` are dropped (in any casing) rather than forwarded. Every other key becomes an HTTP header name and must match that grammar, or the request is rejected with `400 INVALID_TOOL_CONTEXT_KEY` and no run is created.",
3504
3504
  "required": false,
3505
3505
  "type": "object",
3506
3506
  "in": "body"
@@ -4177,7 +4177,7 @@ var routes = {
4177
4177
  "update-formation": {
4178
4178
  serviceClass: "Formations",
4179
4179
  operationId: "updateFormation",
4180
- description: "Applies a new template to the formation. Resources are created, updated, or deleted to reconcile the current state with the desired state. A **template-shape** error is refused with `400`. A **deploy** failure is not: the operation ran, so the formation is returned with `200` and `status: \"failed\"`, and `error` explains why. Read `status` — a `2xx` here means the deploy was attempted, not that it worked. The `builtin` CLI exits non-zero on that body so `update-formation && …` does not lie.",
4180
+ description: "Applies a new template to the formation. Resources are created, updated, or deleted to reconcile the current state with the desired state. A **template-shape** error is refused with `400`. A **deploy** failure is not: the operation ran, so the formation is returned with `200` and `status: \"failed\"`, and `error` explains why. Read `status` — a `2xx` here means the deploy was attempted, not that it worked. The `builtin` CLI exits non-zero on that body so `update-formation && …` does not lie. A deploy that replaced a resource and could not delete the superseded one answers `status: \"active\"` with `error.code: \"FORMATION_REPLACE_CLEANUP_FAILED\"` — the desired state is realised, and `error.meta.failures` names every resource still live. The next deploy retries the disposal.",
4181
4181
  moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/formations",
4182
4182
  httpMethod: "put",
4183
4183
  pathParams: ["formation_id"],
@@ -5082,7 +5082,7 @@ var routes = {
5082
5082
  serviceClass: "MemoryEntries",
5083
5083
  operationId: "listMemoryEntries",
5084
5084
  description: "Returns all entries in a memory container",
5085
- moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/memoryEntries",
5085
+ moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/memory-entries",
5086
5086
  httpMethod: "get",
5087
5087
  pathParams: [],
5088
5088
  queryParams: ["memory_id", "limit", "offset", "include_invalidated"],
@@ -5116,7 +5116,7 @@ var routes = {
5116
5116
  serviceClass: "MemoryEntries",
5117
5117
  operationId: "createMemoryEntry",
5118
5118
  description: "Creates a new entry in the specified memory container. Automatically generates an embedding for semantic search, and skips the write when an existing entry is a near-duplicate (see `duplicate_threshold`). A merely similar fact is stored as its own entry: this path has no agent context and therefore no model to consolidate two facts into one.",
5119
- moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/memoryEntries",
5119
+ moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/memory-entries",
5120
5120
  httpMethod: "post",
5121
5121
  pathParams: [],
5122
5122
  queryParams: [],
@@ -5162,7 +5162,7 @@ var routes = {
5162
5162
  serviceClass: "MemoryEntries",
5163
5163
  operationId: "getMemoryEntry",
5164
5164
  description: "Returns a single memory entry by ID",
5165
- moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/memoryEntries",
5165
+ moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/memory-entries",
5166
5166
  httpMethod: "get",
5167
5167
  pathParams: ["entry_id"],
5168
5168
  queryParams: [],
@@ -5178,7 +5178,7 @@ var routes = {
5178
5178
  serviceClass: "MemoryEntries",
5179
5179
  operationId: "updateMemoryEntry",
5180
5180
  description: "Updates an existing memory entry. Regenerates the embedding if content changes.",
5181
- moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/memoryEntries",
5181
+ moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/memory-entries",
5182
5182
  httpMethod: "put",
5183
5183
  pathParams: ["entry_id"],
5184
5184
  queryParams: [],
@@ -5212,7 +5212,7 @@ var routes = {
5212
5212
  serviceClass: "MemoryEntries",
5213
5213
  operationId: "deleteMemoryEntry",
5214
5214
  description: "Deletes a memory entry",
5215
- moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/memoryEntries",
5215
+ moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/memory-entries",
5216
5216
  httpMethod: "delete",
5217
5217
  pathParams: ["entry_id"],
5218
5218
  queryParams: [],
@@ -5730,7 +5730,7 @@ var routes = {
5730
5730
  "in": "body"
5731
5731
  }, {
5732
5732
  "name": "tool_context",
5733
- "description": "Key-value pairs forwarded as `X-Soat-Context-<key>` headers on every `http`, `mcp` and `builtin` tool call made by an agent node of this run — including the agents of any child run a `loop` or `sub_orchestration` node starts. The header name is `X-Soat-Context-` plus the key verbatim; no character is re-cased.\n\nThe bag is stored on the run and re-read on every step, so it survives an `awaiting_input` pause, a `sleeping` wait, a background worker drive and a crash redrive. A key that is not a valid HTTP header name, or two keys that map to the same header, are rejected with `400 INVALID_TOOL_CONTEXT_KEY` and no run is created.\n\nThe reserved identity keys (`sessionId`, `actorId`, `actorExternalId`) are stripped at generation time — a caller cannot address them from here.",
5733
+ "description": "Key-value pairs forwarded as `X-Soat-Context-<key>` headers on every `http`, `mcp` and `builtin` tool call made by an agent node of this run — including the agents of any child run a `loop` or `sub_orchestration` node starts. The header name is `X-Soat-Context-` plus the key verbatim; no character is re-cased.\n\nThe bag is stored on the run and re-read on every step, so it survives an `awaiting_input` pause, a `sleeping` wait, a background worker drive and a crash redrive. A key that is not a valid HTTP header name, or two keys that map to the same header, are rejected with `400 INVALID_TOOL_CONTEXT_KEY` and no run is created.\n\nThe reserved identity keys (`session_id`, `actor_id`, `actor_external_id`) are stripped at generation time — a caller cannot address them from here.",
5734
5734
  "required": false,
5735
5735
  "type": "object",
5736
5736
  "in": "body"
@@ -6003,7 +6003,7 @@ var routes = {
6003
6003
  "update-project": {
6004
6004
  serviceClass: "Projects",
6005
6005
  operationId: "updateProject",
6006
- description: "Updates a project's name, its attached guardrails (`guardrail_ids` — the project-scope baseline governing every tool call by every agent in the project), its orchestration concurrency limit (`max_concurrent_runs`), its continuation-chain ceiling (`max_chain_generations`), its inherited model route (`default_model_route_id`), its read-auditing opt-in (`audit_reads_enabled`), its trace-content retention window (`trace_content_retention_days`), and/or its zero-retention setting (`trace_content_mode`). At least one field is required. Requires admin role. Detaching a guardrail (removing an id) additionally requires guardrails:DetachGuardrail.",
6006
+ description: "Updates a project's name, its attached guardrails (`guardrail_ids` — the project-scope baseline governing every tool call by every agent in the project), its orchestration concurrency limit (`max_concurrent_runs`), its continuation-chain ceiling (`max_chain_generations`), its orchestration nesting bound (`max_run_depth`), its inherited model route (`default_model_route_id`), its read-auditing opt-in (`audit_reads_enabled`), its trace-content retention window (`trace_content_retention_days`), and/or its zero-retention setting (`trace_content_mode`). At least one field is required. Requires admin role. Detaching a guardrail (removing an id) additionally requires guardrails:DetachGuardrail.",
6007
6007
  moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/projects",
6008
6008
  httpMethod: "patch",
6009
6009
  pathParams: ["project_id"],
@@ -6034,7 +6034,13 @@ var routes = {
6034
6034
  "in": "body"
6035
6035
  }, {
6036
6036
  "name": "max_chain_generations",
6037
- "description": "Generations one continuation chain in this project may hold before the platform stops resuming it. `null` clears the project's ceiling, leaving the deployment-wide `MAX_CONTINUATION_CHAIN_GENERATIONS`; otherwise an integer >= 1. The effective budget is the smallest of the deployment's ceiling, this one, and the agent's own `maxChainGenerations` stop condition, so an agent author can be stricter than this number but never exceed it.",
6037
+ "description": "Generations one continuation chain in this project may hold before the platform stops resuming it. `null` clears the project's ceiling, leaving the deployment-wide `MAX_CONTINUATION_CHAIN_GENERATIONS`; otherwise an integer >= 1. The effective budget is the smallest of the deployment's ceiling, this one, and the agent's own `max_chain_generations` stop condition, so an agent author can be stricter than this number but never exceed it.",
6038
+ "required": false,
6039
+ "type": "integer",
6040
+ "in": "body"
6041
+ }, {
6042
+ "name": "max_run_depth",
6043
+ "description": "`loop` / `sub_orchestration` nesting levels a run tree in this project may reach before the engine refuses to start the next child. `null` clears the project's bound, leaving the deployment-wide `MAX_ORCHESTRATION_RUN_DEPTH` (default 10); otherwise an integer >= 1. The effective bound is the smaller of the two, so this can only be stricter than the deployment's — which is what makes it a bound a graph author cannot opt out of. A refused child fails its parent run with `ORCHESTRATION_RUN_DEPTH_LIMIT`.",
6038
6044
  "required": false,
6039
6045
  "type": "integer",
6040
6046
  "in": "body"
@@ -6105,7 +6111,7 @@ var routes = {
6105
6111
  "update-project-prices": {
6106
6112
  serviceClass: "Projects",
6107
6113
  operationId: "updateProjectPrices",
6108
- description: "Upserts project + provider-slug price rows, keyed on (provider, model, effective_from). A row covers all of the project's instances of that provider slug. Authorized by the caller's access to the project. `effective_from` must be in the future — past prices are immutable, so ship corrections as new future-dated rows.",
6114
+ description: "Upserts project + provider-slug price rows, keyed on (provider, model, effective_from). A row covers all of the project's instances of that provider slug. Authorized by the caller's access to the project. `effective_from` must be in the future once the (provider, model, component) is priced — past prices are immutable, so corrections ship as new future-dated rows. A first price, with no row for the project or the global default, may be dated now or earlier.",
6109
6115
  moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/projects",
6110
6116
  httpMethod: "put",
6111
6117
  pathParams: ["project_id"],
@@ -6890,7 +6896,7 @@ var routes = {
6890
6896
  "in": "body"
6891
6897
  }, {
6892
6898
  "name": "tool_context",
6893
- "description": "Key-value pairs forwarded as `X-Soat-Context-<key>` headers on every `http`, `mcp` and `builtin` tool call made by this task's automation dispatches — the agent generations a state's `on_enter` starts, and the agent nodes of any orchestration run it starts. The header name is `X-Soat-Context-` plus the key verbatim; no character is re-cased.\nCreation is the task's first move, so this is the bag the entry state's `on_enter` runs with. Each transition may replace it (see `TransitionTaskRequest.tool_context`).\nThe reserved identity keys (`sessionId`, `actorId`, `actorExternalId`) are stripped in any casing and re-derived server-side, so a task-dispatched generation cannot forge them. A key outside the HTTP header-name grammar is rejected with `INVALID_TOOL_CONTEXT_KEY` (400).\nWrite-only: the stored bag is never returned by any task read, and it is cleared when the task reaches a terminal state.",
6899
+ "description": "Key-value pairs forwarded as `X-Soat-Context-<key>` headers on every `http`, `mcp` and `builtin` tool call made by this task's automation dispatches — the agent generations a state's `on_enter` starts, and the agent nodes of any orchestration run it starts. The header name is `X-Soat-Context-` plus the key verbatim; no character is re-cased.\nCreation is the task's first move, so this is the bag the entry state's `on_enter` runs with. Each transition may replace it (see `TransitionTaskRequest.tool_context`).\nThe reserved identity keys (`session_id`, `actor_id`, `actor_external_id`) are stripped in any casing and re-derived server-side, so a task-dispatched generation cannot forge them. A key outside the HTTP header-name grammar is rejected with `INVALID_TOOL_CONTEXT_KEY` (400).\nWrite-only: the stored bag is never returned by any task read, and it is cleared when the task reaches a terminal state.",
6894
6900
  "required": false,
6895
6901
  "type": "object",
6896
6902
  "in": "body"
@@ -6996,7 +7002,7 @@ var routes = {
6996
7002
  "in": "body"
6997
7003
  }, {
6998
7004
  "name": "tool_context",
6999
- "description": "Caller context for the automation dispatches the task makes from here on, forwarded as `X-Soat-Context-<key>` headers on their tool calls.\nSupplying it **replaces** the task's stored bag wholesale; omitting it keeps the current one, so the context follows whoever last moved the task and survives every move that does not speak about it — including an approval gate, a retry, and an automation hop. Send an empty object to clear it without closing the task.\nThe reserved identity keys (`sessionId`, `actorId`, `actorExternalId`) are stripped in any casing and re-derived server-side. A key outside the HTTP header-name grammar is rejected with `INVALID_TOOL_CONTEXT_KEY` (400).\nWrite-only: never returned by a task read, and cleared when the transition closes the task.",
7005
+ "description": "Caller context for the automation dispatches the task makes from here on, forwarded as `X-Soat-Context-<key>` headers on their tool calls.\nSupplying it **replaces** the task's stored bag wholesale; omitting it keeps the current one, so the context follows whoever last moved the task and survives every move that does not speak about it — including an approval gate, a retry, and an automation hop. Send an empty object to clear it without closing the task.\nThe reserved identity keys (`session_id`, `actor_id`, `actor_external_id`) are stripped in any casing and re-derived server-side. A key outside the HTTP header-name grammar is rejected with `INVALID_TOOL_CONTEXT_KEY` (400).\nWrite-only: never returned by a task read, and cleared when the transition closes the task.",
7000
7006
  "required": false,
7001
7007
  "type": "object",
7002
7008
  "in": "body"
@@ -7110,7 +7116,7 @@ var routes = {
7110
7116
  "in": "body"
7111
7117
  }, {
7112
7118
  "name": "context_keys",
7113
- "description": "Optional allowlist of `tool_context` keys that may be forwarded to this tool as prefixed context headers (`X-Soat-Context-<key>` by default). When `null` or omitted, every key in the caller's `tool_context` is forwarded — the behavior of every tool created before this field existed. When set, only the listed keys are, so a per-user credential in `tool_context` can be confined to the tools that need it; `[]` forwards none. The server-pinned identity keys (`sessionId`, `actorId`, `actorExternalId`) are always forwarded. A key consumed by a `{{context:<key>}}` token in this tool's own headers is substituted regardless of this list — the tool declared that header itself.",
7119
+ "description": "Optional allowlist of `tool_context` keys that may be forwarded to this tool as prefixed context headers (`X-Soat-Context-<key>` by default). When `null` or omitted, every key in the caller's `tool_context` is forwarded — the behavior of every tool created before this field existed. When set, only the listed keys are, so a per-user credential in `tool_context` can be confined to the tools that need it; `[]` forwards none. The server-pinned identity keys (`session_id`, `actor_id`, `actor_external_id`) are always forwarded. A key consumed by a `{{context:<key>}}` token in this tool's own headers is substituted regardless of this list — the tool declared that header itself.",
7114
7120
  "required": false,
7115
7121
  "type": "array",
7116
7122
  "in": "body"
@@ -7220,7 +7226,7 @@ var routes = {
7220
7226
  "in": "body"
7221
7227
  }, {
7222
7228
  "name": "context_keys",
7223
- "description": "Optional allowlist of `tool_context` keys that may be forwarded to this tool as prefixed context headers (`X-Soat-Context-<key>` by default). When `null` or omitted, every key in the caller's `tool_context` is forwarded — the behavior of every tool created before this field existed. When set, only the listed keys are, so a per-user credential in `tool_context` can be confined to the tools that need it; `[]` forwards none. The server-pinned identity keys (`sessionId`, `actorId`, `actorExternalId`) are always forwarded. A key consumed by a `{{context:<key>}}` token in this tool's own headers is substituted regardless of this list — the tool declared that header itself.",
7229
+ "description": "Optional allowlist of `tool_context` keys that may be forwarded to this tool as prefixed context headers (`X-Soat-Context-<key>` by default). When `null` or omitted, every key in the caller's `tool_context` is forwarded — the behavior of every tool created before this field existed. When set, only the listed keys are, so a per-user credential in `tool_context` can be confined to the tools that need it; `[]` forwards none. The server-pinned identity keys (`session_id`, `actor_id`, `actor_external_id`) are always forwarded. A key consumed by a `{{context:<key>}}` token in this tool's own headers is substituted regardless of this list — the tool declared that header itself.",
7224
7230
  "required": false,
7225
7231
  "type": "array",
7226
7232
  "in": "body"
@@ -7294,7 +7300,7 @@ var routes = {
7294
7300
  "in": "body"
7295
7301
  }, {
7296
7302
  "name": "tool_context",
7297
- "description": "Key/value context for this call, forwarded to the tool as `X-Soat-Context-<key>` request headers and resolving any `{{context:<key>}}` token in the tool's `execute.headers`, `mcp.headers` or `preset_parameters`. Narrowed by the tool's `context_keys` allowlist when it sets one.\nThis route has no session, so it stamps no server-derived identity: the reserved keys `sessionId`, `actorId` and `actorExternalId` are dropped from this bag (in any casing) rather than forwarded, so a downstream tool can still trust that a context header naming one is server-derived. Every other key becomes an HTTP header name and must match that grammar, or the call fails with `INVALID_TOOL_CONTEXT_KEY`.\n",
7303
+ "description": "Key/value context for this call, forwarded to the tool as `X-Soat-Context-<key>` request headers and resolving any `{{context:<key>}}` token in the tool's `execute.headers`, `mcp.headers` or `preset_parameters`. Narrowed by the tool's `context_keys` allowlist when it sets one.\nThis route has no session, so it stamps no server-derived identity: the reserved keys `session_id`, `actor_id` and `actor_external_id` are dropped from this bag (in any casing) rather than forwarded, so a downstream tool can still trust that a context header naming one is server-derived. Every other key becomes an HTTP header name and must match that grammar, or the call fails with `INVALID_TOOL_CONTEXT_KEY`.\n",
7298
7304
  "required": false,
7299
7305
  "type": "object",
7300
7306
  "in": "body"
@@ -7939,7 +7945,7 @@ var routes = {
7939
7945
  "upsert-price-book": {
7940
7946
  serviceClass: "Usage",
7941
7947
  operationId: "upsertPriceBook",
7942
- description: "Upserts price rows keyed on (provider, model, effective_from). Admin only. `effective_from` must be in the future — past prices are immutable so recorded costs stay explainable; ship corrections as new future-dated rows.",
7948
+ description: "Upserts price rows keyed on (provider, model, effective_from). Admin only. `effective_from` must be in the future once the (provider, model, component) is priced — past prices are immutable so recorded costs stay explainable; ship corrections as new future-dated rows. A first price, with no row in this scope or any broader one, may be dated now or earlier.",
7943
7949
  moduleDocsUrl: "https://soat.ttoss.dev/docs/modules/usage",
7944
7950
  httpMethod: "put",
7945
7951
  pathParams: [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soat/cli",
3
- "version": "0.36.0",
3
+ "version": "0.37.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.36.0",
25
+ "@soat/sdk": "0.37.0",
26
26
  "@ttoss/logger": "^0.8.19",
27
27
  "commander": "^15.0.0",
28
28
  "js-yaml": "^5.2.1"