@genesislcap/ai-assistant 15.10.6 → 15.12.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 (70) hide show
  1. package/dist/ai-assistant.api.json +226 -0
  2. package/dist/ai-assistant.d.ts +100 -3
  3. package/dist/chat-driver.cjs +540 -117
  4. package/dist/chat-driver.cjs.map +4 -4
  5. package/dist/chat-driver.mjs +524 -116
  6. package/dist/chat-driver.mjs.map +4 -4
  7. package/dist/custom-elements.json +439 -66
  8. package/dist/dts/chat-driver-node.d.ts +5 -2
  9. package/dist/dts/chat-driver-node.d.ts.map +1 -1
  10. package/dist/dts/components/chat-driver/chat-driver.d.ts +20 -3
  11. package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
  12. package/dist/dts/components/chat-driver/chat-driver.thinking-policy.test.d.ts +2 -0
  13. package/dist/dts/components/chat-driver/chat-driver.thinking-policy.test.d.ts.map +1 -0
  14. package/dist/dts/components/chat-driver/chat-driver.trace-capture.test.d.ts +2 -0
  15. package/dist/dts/components/chat-driver/chat-driver.trace-capture.test.d.ts.map +1 -0
  16. package/dist/dts/components/settings-modal/settings-modal.styles.d.ts.map +1 -1
  17. package/dist/dts/components/settings-modal/settings-modal.template.d.ts +1 -1
  18. package/dist/dts/components/settings-modal/settings-modal.template.d.ts.map +1 -1
  19. package/dist/dts/config/config.d.ts +39 -2
  20. package/dist/dts/config/config.d.ts.map +1 -1
  21. package/dist/dts/config/define-stateful-agent.d.ts +15 -1
  22. package/dist/dts/config/define-stateful-agent.d.ts.map +1 -1
  23. package/dist/dts/main/main.d.ts +25 -0
  24. package/dist/dts/main/main.d.ts.map +1 -1
  25. package/dist/dts/main/main.template.d.ts.map +1 -1
  26. package/dist/dts/react.d.ts +9 -8
  27. package/dist/dts/utils/strip-agent-handlers.d.ts +1 -1
  28. package/dist/dts/utils/sum-usage.d.ts +37 -4
  29. package/dist/dts/utils/sum-usage.d.ts.map +1 -1
  30. package/dist/dts/utils/usage-rows.d.ts +102 -0
  31. package/dist/dts/utils/usage-rows.d.ts.map +1 -0
  32. package/dist/dts/utils/usage-rows.test.d.ts +2 -0
  33. package/dist/dts/utils/usage-rows.test.d.ts.map +1 -0
  34. package/dist/esm/chat-driver-node.js +36 -1
  35. package/dist/esm/components/chat-driver/chat-driver.js +73 -10
  36. package/dist/esm/components/chat-driver/chat-driver.thinking-policy.test.js +137 -0
  37. package/dist/esm/components/chat-driver/chat-driver.trace-capture.test.js +200 -0
  38. package/dist/esm/components/settings-modal/settings-modal.styles.js +22 -0
  39. package/dist/esm/components/settings-modal/settings-modal.template.js +25 -4
  40. package/dist/esm/components/settings-modal/settings-modal.template.test.js +1 -1
  41. package/dist/esm/config/define-stateful-agent.js +11 -0
  42. package/dist/esm/main/blocked-state.test.js +1 -0
  43. package/dist/esm/main/budget-meter.test.js +42 -0
  44. package/dist/esm/main/main.js +49 -0
  45. package/dist/esm/main/main.template.js +20 -1
  46. package/dist/esm/utils/strip-agent-handlers.js +1 -1
  47. package/dist/esm/utils/sum-usage.js +37 -4
  48. package/dist/esm/utils/usage-rows.js +90 -0
  49. package/dist/esm/utils/usage-rows.test.js +189 -0
  50. package/dist/react.cjs +11 -6
  51. package/dist/react.mjs +10 -5
  52. package/dist/tsconfig.tsbuildinfo +1 -1
  53. package/package.json +17 -17
  54. package/src/chat-driver-node.ts +58 -0
  55. package/src/components/chat-driver/chat-driver.thinking-policy.test.ts +185 -0
  56. package/src/components/chat-driver/chat-driver.trace-capture.test.ts +251 -0
  57. package/src/components/chat-driver/chat-driver.ts +90 -10
  58. package/src/components/settings-modal/settings-modal.styles.ts +22 -0
  59. package/src/components/settings-modal/settings-modal.template.test.ts +1 -1
  60. package/src/components/settings-modal/settings-modal.template.ts +27 -2
  61. package/src/config/config.ts +50 -1
  62. package/src/config/define-stateful-agent.ts +37 -0
  63. package/src/main/blocked-state.test.ts +1 -0
  64. package/src/main/budget-meter.test.ts +50 -0
  65. package/src/main/main.template.ts +19 -1
  66. package/src/main/main.ts +47 -0
  67. package/src/utils/strip-agent-handlers.ts +1 -1
  68. package/src/utils/sum-usage.ts +37 -4
  69. package/src/utils/usage-rows.test.ts +237 -0
  70. package/src/utils/usage-rows.ts +187 -0
