@naturali/sdk 0.90.0 → 0.91.1

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.
package/dist/index.cjs CHANGED
@@ -1385,7 +1385,7 @@ var AiProviders = class {
1385
1385
  /**
1386
1386
  * Upsert per-provider price overrides
1387
1387
  *
1388
- * 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.
1388
+ * 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.
1389
1389
  *
1390
1390
  */
1391
1391
  static updateAiProviderPrices(options) {
@@ -2663,6 +2663,8 @@ var Formations = class {
2663
2663
  *
2664
2664
  * 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 `naturali` CLI exits non-zero on that body so `update-formation && …` does not lie.
2665
2665
  *
2666
+ * 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.
2667
+ *
2666
2668
  */
2667
2669
  static updateFormation(options) {
2668
2670
  return (options.client ?? client).put({
package/dist/index.d.cts CHANGED
@@ -600,11 +600,11 @@ type Agent = {
600
600
  */
601
601
  max_steps?: number | null;
602
602
  /**
603
- * 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`.
603
+ * 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`.
604
604
  */
605
605
  tool_choice?: unknown;
606
606
  /**
607
- * Conditions that end the agent's work early, on top of `max_steps` — turn-scoped (`hasToolCall`) or chain-scoped (`maxChainGenerations`). See the create request body for the accepted shapes.
607
+ * Conditions that end the agent's work early, on top of `max_steps` — turn-scoped (`has_tool_call`) or chain-scoped (`max_chain_generations`). See the create request body for the accepted shapes.
608
608
  */
609
609
  stop_conditions?: Array<{
610
610
  [key: string]: unknown;
@@ -816,17 +816,17 @@ type CreateAgentRequest = {
816
816
  tool_bindings?: Array<ToolBinding>;
817
817
  max_steps?: number;
818
818
  /**
819
- * 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`.
819
+ * 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`.
820
820
  */
821
821
  tool_choice?: unknown;
822
822
  /**
823
823
  * Conditions that end the agent's work early, on top of `max_steps`. Two scopes:
824
824
  *
825
- * `{"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`.
825
+ * `{"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`.
826
826
  *
827
- * `{"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.
827
+ * `{"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.
828
828
  *
829
- * An 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.
829
+ * An 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.
830
830
  */
831
831
  stop_conditions?: Array<{
832
832
  [key: string]: unknown;
@@ -921,17 +921,17 @@ type UpdateAgentRequest = {
921
921
  tool_bindings?: Array<ToolBinding> | null;
922
922
  max_steps?: number | null;
923
923
  /**
924
- * 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`.
924
+ * 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`.
925
925
  */
926
926
  tool_choice?: unknown;
927
927
  /**
928
928
  * Conditions that end the agent's work early, on top of `max_steps`. Two scopes:
929
929
  *
930
- * `{"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`.
930
+ * `{"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`.
931
931
  *
932
- * `{"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.
932
+ * `{"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.
933
933
  *
934
- * An 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.
934
+ * An 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.
935
935
  */
936
936
  stop_conditions?: Array<{
937
937
  [key: string]: unknown;
@@ -1250,7 +1250,7 @@ type CreateToolRequest = {
1250
1250
  */
1251
1251
  denied_actions?: Array<string>;
1252
1252
  /**
1253
- * Optional allowlist of `tool_context` keys that may be forwarded to this tool as prefixed context headers (`X-Naturali-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.
1253
+ * Optional allowlist of `tool_context` keys that may be forwarded to this tool as prefixed context headers (`X-Naturali-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.
1254
1254
  */
1255
1255
  context_keys?: Array<string> | null;
1256
1256
  /**
@@ -2800,19 +2800,19 @@ type AgentResourceProperties = {
2800
2800
  */
2801
2801
  tool_choice?: unknown;
2802
2802
  /**
2803
- * Conditions that stop the agent's work early — turn-scoped (`hasToolCall`) or chain-scoped (`maxChainGenerations`).
2803
+ * Conditions that stop the agent's work early — turn-scoped (`has_tool_call`) or chain-scoped (`max_chain_generations`).
2804
2804
  */
2805
2805
  stop_conditions?: Array<{
2806
2806
  /**
2807
- * Condition type — `hasToolCall` or `maxChainGenerations`
2807
+ * Condition type — `has_tool_call` or `max_chain_generations`
2808
2808
  */
2809
2809
  type?: string;
2810
2810
  /**
2811
- * Tool name to match when type is `hasToolCall`
2811
+ * Tool name to match when type is `has_tool_call`
2812
2812
  */
2813
2813
  tool_name?: string | null;
2814
2814
  /**
2815
- * Generations the continuation chain may reach when type is `maxChainGenerations`
2815
+ * Generations the continuation chain may reach when type is `max_chain_generations`
2816
2816
  */
2817
2817
  max_generations?: number | null;
2818
2818
  }> | null;
@@ -3077,7 +3077,7 @@ type ToolResourceProperties = {
3077
3077
  */
3078
3078
  denied_actions?: Array<string> | null;
3079
3079
  /**
3080
- * Optional allowlist of `tool_context` keys forwarded to this tool as prefixed context headers. `null` or omitted forwards every key; `[]` forwards none. The server-pinned identity keys (`sessionId`, `actorId`, `actorExternalId`) are always forwarded, and a key consumed by a `{{context:<key>}}` token in this tool's own headers is substituted regardless of this list.
3080
+ * Optional allowlist of `tool_context` keys forwarded to this tool as prefixed context headers. `null` or omitted forwards every key; `[]` forwards none. The server-pinned identity keys (`session_id`, `actor_id`, `actor_external_id`) are always forwarded, and a key consumed by a `{{context:<key>}}` token in this tool's own headers is substituted regardless of this list.
3081
3081
  */
3082
3082
  context_keys?: Array<string> | null;
3083
3083
  /**
@@ -3714,6 +3714,8 @@ type Formation = {
3714
3714
  /**
3715
3715
  * Why the formation is `failed` or `delete_failed`, in the same `{ code, message, meta }` shape as an error response. Null in every other status, and cleared by the next successful deploy. This is the reason a `2xx` deploy response can report `status: "failed"` without a second call to `list-formation-events`.
3716
3716
  *
3717
+ * One case carries an error while the formation is `active`: `FORMATION_REPLACE_CLEANUP_FAILED`, when a deploy replaced a resource and the superseded one could not be deleted. The desired state is realised, so the deploy succeeded — but the old resource is still live, and `meta.failures` names it. It stays on the formation as pending cleanup and is retried on the next deploy or teardown, which clears the error once it is gone.
3718
+ *
3717
3719
  */
3718
3720
  error?: FormationError | null;
3719
3721
  /**
@@ -3784,7 +3786,7 @@ type UnauthorizedFormationAction = {
3784
3786
  */
3785
3787
  type FormationError = {
3786
3788
  /**
3787
- * The failing operation's error code (`VALIDATION_FAILED`, `RESOURCE_NOT_FOUND`, `FORMATION_DELETE_FAILED`, …), or `UNKNOWN` when the underlying failure carried no code.
3789
+ * The failing operation's error code (`VALIDATION_FAILED`, `RESOURCE_NOT_FOUND`, `FORMATION_DELETE_FAILED`, `FORMATION_REPLACE_CLEANUP_FAILED`, …), or `UNKNOWN` when the underlying failure carried no code.
3788
3790
  */
3789
3791
  code: string;
3790
3792
  /**
@@ -3792,7 +3794,7 @@ type FormationError = {
3792
3794
  */
3793
3795
  message: string;
3794
3796
  /**
3795
- * Context for the failure. A failed apply names the resource that broke it (`logical_id`, `resource_type`); a failed teardown lists every blocker under `failures`.
3797
+ * Context for the failure. A failed apply names the resource that broke it (`logical_id`, `resource_type`); a failed teardown lists every blocker under `failures`, and so does a succeeded deploy that could not dispose of a replaced resource — there each entry adds the `physical_resource_id` still live.
3796
3798
  */
3797
3799
  meta?: {
3798
3800
  [key: string]: unknown;
@@ -4750,7 +4752,7 @@ type OrchestrationNode = {
4750
4752
  */
4751
4753
  parallelism?: number;
4752
4754
  /**
4753
- * For loop and sub_orchestration nodes — allowlist of the run's `tool_context` keys the child run inherits. When `null` (the default), the child inherits the parent's whole bag — the behavior of every graph authored before this field existed. When set, only the listed keys are handed down, so a run holding a broad credential can delegate one step to a shared sub-graph without passing on what that sub-graph does not need; `[]` hands down nothing. Matching is case-insensitive, since an entry names a key that becomes an HTTP header name; an entry outside that grammar is rejected at write time with `INVALID_TOOL_CONTEXT_KEY`. The server-derived identity keys (`sessionId`, `actorId`, `actorExternalId`) are unaffected — they are re-derived per generation in the child regardless of this list. Ignored for other node types.
4755
+ * For loop and sub_orchestration nodes — allowlist of the run's `tool_context` keys the child run inherits. When `null` (the default), the child inherits the parent's whole bag — the behavior of every graph authored before this field existed. When set, only the listed keys are handed down, so a run holding a broad credential can delegate one step to a shared sub-graph without passing on what that sub-graph does not need; `[]` hands down nothing. Matching is case-insensitive, since an entry names a key that becomes an HTTP header name; an entry outside that grammar is rejected at write time with `INVALID_TOOL_CONTEXT_KEY`. The server-derived identity keys (`session_id`, `actor_id`, `actor_external_id`) are unaffected — they are re-derived per generation in the child regardless of this list. Ignored for other node types.
4754
4756
  */
4755
4757
  context_keys?: Array<string> | null;
4756
4758
  /**
@@ -5036,6 +5038,10 @@ type OrchestrationRun = {
5036
5038
  * The node within `parent_orchestration_run_id` that started this run. Null when `parent_orchestration_run_id` is null.
5037
5039
  */
5038
5040
  parent_node_id?: string | null;
5041
+ /**
5042
+ * `loop` / `sub_orchestration` edges between this run and the run a caller started: `0` for a caller-started run, one more than its parent's for a child. Starting a child past the effective bound — the smaller of the deployment's `MAX_ORCHESTRATION_RUN_DEPTH` (default 10) and the project's `max_run_depth` — is refused with `ORCHESTRATION_RUN_DEPTH_LIMIT`, which fails the run that tried to descend. That bounds a graph whose `sub_orchestration` node names itself, directly or through a cycle of two graphs, which the intra-graph cycle check cannot see.
5043
+ */
5044
+ run_depth?: number;
5039
5045
  /**
5040
5046
  * Terminal node artifact(s) when the run has succeeded.
5041
5047
  */
@@ -5177,7 +5183,7 @@ type StartRunRequest = {
5177
5183
  *
5178
5184
  * The 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.
5179
5185
  *
5180
- * The reserved identity keys (`sessionId`, `actorId`, `actorExternalId`) are stripped at generation time — a caller cannot address them from here.
5186
+ * The reserved identity keys (`session_id`, `actor_id`, `actor_external_id`) are stripped at generation time — a caller cannot address them from here.
5181
5187
  */
5182
5188
  tool_context?: {
5183
5189
  [key: string]: string;
@@ -5773,7 +5779,7 @@ type CreateTaskRequest = {
5773
5779
  /**
5774
5780
  * Key-value pairs forwarded as `X-Naturali-Context-<key>` headers on every `http` and `mcp` 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-Naturali-Context-` plus the key verbatim; no character is re-cased.
5775
5781
  * Creation 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`).
5776
- * The 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).
5782
+ * The 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).
5777
5783
  * Write-only: the stored bag is never returned by any task read, and it is cleared when the task reaches a terminal state.
5778
5784
  */
5779
5785
  tool_context?: {
@@ -5806,7 +5812,7 @@ type TransitionTaskRequest = {
5806
5812
  /**
5807
5813
  * Caller context for the automation dispatches the task makes from here on, forwarded as `X-Naturali-Context-<key>` headers on their tool calls.
5808
5814
  * Supplying 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.
5809
- * The 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).
5815
+ * The 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).
5810
5816
  * Write-only: never returned by a task read, and cleared when the transition closes the task.
5811
5817
  */
5812
5818
  tool_context?: {
@@ -5871,7 +5877,7 @@ type Tool = {
5871
5877
  */
5872
5878
  denied_actions?: Array<string> | null;
5873
5879
  /**
5874
- * Optional allowlist of `tool_context` keys that may be forwarded to this tool as prefixed context headers (`X-Naturali-Context-<key>` by default). When `null`, 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.
5880
+ * Optional allowlist of `tool_context` keys that may be forwarded to this tool as prefixed context headers (`X-Naturali-Context-<key>` by default). When `null`, 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.
5875
5881
  */
5876
5882
  context_keys?: Array<string> | null;
5877
5883
  /**
@@ -5939,7 +5945,7 @@ type UpdateToolRequest = {
5939
5945
  */
5940
5946
  denied_actions?: Array<string> | null;
5941
5947
  /**
5942
- * Optional allowlist of `tool_context` keys that may be forwarded to this tool as prefixed context headers (`X-Naturali-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.
5948
+ * Optional allowlist of `tool_context` keys that may be forwarded to this tool as prefixed context headers (`X-Naturali-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.
5943
5949
  */
5944
5950
  context_keys?: Array<string> | null;
5945
5951
  /**
@@ -5982,7 +5988,7 @@ type CallToolRequest = {
5982
5988
  };
5983
5989
  /**
5984
5990
  * Key/value context for this call, forwarded to the tool as `X-Naturali-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.
5985
- * This 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`.
5991
+ * This 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`.
5986
5992
  *
5987
5993
  */
5988
5994
  tool_context?: {
@@ -7581,7 +7587,7 @@ type DeleteAgentErrors = {
7581
7587
  */
7582
7588
  404: ErrorResponse;
7583
7589
  /**
7584
- * Agent has dependent generations or traces (pass `force=true` to delete anyway). `error.meta` carries `generationCount` and `traceCount` so a caller can tell which one is nonzero.
7590
+ * Agent has dependent generations or traces (pass `force=true` to delete anyway). `error.meta` carries `generation_count` and `trace_count` so a caller can tell which one is nonzero.
7585
7591
  *
7586
7592
  */
7587
7593
  409: ErrorResponse;
@@ -12022,7 +12028,7 @@ type StartEvalRunData = {
12022
12028
  *
12023
12029
  * Stored 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.
12024
12030
  *
12025
- * An 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.
12031
+ * An 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.
12026
12032
  */
12027
12033
  tool_context?: {
12028
12034
  [key: string]: string;
@@ -15918,7 +15924,7 @@ type CreateQuotaData = {
15918
15924
  */
15919
15925
  mode?: 'enforce' | 'monitor';
15920
15926
  /**
15921
- * Only for metric cost_usd (400 on any other metric). What an enforce quota does when the current window is a pricing blackout — several metered events, none of them priced, so the aggregate is 0 however much was actually spent. block (the default) refuses new generations with 409 QUOTA_UNENFORCEABLE until pricing is configured; allow accepts the unmeasurable spend explicitly. Either way a quota_unpriced exception is filed. monitor-mode quotas never block regardless.
15927
+ * Only for metric cost_usd (400 on any other metric). What an enforce quota does when the current window is a pricing blackout — several metered llm_tokens events, none of them priced, so the aggregate is 0 however much was actually spent. Platform meters such as compute_execution are read for the aggregate but never for this verdict. block (the default) refuses new generations with 409 QUOTA_UNENFORCEABLE until pricing is configured; allow accepts the unmeasurable spend explicitly. Either way a quota_unpriced exception is filed. monitor-mode quotas never block regardless.
15922
15928
  */
15923
15929
  on_unpriced?: 'block' | 'allow';
15924
15930
  };
@@ -19016,7 +19022,7 @@ declare class AiProviders {
19016
19022
  /**
19017
19023
  * Upsert per-provider price overrides
19018
19024
  *
19019
- * 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.
19025
+ * 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.
19020
19026
  *
19021
19027
  */
19022
19028
  static updateAiProviderPrices<ThrowOnError extends boolean = false>(options: Options<UpdateAiProviderPricesData, ThrowOnError>): RequestResult<UpdateAiProviderPricesResponses, UpdateAiProviderPricesErrors, ThrowOnError>;
@@ -19674,6 +19680,8 @@ declare class Formations {
19674
19680
  *
19675
19681
  * 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 `naturali` CLI exits non-zero on that body so `update-formation && …` does not lie.
19676
19682
  *
19683
+ * 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.
19684
+ *
19677
19685
  */
19678
19686
  static updateFormation<ThrowOnError extends boolean = false>(options: Options<UpdateFormationData, ThrowOnError>): RequestResult<UpdateFormationResponses, UpdateFormationErrors, ThrowOnError>;
19679
19687
  /**
package/dist/index.d.mts CHANGED
@@ -600,11 +600,11 @@ type Agent = {
600
600
  */
601
601
  max_steps?: number | null;
602
602
  /**
603
- * 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`.
603
+ * 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`.
604
604
  */
605
605
  tool_choice?: unknown;
606
606
  /**
607
- * Conditions that end the agent's work early, on top of `max_steps` — turn-scoped (`hasToolCall`) or chain-scoped (`maxChainGenerations`). See the create request body for the accepted shapes.
607
+ * Conditions that end the agent's work early, on top of `max_steps` — turn-scoped (`has_tool_call`) or chain-scoped (`max_chain_generations`). See the create request body for the accepted shapes.
608
608
  */
609
609
  stop_conditions?: Array<{
610
610
  [key: string]: unknown;
@@ -816,17 +816,17 @@ type CreateAgentRequest = {
816
816
  tool_bindings?: Array<ToolBinding>;
817
817
  max_steps?: number;
818
818
  /**
819
- * 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`.
819
+ * 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`.
820
820
  */
821
821
  tool_choice?: unknown;
822
822
  /**
823
823
  * Conditions that end the agent's work early, on top of `max_steps`. Two scopes:
824
824
  *
825
- * `{"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`.
825
+ * `{"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`.
826
826
  *
827
- * `{"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.
827
+ * `{"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.
828
828
  *
829
- * An 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.
829
+ * An 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.
830
830
  */
831
831
  stop_conditions?: Array<{
832
832
  [key: string]: unknown;
@@ -921,17 +921,17 @@ type UpdateAgentRequest = {
921
921
  tool_bindings?: Array<ToolBinding> | null;
922
922
  max_steps?: number | null;
923
923
  /**
924
- * 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`.
924
+ * 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`.
925
925
  */
926
926
  tool_choice?: unknown;
927
927
  /**
928
928
  * Conditions that end the agent's work early, on top of `max_steps`. Two scopes:
929
929
  *
930
- * `{"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`.
930
+ * `{"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`.
931
931
  *
932
- * `{"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.
932
+ * `{"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.
933
933
  *
934
- * An 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.
934
+ * An 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.
935
935
  */
936
936
  stop_conditions?: Array<{
937
937
  [key: string]: unknown;
@@ -1250,7 +1250,7 @@ type CreateToolRequest = {
1250
1250
  */
1251
1251
  denied_actions?: Array<string>;
1252
1252
  /**
1253
- * Optional allowlist of `tool_context` keys that may be forwarded to this tool as prefixed context headers (`X-Naturali-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.
1253
+ * Optional allowlist of `tool_context` keys that may be forwarded to this tool as prefixed context headers (`X-Naturali-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.
1254
1254
  */
1255
1255
  context_keys?: Array<string> | null;
1256
1256
  /**
@@ -2800,19 +2800,19 @@ type AgentResourceProperties = {
2800
2800
  */
2801
2801
  tool_choice?: unknown;
2802
2802
  /**
2803
- * Conditions that stop the agent's work early — turn-scoped (`hasToolCall`) or chain-scoped (`maxChainGenerations`).
2803
+ * Conditions that stop the agent's work early — turn-scoped (`has_tool_call`) or chain-scoped (`max_chain_generations`).
2804
2804
  */
2805
2805
  stop_conditions?: Array<{
2806
2806
  /**
2807
- * Condition type — `hasToolCall` or `maxChainGenerations`
2807
+ * Condition type — `has_tool_call` or `max_chain_generations`
2808
2808
  */
2809
2809
  type?: string;
2810
2810
  /**
2811
- * Tool name to match when type is `hasToolCall`
2811
+ * Tool name to match when type is `has_tool_call`
2812
2812
  */
2813
2813
  tool_name?: string | null;
2814
2814
  /**
2815
- * Generations the continuation chain may reach when type is `maxChainGenerations`
2815
+ * Generations the continuation chain may reach when type is `max_chain_generations`
2816
2816
  */
2817
2817
  max_generations?: number | null;
2818
2818
  }> | null;
@@ -3077,7 +3077,7 @@ type ToolResourceProperties = {
3077
3077
  */
3078
3078
  denied_actions?: Array<string> | null;
3079
3079
  /**
3080
- * Optional allowlist of `tool_context` keys forwarded to this tool as prefixed context headers. `null` or omitted forwards every key; `[]` forwards none. The server-pinned identity keys (`sessionId`, `actorId`, `actorExternalId`) are always forwarded, and a key consumed by a `{{context:<key>}}` token in this tool's own headers is substituted regardless of this list.
3080
+ * Optional allowlist of `tool_context` keys forwarded to this tool as prefixed context headers. `null` or omitted forwards every key; `[]` forwards none. The server-pinned identity keys (`session_id`, `actor_id`, `actor_external_id`) are always forwarded, and a key consumed by a `{{context:<key>}}` token in this tool's own headers is substituted regardless of this list.
3081
3081
  */
3082
3082
  context_keys?: Array<string> | null;
3083
3083
  /**
@@ -3714,6 +3714,8 @@ type Formation = {
3714
3714
  /**
3715
3715
  * Why the formation is `failed` or `delete_failed`, in the same `{ code, message, meta }` shape as an error response. Null in every other status, and cleared by the next successful deploy. This is the reason a `2xx` deploy response can report `status: "failed"` without a second call to `list-formation-events`.
3716
3716
  *
3717
+ * One case carries an error while the formation is `active`: `FORMATION_REPLACE_CLEANUP_FAILED`, when a deploy replaced a resource and the superseded one could not be deleted. The desired state is realised, so the deploy succeeded — but the old resource is still live, and `meta.failures` names it. It stays on the formation as pending cleanup and is retried on the next deploy or teardown, which clears the error once it is gone.
3718
+ *
3717
3719
  */
3718
3720
  error?: FormationError | null;
3719
3721
  /**
@@ -3784,7 +3786,7 @@ type UnauthorizedFormationAction = {
3784
3786
  */
3785
3787
  type FormationError = {
3786
3788
  /**
3787
- * The failing operation's error code (`VALIDATION_FAILED`, `RESOURCE_NOT_FOUND`, `FORMATION_DELETE_FAILED`, …), or `UNKNOWN` when the underlying failure carried no code.
3789
+ * The failing operation's error code (`VALIDATION_FAILED`, `RESOURCE_NOT_FOUND`, `FORMATION_DELETE_FAILED`, `FORMATION_REPLACE_CLEANUP_FAILED`, …), or `UNKNOWN` when the underlying failure carried no code.
3788
3790
  */
3789
3791
  code: string;
3790
3792
  /**
@@ -3792,7 +3794,7 @@ type FormationError = {
3792
3794
  */
3793
3795
  message: string;
3794
3796
  /**
3795
- * Context for the failure. A failed apply names the resource that broke it (`logical_id`, `resource_type`); a failed teardown lists every blocker under `failures`.
3797
+ * Context for the failure. A failed apply names the resource that broke it (`logical_id`, `resource_type`); a failed teardown lists every blocker under `failures`, and so does a succeeded deploy that could not dispose of a replaced resource — there each entry adds the `physical_resource_id` still live.
3796
3798
  */
3797
3799
  meta?: {
3798
3800
  [key: string]: unknown;
@@ -4750,7 +4752,7 @@ type OrchestrationNode = {
4750
4752
  */
4751
4753
  parallelism?: number;
4752
4754
  /**
4753
- * For loop and sub_orchestration nodes — allowlist of the run's `tool_context` keys the child run inherits. When `null` (the default), the child inherits the parent's whole bag — the behavior of every graph authored before this field existed. When set, only the listed keys are handed down, so a run holding a broad credential can delegate one step to a shared sub-graph without passing on what that sub-graph does not need; `[]` hands down nothing. Matching is case-insensitive, since an entry names a key that becomes an HTTP header name; an entry outside that grammar is rejected at write time with `INVALID_TOOL_CONTEXT_KEY`. The server-derived identity keys (`sessionId`, `actorId`, `actorExternalId`) are unaffected — they are re-derived per generation in the child regardless of this list. Ignored for other node types.
4755
+ * For loop and sub_orchestration nodes — allowlist of the run's `tool_context` keys the child run inherits. When `null` (the default), the child inherits the parent's whole bag — the behavior of every graph authored before this field existed. When set, only the listed keys are handed down, so a run holding a broad credential can delegate one step to a shared sub-graph without passing on what that sub-graph does not need; `[]` hands down nothing. Matching is case-insensitive, since an entry names a key that becomes an HTTP header name; an entry outside that grammar is rejected at write time with `INVALID_TOOL_CONTEXT_KEY`. The server-derived identity keys (`session_id`, `actor_id`, `actor_external_id`) are unaffected — they are re-derived per generation in the child regardless of this list. Ignored for other node types.
4754
4756
  */
4755
4757
  context_keys?: Array<string> | null;
4756
4758
  /**
@@ -5036,6 +5038,10 @@ type OrchestrationRun = {
5036
5038
  * The node within `parent_orchestration_run_id` that started this run. Null when `parent_orchestration_run_id` is null.
5037
5039
  */
5038
5040
  parent_node_id?: string | null;
5041
+ /**
5042
+ * `loop` / `sub_orchestration` edges between this run and the run a caller started: `0` for a caller-started run, one more than its parent's for a child. Starting a child past the effective bound — the smaller of the deployment's `MAX_ORCHESTRATION_RUN_DEPTH` (default 10) and the project's `max_run_depth` — is refused with `ORCHESTRATION_RUN_DEPTH_LIMIT`, which fails the run that tried to descend. That bounds a graph whose `sub_orchestration` node names itself, directly or through a cycle of two graphs, which the intra-graph cycle check cannot see.
5043
+ */
5044
+ run_depth?: number;
5039
5045
  /**
5040
5046
  * Terminal node artifact(s) when the run has succeeded.
5041
5047
  */
@@ -5177,7 +5183,7 @@ type StartRunRequest = {
5177
5183
  *
5178
5184
  * The 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.
5179
5185
  *
5180
- * The reserved identity keys (`sessionId`, `actorId`, `actorExternalId`) are stripped at generation time — a caller cannot address them from here.
5186
+ * The reserved identity keys (`session_id`, `actor_id`, `actor_external_id`) are stripped at generation time — a caller cannot address them from here.
5181
5187
  */
5182
5188
  tool_context?: {
5183
5189
  [key: string]: string;
@@ -5773,7 +5779,7 @@ type CreateTaskRequest = {
5773
5779
  /**
5774
5780
  * Key-value pairs forwarded as `X-Naturali-Context-<key>` headers on every `http` and `mcp` 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-Naturali-Context-` plus the key verbatim; no character is re-cased.
5775
5781
  * Creation 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`).
5776
- * The 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).
5782
+ * The 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).
5777
5783
  * Write-only: the stored bag is never returned by any task read, and it is cleared when the task reaches a terminal state.
5778
5784
  */
5779
5785
  tool_context?: {
@@ -5806,7 +5812,7 @@ type TransitionTaskRequest = {
5806
5812
  /**
5807
5813
  * Caller context for the automation dispatches the task makes from here on, forwarded as `X-Naturali-Context-<key>` headers on their tool calls.
5808
5814
  * Supplying 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.
5809
- * The 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).
5815
+ * The 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).
5810
5816
  * Write-only: never returned by a task read, and cleared when the transition closes the task.
5811
5817
  */
5812
5818
  tool_context?: {
@@ -5871,7 +5877,7 @@ type Tool = {
5871
5877
  */
5872
5878
  denied_actions?: Array<string> | null;
5873
5879
  /**
5874
- * Optional allowlist of `tool_context` keys that may be forwarded to this tool as prefixed context headers (`X-Naturali-Context-<key>` by default). When `null`, 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.
5880
+ * Optional allowlist of `tool_context` keys that may be forwarded to this tool as prefixed context headers (`X-Naturali-Context-<key>` by default). When `null`, 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.
5875
5881
  */
5876
5882
  context_keys?: Array<string> | null;
5877
5883
  /**
@@ -5939,7 +5945,7 @@ type UpdateToolRequest = {
5939
5945
  */
5940
5946
  denied_actions?: Array<string> | null;
5941
5947
  /**
5942
- * Optional allowlist of `tool_context` keys that may be forwarded to this tool as prefixed context headers (`X-Naturali-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.
5948
+ * Optional allowlist of `tool_context` keys that may be forwarded to this tool as prefixed context headers (`X-Naturali-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.
5943
5949
  */
5944
5950
  context_keys?: Array<string> | null;
5945
5951
  /**
@@ -5982,7 +5988,7 @@ type CallToolRequest = {
5982
5988
  };
5983
5989
  /**
5984
5990
  * Key/value context for this call, forwarded to the tool as `X-Naturali-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.
5985
- * This 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`.
5991
+ * This 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`.
5986
5992
  *
5987
5993
  */
5988
5994
  tool_context?: {
@@ -7581,7 +7587,7 @@ type DeleteAgentErrors = {
7581
7587
  */
7582
7588
  404: ErrorResponse;
7583
7589
  /**
7584
- * Agent has dependent generations or traces (pass `force=true` to delete anyway). `error.meta` carries `generationCount` and `traceCount` so a caller can tell which one is nonzero.
7590
+ * Agent has dependent generations or traces (pass `force=true` to delete anyway). `error.meta` carries `generation_count` and `trace_count` so a caller can tell which one is nonzero.
7585
7591
  *
7586
7592
  */
7587
7593
  409: ErrorResponse;
@@ -12022,7 +12028,7 @@ type StartEvalRunData = {
12022
12028
  *
12023
12029
  * Stored 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.
12024
12030
  *
12025
- * An 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.
12031
+ * An 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.
12026
12032
  */
12027
12033
  tool_context?: {
12028
12034
  [key: string]: string;
@@ -15918,7 +15924,7 @@ type CreateQuotaData = {
15918
15924
  */
15919
15925
  mode?: 'enforce' | 'monitor';
15920
15926
  /**
15921
- * Only for metric cost_usd (400 on any other metric). What an enforce quota does when the current window is a pricing blackout — several metered events, none of them priced, so the aggregate is 0 however much was actually spent. block (the default) refuses new generations with 409 QUOTA_UNENFORCEABLE until pricing is configured; allow accepts the unmeasurable spend explicitly. Either way a quota_unpriced exception is filed. monitor-mode quotas never block regardless.
15927
+ * Only for metric cost_usd (400 on any other metric). What an enforce quota does when the current window is a pricing blackout — several metered llm_tokens events, none of them priced, so the aggregate is 0 however much was actually spent. Platform meters such as compute_execution are read for the aggregate but never for this verdict. block (the default) refuses new generations with 409 QUOTA_UNENFORCEABLE until pricing is configured; allow accepts the unmeasurable spend explicitly. Either way a quota_unpriced exception is filed. monitor-mode quotas never block regardless.
15922
15928
  */
15923
15929
  on_unpriced?: 'block' | 'allow';
15924
15930
  };
@@ -19016,7 +19022,7 @@ declare class AiProviders {
19016
19022
  /**
19017
19023
  * Upsert per-provider price overrides
19018
19024
  *
19019
- * 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.
19025
+ * 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.
19020
19026
  *
19021
19027
  */
19022
19028
  static updateAiProviderPrices<ThrowOnError extends boolean = false>(options: Options<UpdateAiProviderPricesData, ThrowOnError>): RequestResult<UpdateAiProviderPricesResponses, UpdateAiProviderPricesErrors, ThrowOnError>;
@@ -19674,6 +19680,8 @@ declare class Formations {
19674
19680
  *
19675
19681
  * 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 `naturali` CLI exits non-zero on that body so `update-formation && …` does not lie.
19676
19682
  *
19683
+ * 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.
19684
+ *
19677
19685
  */
19678
19686
  static updateFormation<ThrowOnError extends boolean = false>(options: Options<UpdateFormationData, ThrowOnError>): RequestResult<UpdateFormationResponses, UpdateFormationErrors, ThrowOnError>;
19679
19687
  /**
package/dist/index.mjs CHANGED
@@ -1384,7 +1384,7 @@ var AiProviders = class {
1384
1384
  /**
1385
1385
  * Upsert per-provider price overrides
1386
1386
  *
1387
- * 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.
1387
+ * 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.
1388
1388
  *
1389
1389
  */
1390
1390
  static updateAiProviderPrices(options) {
@@ -2662,6 +2662,8 @@ var Formations = class {
2662
2662
  *
2663
2663
  * 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 `naturali` CLI exits non-zero on that body so `update-formation && …` does not lie.
2664
2664
  *
2665
+ * 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.
2666
+ *
2665
2667
  */
2666
2668
  static updateFormation(options) {
2667
2669
  return (options.client ?? client).put({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturali/sdk",
3
- "version": "0.90.0",
3
+ "version": "0.91.1",
4
4
  "description": "TypeScript SDK for the naturali.ai API, generated from its OpenAPI specs",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -37,7 +37,7 @@
37
37
  "tsx": "^4.23.1",
38
38
  "typescript": "~6.0.3",
39
39
  "vitest": "^4.1.10",
40
- "@naturali/api": "0.90.0"
40
+ "@naturali/api": "0.91.1"
41
41
  },
42
42
  "scripts": {
43
43
  "generate": "tsx scripts/generate.ts",