@@ -7753,6 +7753,36 @@
7753
7753
  "isProtected": false,
7754
7754
  "isAbstract": false
7755
7755
  },
7756
+ {
7757
+ "kind": "Property",
7758
+ "canonicalReference": "@genesislcap/ai-assistant!FoundationAiAssistant#budgetMeterLastFedAt:member",
7759
+ "docComment": "/**\n * When budget figures last arrived — from the host's {@link FoundationAiAssistant.setVendorBudget} or the wall latch's own feed — as epoch ms; `null` until the first feed.\n *\n * ELEMENT state, not slice state, on purpose: the reducer is idempotent by value (an unchanged re-feed must not re-render the meter rows), but \"when was this fetched\" must move on every feed, changed figures or not — a refresh that confirms the same dollars is still a refresh. Only the toolbar label observes this, so a stamp re-renders one span, not the rows.\n */\n",
7760
+ "excerptTokens": [
7761
+ {
7762
+ "kind": "Content",
7763
+ "text": "budgetMeterLastFedAt: "
7764
+ },
7765
+ {
7766
+ "kind": "Content",
7767
+ "text": "number | null"
7768
+ },
7769
+ {
7770
+ "kind": "Content",
7771
+ "text": ";"
7772
+ }
7773
+ ],
7774
+ "isReadonly": false,
7775
+ "isOptional": false,
7776
+ "releaseTag": "Beta",
7777
+ "name": "budgetMeterLastFedAt",
7778
+ "propertyTypeTokenRange": {
7779
+ "startIndex": 1,
7780
+ "endIndex": 2
7781
+ },
7782
+ "isStatic": false,
7783
+ "isProtected": false,
7784
+ "isAbstract": false
7785
+ },
7756
7786
  {
7757
7787
  "kind": "Property",
7758
7788
  "canonicalReference": "@genesislcap/ai-assistant!FoundationAiAssistant#busy:member",
@@ -10485,6 +10515,37 @@
10485
10515
  "isAbstract": false,
10486
10516
  "name": "removeCostSessionFromHistory"
10487
10517
  },
10518
+ {
10519
+ "kind": "Method",
10520
+ "canonicalReference": "@genesislcap/ai-assistant!FoundationAiAssistant#requestBudgetRefresh:member(1)",
10521
+ "docComment": "/**\n * Ask the host to re-fetch budget figures now (GENC-1464 refresh affordance).\n *\n * The element cannot fetch — the meter is host-fed by design — so this emits `budget-refresh-requested` and the host answers with the same fetch that already feeds {@link FoundationAiAssistant.setVendorBudget} (Create's handler coalesces in-flight fetches, so a spammed button costs one request). Fired by the meter's refresh button and on settings-modal open, so the figures are fresh exactly when someone is looking at them. Fires unconditionally: a host without a listener simply keeps the per-turn cadence.\n */\n",
10522
+ "excerptTokens": [
10523
+ {
10524
+ "kind": "Content",
10525
+ "text": "requestBudgetRefresh(): "
10526
+ },
10527
+ {
10528
+ "kind": "Content",
10529
+ "text": "void"
10530
+ },
10531
+ {
10532
+ "kind": "Content",
10533
+ "text": ";"
10534
+ }
10535
+ ],
10536
+ "isStatic": false,
10537
+ "returnTypeTokenRange": {
10538
+ "startIndex": 1,
10539
+ "endIndex": 2
10540
+ },
10541
+ "releaseTag": "Beta",
10542
+ "isProtected": false,
10543
+ "overloadIndex": 1,
10544
+ "parameters": [],
10545
+ "isOptional": false,
10546
+ "isAbstract": false,
10547
+ "name": "requestBudgetRefresh"
10548
+ },
10488
10549
  {
10489
10550
  "kind": "Property",
10490
10551
  "canonicalReference": "@genesislcap/ai-assistant!FoundationAiAssistant#resolvedCostHistory:member",
@@ -11207,6 +11268,36 @@
11207
11268
  "isProtected": false,
11208
11269
  "isAbstract": false
11209
11270
  },
11271
+ {
11272
+ "kind": "Property",
11273
+ "canonicalReference": "@genesislcap/ai-assistant!FoundationAiAssistant#settingsBudgetUpdatedLabel:member",
11274
+ "docComment": "/**\n * \"Updated HH:MM:SS\" for the meter toolbar, or `undefined` before any feed.\n */\n",
11275
+ "excerptTokens": [
11276
+ {
11277
+ "kind": "Content",
11278
+ "text": "get settingsBudgetUpdatedLabel(): "
11279
+ },
11280
+ {
11281
+ "kind": "Content",
11282
+ "text": "string | undefined"
11283
+ },
11284
+ {
11285
+ "kind": "Content",
11286
+ "text": ";"
11287
+ }
11288
+ ],
11289
+ "isReadonly": true,
11290
+ "isOptional": false,
11291
+ "releaseTag": "Beta",
11292
+ "name": "settingsBudgetUpdatedLabel",
11293
+ "propertyTypeTokenRange": {
11294
+ "startIndex": 1,
11295
+ "endIndex": 2
11296
+ },
11297
+ "isStatic": false,
11298
+ "isProtected": false,
11299
+ "isAbstract": false
11300
+ },
11210
11301
  {
11211
11302
  "kind": "Property",
11212
11303
  "canonicalReference": "@genesislcap/ai-assistant!FoundationAiAssistant#settingsCogVisible:member",
@@ -17768,6 +17859,74 @@
17768
17859
  "endIndex": 6
17769
17860
  }
17770
17861
  },
17862
+ {
17863
+ "kind": "PropertySignature",
17864
+ "canonicalReference": "@genesislcap/ai-assistant!StatefulAgentInit#thinkingPolicy:member",
17865
+ "docComment": "/**\n * Extended-thinking posture. Either a static `ChatThinkingPolicy` or a function resolved with the current `state` **once per user turn** — the function form is the point of this option on a machine agent: `'auto'` in the state that makes a real decision, `'off'` in the states that only step a known sequence, where reasoning is billed at the full output rate to re-derive what the machine already knows. Omit, or return `undefined` from the function, to keep the model's own default for that turn.\n *\n * Resolved once per turn rather than per tool-loop iteration (unlike `temperature` and `toolChoice`): a tool-use loop is one assistant turn and its thinking mode must hold for the whole of it. A state transition part-way through a loop therefore takes effect on the next user turn, not immediately.\n */\n",
17866
+ "excerptTokens": [
17867
+ {
17868
+ "kind": "Content",
17869
+ "text": "thinkingPolicy?: "
17870
+ },
17871
+ {
17872
+ "kind": "Reference",
17873
+ "text": "ChatThinkingPolicy",
17874
+ "canonicalReference": "@genesislcap/foundation-ai!ChatThinkingPolicy:type"
17875
+ },
17876
+ {
17877
+ "kind": "Content",
17878
+ "text": " | ((ctx: "
17879
+ },
17880
+ {
17881
+ "kind": "Reference",
17882
+ "text": "StatefulAgentContext",
17883
+ "canonicalReference": "@genesislcap/ai-assistant!StatefulAgentContext:type"
17884
+ },
17885
+ {
17886
+ "kind": "Content",
17887
+ "text": "<S>) => "
17888
+ },
17889
+ {
17890
+ "kind": "Reference",
17891
+ "text": "ChatThinkingPolicy",
17892
+ "canonicalReference": "@genesislcap/foundation-ai!ChatThinkingPolicy:type"
17893
+ },
17894
+ {
17895
+ "kind": "Content",
17896
+ "text": " | undefined | "
17897
+ },
17898
+ {
17899
+ "kind": "Reference",
17900
+ "text": "Promise",
17901
+ "canonicalReference": "!Promise:interface"
17902
+ },
17903
+ {
17904
+ "kind": "Content",
17905
+ "text": "<"
17906
+ },
17907
+ {
17908
+ "kind": "Reference",
17909
+ "text": "ChatThinkingPolicy",
17910
+ "canonicalReference": "@genesislcap/foundation-ai!ChatThinkingPolicy:type"
17911
+ },
17912
+ {
17913
+ "kind": "Content",
17914
+ "text": " | undefined>)"
17915
+ },
17916
+ {
17917
+ "kind": "Content",
17918
+ "text": ";"
17919
+ }
17920
+ ],
17921
+ "isReadonly": false,
17922
+ "isOptional": true,
17923
+ "releaseTag": "Beta",
17924
+ "name": "thinkingPolicy",
17925
+ "propertyTypeTokenRange": {
17926
+ "startIndex": 1,
17927
+ "endIndex": 11
17928
+ }
17929
+ },
17771
17930
  {
17772
17931
  "kind": "PropertySignature",
17773
17932
  "canonicalReference": "@genesislcap/ai-assistant!StatefulAgentInit#toolChoice:member",
@@ -18409,6 +18568,73 @@
18409
18568
  "endIndex": 6
18410
18569
  }
18411
18570
  },
18571
+ {
18572
+ "kind": "TypeAlias",
18573
+ "canonicalReference": "@genesislcap/ai-assistant!ThinkingPolicyInput:type",
18574
+ "docComment": "/**\n * Extended-thinking posture for an agent — whether the model reasons before answering. Either a static `ChatThinkingPolicy` or a function resolved **once per user turn**, at the start of the tool loop. Pick the function form to vary it by current state: reason in the state that makes a real decision, and drop it in states that only step a known sequence, where reasoning bills at the full output rate to re-derive what the state machine already knows.\n *\n * Note the resolution point, which differs from every other per-turn input here: a tool-use loop is a single assistant turn and its thinking mode must hold for the whole of it, so this resolver is consulted on the first model call of a turn and its answer reused for the rest. A resolver that returns a different value part-way through a loop will not see it applied until the next user turn.\n *\n * **Omit — or return `undefined` from the function — to keep the model's own default**, which is a distinct third state rather than a synonym for either value: Sonnet 5 and Fable 5 think by default, the rest do not. So an agent that leaves this unset, or a resolver that answers `undefined` on some turns, behaves and prices exactly as it did before this option existed.\n *\n * A request, not a guarantee — transports clamp what a model cannot honour (Fable 5 and Gemini 2.5 Pro always think) and warn once instead of failing the turn. Resolved and applied the same way as {@link TemperatureInput}. See `ChatThinkingPolicy`.\n *\n * @beta\n */\n",
18575
+ "excerptTokens": [
18576
+ {
18577
+ "kind": "Content",
18578
+ "text": "export type ThinkingPolicyInput = "
18579
+ },
18580
+ {
18581
+ "kind": "Reference",
18582
+ "text": "ChatThinkingPolicy",
18583
+ "canonicalReference": "@genesislcap/foundation-ai!ChatThinkingPolicy:type"
18584
+ },
18585
+ {
18586
+ "kind": "Content",
18587
+ "text": " | ((ctx: "
18588
+ },
18589
+ {
18590
+ "kind": "Reference",
18591
+ "text": "SystemPromptContext",
18592
+ "canonicalReference": "@genesislcap/ai-assistant!SystemPromptContext:interface"
18593
+ },
18594
+ {
18595
+ "kind": "Content",
18596
+ "text": ") => "
18597
+ },
18598
+ {
18599
+ "kind": "Reference",
18600
+ "text": "ChatThinkingPolicy",
18601
+ "canonicalReference": "@genesislcap/foundation-ai!ChatThinkingPolicy:type"
18602
+ },
18603
+ {
18604
+ "kind": "Content",
18605
+ "text": " | undefined | "
18606
+ },
18607
+ {
18608
+ "kind": "Reference",
18609
+ "text": "Promise",
18610
+ "canonicalReference": "!Promise:interface"
18611
+ },
18612
+ {
18613
+ "kind": "Content",
18614
+ "text": "<"
18615
+ },
18616
+ {
18617
+ "kind": "Reference",
18618
+ "text": "ChatThinkingPolicy",
18619
+ "canonicalReference": "@genesislcap/foundation-ai!ChatThinkingPolicy:type"
18620
+ },
18621
+ {
18622
+ "kind": "Content",
18623
+ "text": " | undefined>)"
18624
+ },
18625
+ {
18626
+ "kind": "Content",
18627
+ "text": ";"
18628
+ }
18629
+ ],
18630
+ "fileUrlPath": "src/config/config.ts",
18631
+ "releaseTag": "Beta",
18632
+ "name": "ThinkingPolicyInput",
18633
+ "typeTokenRange": {
18634
+ "startIndex": 1,
18635
+ "endIndex": 11
18636
+ }
18637
+ },
18412
18638
  {
18413
18639
  "kind": "TypeAlias",
18414
18640
  "canonicalReference": "@genesislcap/ai-assistant!TimelineMessage:type",
@@ -11,6 +11,7 @@ import type { ChatDriverResult } from '@genesislcap/foundation-ai';
11
11
  import type { ChatFallback } from '@genesislcap/foundation-ai';
12
12
  import type { ChatInputDuringExecutionMode } from '@genesislcap/foundation-ai';
13
13
  import type { ChatMessage } from '@genesislcap/foundation-ai';
14
+ import type { ChatThinkingPolicy } from '@genesislcap/foundation-ai';
14
15
  import type { ChatToolChoice } from '@genesislcap/foundation-ai';
15
16
  import type { ChatToolDefinition } from '@genesislcap/foundation-ai';
16
17
  import type { ChatToolHandlers } from '@genesislcap/foundation-ai';
@@ -969,6 +970,18 @@ declare interface BaseAgentConfig {
969
970
  * @beta
970
971
  */
971
972
  cachePolicy?: CachePolicyInput;
973
+ /**
974
+ * Extended-thinking posture for this agent — whether the model reasons before answering. Either
975
+ * a static value or a function resolved **once per user turn** and held for that turn's whole
976
+ * tool loop (vary by state: `'auto'` where the turn is a genuine decision, `'off'` where it only
977
+ * steps a known sequence and reasoning is billed at the full output rate for no benefit). Omit —
978
+ * or return `undefined` — to keep the model's own default, which is neither `'auto'` nor `'off'`
979
+ * uniformly. Provider-neutral; transports clamp models that cannot honour it.
980
+ * See {@link ThinkingPolicyInput}.
981
+ *
982
+ * @beta
983
+ */
984
+ thinkingPolicy?: ThinkingPolicyInput;
972
985
  /**
973
986
  * Volatile per-turn context injected at the tail of every model-call (after the history and any
974
987
  * cache breakpoint), so it is seen each turn without busting the cached prefix — the place to put
@@ -1425,6 +1438,12 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
1425
1438
  * `undefined` requests no caching (equivalent to `{ scope: 'default' }`).
1426
1439
  */
1427
1440
  private activeCachePolicyInput?;
1441
+ /**
1442
+ * Active agent's extended-thinking selector (static value or per-turn resolver). `undefined` —
1443
+ * unset, or returned by the resolver — leaves the model on its own default posture, which is
1444
+ * neither uniformly on nor off, so an agent that never sets this is unaffected by the option.
1445
+ */
1446
+ private activeThinkingPolicyInput?;
1428
1447
  /**
1429
1448
  * Active agent's tail-context selector (static value or per-turn resolver). The driver frames
1430
1449
  * the resolved string in a `<system-reminder>` marker and injects it at the message tail.
@@ -1826,9 +1845,20 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
1826
1845
  * `condenseWhen` can register against the right call (it stamps the clocks
1827
1846
  * straight off the driver). Absent for dispatch paths with no addressable tool
1828
1847
  * call (e.g. the fold-close handler), where `condenseWhen` is a no-op.
1829
- * @param traceCapture - Optional per-invocation slot. When provided, the trace
1830
- * from any sub-agent call is written here rather than to shared instance state,
1831
- * so parallel tool calls each capture their own trace independently.
1848
+ * @param traceCapture - Optional per-tool-call accumulator. When provided, every
1849
+ * sub-agent call's trace is **appended** here rather than written to shared
1850
+ * instance state, so parallel tool calls each capture their own traces
1851
+ * independently.
1852
+ *
1853
+ * Deliberately a list of traces, not one slot. A single handler may call
1854
+ * `requestSubAgent` more than once — a code-driven scheduler dispatching a
1855
+ * dependency graph, a retry of a timed-out child, any fan-out helper — and a
1856
+ * single slot kept only the last, so every other child ran, was billed by the
1857
+ * provider, and then vanished from history. The loss was silent in the worst
1858
+ * way: `sumUsage` and `usageRows` both recurse into the trace, so they summed a
1859
+ * truncated input and still agreed with each other. Measured at 1 of 7 traces
1860
+ * kept on a seven-way fan-out, reporting ~2.3x under the real cost, with the
1861
+ * error growing as the fan-out widens.
1832
1862
  */
1833
1863
  private buildHandlerContext;
1834
1864
  /**
@@ -1968,6 +1998,8 @@ declare type ChatInteractionEventsMap = {
1968
1998
  };
1969
1999
  };
1970
2000
 
2001
+ export { ChatThinkingPolicy }
2002
+
1971
2003
  export { ChatToolChoice }
1972
2004
 
1973
2005
  /**
@@ -2649,6 +2681,31 @@ export declare class FoundationAiAssistant extends GenesisElement {
2649
2681
  budgetUsd: number;
2650
2682
  spentUsd: number;
2651
2683
  } | null): boolean;
2684
+ /**
2685
+ * When budget figures last arrived — from the host's {@link FoundationAiAssistant.setVendorBudget}
2686
+ * or the wall latch's own feed — as epoch ms; `null` until the first feed.
2687
+ *
2688
+ * ELEMENT state, not slice state, on purpose: the reducer is idempotent by
2689
+ * value (an unchanged re-feed must not re-render the meter rows), but "when
2690
+ * was this fetched" must move on every feed, changed figures or not — a
2691
+ * refresh that confirms the same dollars is still a refresh. Only the
2692
+ * toolbar label observes this, so a stamp re-renders one span, not the rows.
2693
+ */
2694
+ budgetMeterLastFedAt: number | null;
2695
+ /** "Updated HH:MM:SS" for the meter toolbar, or `undefined` before any feed. */
2696
+ get settingsBudgetUpdatedLabel(): string | undefined;
2697
+ /**
2698
+ * Ask the host to re-fetch budget figures now (GENC-1464 refresh affordance).
2699
+ *
2700
+ * The element cannot fetch — the meter is host-fed by design — so this emits
2701
+ * `budget-refresh-requested` and the host answers with the same fetch that
2702
+ * already feeds {@link FoundationAiAssistant.setVendorBudget} (Create's handler coalesces in-flight
2703
+ * fetches, so a spammed button costs one request). Fired by the meter's
2704
+ * refresh button and on settings-modal open, so the figures are fresh exactly
2705
+ * when someone is looking at them. Fires unconditionally: a host without a
2706
+ * listener simply keeps the per-turn cadence.
2707
+ */
2708
+ requestBudgetRefresh(): void;
2652
2709
  /** Whether this vendor's wall came from the sweep alone — see the slice's `sweptVendors`. */
2653
2710
  private isVendorSwept;
2654
2711
  /**
@@ -4689,6 +4746,20 @@ export declare interface StatefulAgentInit<S> {
4689
4746
  * request no caching.
4690
4747
  */
4691
4748
  cachePolicy?: CachePolicy | ((ctx: StatefulAgentContext<S>) => CachePolicy | Promise<CachePolicy>);
4749
+ /**
4750
+ * Extended-thinking posture. Either a static `ChatThinkingPolicy` or a function resolved with
4751
+ * the current `state` **once per user turn** — the function form is the point of this option on
4752
+ * a machine agent: `'auto'` in the state that makes a real decision, `'off'` in the states that
4753
+ * only step a known sequence, where reasoning is billed at the full output rate to re-derive
4754
+ * what the machine already knows. Omit, or return `undefined` from the function, to keep the
4755
+ * model's own default for that turn.
4756
+ *
4757
+ * Resolved once per turn rather than per tool-loop iteration (unlike `temperature` and
4758
+ * `toolChoice`): a tool-use loop is one assistant turn and its thinking mode must hold for the
4759
+ * whole of it. A state transition part-way through a loop therefore takes effect on the next
4760
+ * user turn, not immediately.
4761
+ */
4762
+ thinkingPolicy?: ChatThinkingPolicy | ((ctx: StatefulAgentContext<S>) => ChatThinkingPolicy | undefined | Promise<ChatThinkingPolicy | undefined>);
4692
4763
  /**
4693
4764
  * Volatile per-turn tail context (current file/spec, diagnostics, live state). Either a static
4694
4765
  * string or a function resolved each tool-loop iteration with the current `state`. Provide raw
@@ -4851,6 +4922,32 @@ export declare type TailContextInput = string | ((ctx: SystemPromptContext) => s
4851
4922
  */
4852
4923
  export declare type TemperatureInput = number | ((ctx: SystemPromptContext) => number | Promise<number>);
4853
4924
 
4925
+ /**
4926
+ * Extended-thinking posture for an agent — whether the model reasons before answering. Either a
4927
+ * static `ChatThinkingPolicy` or a function resolved **once per user turn**, at the start of the
4928
+ * tool loop. Pick the function form to vary it by current state: reason in the state that makes a
4929
+ * real decision, and drop it in states that only step a known sequence, where reasoning bills at
4930
+ * the full output rate to re-derive what the state machine already knows.
4931
+ *
4932
+ * Note the resolution point, which differs from every other per-turn input here: a tool-use loop
4933
+ * is a single assistant turn and its thinking mode must hold for the whole of it, so this resolver
4934
+ * is consulted on the first model call of a turn and its answer reused for the rest. A resolver
4935
+ * that returns a different value part-way through a loop will not see it applied until the next
4936
+ * user turn.
4937
+ *
4938
+ * **Omit — or return `undefined` from the function — to keep the model's own default**, which is
4939
+ * a distinct third state rather than a synonym for either value: Sonnet 5 and Fable 5 think by
4940
+ * default, the rest do not. So an agent that leaves this unset, or a resolver that answers
4941
+ * `undefined` on some turns, behaves and prices exactly as it did before this option existed.
4942
+ *
4943
+ * A request, not a guarantee — transports clamp what a model cannot honour (Fable 5 and Gemini
4944
+ * 2.5 Pro always think) and warn once instead of failing the turn. Resolved and applied the same
4945
+ * way as {@link TemperatureInput}. See `ChatThinkingPolicy`.
4946
+ *
4947
+ * @beta
4948
+ */
4949
+ export declare type ThinkingPolicyInput = ChatThinkingPolicy | ((ctx: SystemPromptContext) => ChatThinkingPolicy | undefined | Promise<ChatThinkingPolicy | undefined>);
4950
+
4854
4951
  /**
4855
4952
  * A chat message lifted into the debug-log timeline as a `kind: 'message'` entry.
4856
4953
  *