@stigmer/react 3.12.4 → 3.12.6

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 (369) hide show
  1. package/agent/AgentDetailView.js +2 -2
  2. package/agent/AgentDetailView.js.map +1 -1
  3. package/agent/index.d.ts +0 -1
  4. package/agent/index.d.ts.map +1 -1
  5. package/agent/index.js +0 -1
  6. package/agent/index.js.map +1 -1
  7. package/agent/useUpdateAgent.d.ts +3 -3
  8. package/agent/useUpdateAgent.js +3 -3
  9. package/agent-instance/AgentInstanceDetailPanel.d.ts.map +1 -1
  10. package/agent-instance/AgentInstanceDetailPanel.js +5 -7
  11. package/agent-instance/AgentInstanceDetailPanel.js.map +1 -1
  12. package/agent-instance/useUpdateAgentInstance.d.ts +1 -1
  13. package/agent-instance/useUpdateAgentInstance.js +1 -1
  14. package/attachment/AttachmentChipList.js +16 -6
  15. package/attachment/AttachmentChipList.js.map +1 -1
  16. package/attachment/index.d.ts +1 -1
  17. package/attachment/index.d.ts.map +1 -1
  18. package/attachment/index.js.map +1 -1
  19. package/attachment/useAttachments.d.ts +51 -8
  20. package/attachment/useAttachments.d.ts.map +1 -1
  21. package/attachment/useAttachments.js +74 -3
  22. package/attachment/useAttachments.js.map +1 -1
  23. package/channel/AgentChannelsPanel.d.ts.map +1 -1
  24. package/channel/AgentChannelsPanel.js +10 -5
  25. package/channel/AgentChannelsPanel.js.map +1 -1
  26. package/channel/ChannelRunConfigDialog.d.ts +51 -0
  27. package/channel/ChannelRunConfigDialog.d.ts.map +1 -0
  28. package/channel/ChannelRunConfigDialog.js +121 -0
  29. package/channel/ChannelRunConfigDialog.js.map +1 -0
  30. package/channel/index.d.ts +2 -0
  31. package/channel/index.d.ts.map +1 -1
  32. package/channel/index.js +1 -0
  33. package/channel/index.js.map +1 -1
  34. package/channel/useSaveAgentChannel.d.ts.map +1 -1
  35. package/channel/useSaveAgentChannel.js +6 -3
  36. package/channel/useSaveAgentChannel.js.map +1 -1
  37. package/channel-app/ChannelAppDetailPanel.js +9 -9
  38. package/channel-app/ChannelAppDetailPanel.js.map +1 -1
  39. package/composer/ComposerToolbar.d.ts +6 -1
  40. package/composer/ComposerToolbar.d.ts.map +1 -1
  41. package/composer/ComposerToolbar.js +2 -2
  42. package/composer/ComposerToolbar.js.map +1 -1
  43. package/composer/SessionComposer.d.ts +9 -0
  44. package/composer/SessionComposer.d.ts.map +1 -1
  45. package/composer/SessionComposer.js +39 -13
  46. package/composer/SessionComposer.js.map +1 -1
  47. package/conversation/ConversationComposer.d.ts +19 -3
  48. package/conversation/ConversationComposer.d.ts.map +1 -1
  49. package/conversation/ConversationComposer.js +4 -4
  50. package/conversation/ConversationComposer.js.map +1 -1
  51. package/conversation/ConversationTemplatePickerDialog.d.ts +63 -0
  52. package/conversation/ConversationTemplatePickerDialog.d.ts.map +1 -0
  53. package/conversation/ConversationTemplatePickerDialog.js +151 -0
  54. package/conversation/ConversationTemplatePickerDialog.js.map +1 -0
  55. package/conversation/ConversationsWorkbench.d.ts.map +1 -1
  56. package/conversation/ConversationsWorkbench.js +16 -5
  57. package/conversation/ConversationsWorkbench.js.map +1 -1
  58. package/conversation/index.d.ts +3 -1
  59. package/conversation/index.d.ts.map +1 -1
  60. package/conversation/index.js +1 -0
  61. package/conversation/index.js.map +1 -1
  62. package/conversation/useConversationParticipation.d.ts +41 -4
  63. package/conversation/useConversationParticipation.d.ts.map +1 -1
  64. package/conversation/useConversationParticipation.js +13 -2
  65. package/conversation/useConversationParticipation.js.map +1 -1
  66. package/cursor-accounts/CursorAccountsConsole.d.ts.map +1 -1
  67. package/cursor-accounts/CursorAccountsConsole.js +12 -3
  68. package/cursor-accounts/CursorAccountsConsole.js.map +1 -1
  69. package/cursor-accounts/cursor-account-coverage.d.ts +30 -1
  70. package/cursor-accounts/cursor-account-coverage.d.ts.map +1 -1
  71. package/cursor-accounts/cursor-account-coverage.js +21 -0
  72. package/cursor-accounts/cursor-account-coverage.js.map +1 -1
  73. package/execution/useCreateAgentExecution.d.ts +15 -0
  74. package/execution/useCreateAgentExecution.d.ts.map +1 -1
  75. package/execution/useCreateAgentExecution.js +5 -0
  76. package/execution/useCreateAgentExecution.js.map +1 -1
  77. package/identity-account/AccountPreferencesPanel.d.ts +36 -0
  78. package/identity-account/AccountPreferencesPanel.d.ts.map +1 -0
  79. package/identity-account/AccountPreferencesPanel.js +202 -0
  80. package/identity-account/AccountPreferencesPanel.js.map +1 -0
  81. package/identity-account/index.d.ts +8 -0
  82. package/identity-account/index.d.ts.map +1 -1
  83. package/identity-account/index.js +4 -0
  84. package/identity-account/index.js.map +1 -1
  85. package/identity-account/useAccountExecutionDefaults.d.ts +36 -0
  86. package/identity-account/useAccountExecutionDefaults.d.ts.map +1 -0
  87. package/identity-account/useAccountExecutionDefaults.js +46 -0
  88. package/identity-account/useAccountExecutionDefaults.js.map +1 -0
  89. package/identity-account/useMyIdentityAccount.d.ts +55 -0
  90. package/identity-account/useMyIdentityAccount.d.ts.map +1 -0
  91. package/identity-account/useMyIdentityAccount.js +37 -0
  92. package/identity-account/useMyIdentityAccount.js.map +1 -0
  93. package/identity-account/useUpdateIdentityAccount.d.ts +42 -0
  94. package/identity-account/useUpdateIdentityAccount.d.ts.map +1 -0
  95. package/identity-account/useUpdateIdentityAccount.js +53 -0
  96. package/identity-account/useUpdateIdentityAccount.js.map +1 -0
  97. package/identity-provider/IdentityProviderDetailPanel.d.ts.map +1 -1
  98. package/identity-provider/IdentityProviderDetailPanel.js +16 -15
  99. package/identity-provider/IdentityProviderDetailPanel.js.map +1 -1
  100. package/index.d.ts +15 -13
  101. package/index.d.ts.map +1 -1
  102. package/index.js +11 -8
  103. package/index.js.map +1 -1
  104. package/internal/StandingContextField.d.ts +37 -0
  105. package/internal/StandingContextField.d.ts.map +1 -0
  106. package/internal/StandingContextField.js +24 -0
  107. package/internal/StandingContextField.js.map +1 -0
  108. package/library/InstanceVisibilitySelector.d.ts.map +1 -1
  109. package/library/InstanceVisibilitySelector.js +9 -2
  110. package/library/InstanceVisibilitySelector.js.map +1 -1
  111. package/library/ResourceVisibilityControl.d.ts +13 -3
  112. package/library/ResourceVisibilityControl.d.ts.map +1 -1
  113. package/library/ResourceVisibilityControl.js +33 -5
  114. package/library/ResourceVisibilityControl.js.map +1 -1
  115. package/library/VisibilityOptionRow.d.ts +6 -0
  116. package/library/VisibilityOptionRow.d.ts.map +1 -1
  117. package/library/VisibilityOptionRow.js +11 -1
  118. package/library/VisibilityOptionRow.js.map +1 -1
  119. package/library/VisibilitySelector.d.ts.map +1 -1
  120. package/library/VisibilitySelector.js +14 -2
  121. package/library/VisibilitySelector.js.map +1 -1
  122. package/library/index.d.ts +4 -2
  123. package/library/index.d.ts.map +1 -1
  124. package/library/index.js +2 -1
  125. package/library/index.js.map +1 -1
  126. package/library/useCanSetPublicVisibility.d.ts +30 -0
  127. package/library/useCanSetPublicVisibility.d.ts.map +1 -0
  128. package/library/useCanSetPublicVisibility.js +41 -0
  129. package/library/useCanSetPublicVisibility.js.map +1 -0
  130. package/library/visibilityLevels.d.ts +32 -1
  131. package/library/visibilityLevels.d.ts.map +1 -1
  132. package/library/visibilityLevels.js +34 -14
  133. package/library/visibilityLevels.js.map +1 -1
  134. package/mcp-server/McpServerDetailView.js +2 -2
  135. package/mcp-server/McpServerDetailView.js.map +1 -1
  136. package/mcp-server/index.d.ts +0 -1
  137. package/mcp-server/index.d.ts.map +1 -1
  138. package/mcp-server/index.js +0 -1
  139. package/mcp-server/index.js.map +1 -1
  140. package/mcp-server/internal/definitionDrift.d.ts +14 -12
  141. package/mcp-server/internal/definitionDrift.d.ts.map +1 -1
  142. package/mcp-server/internal/definitionDrift.js +22 -19
  143. package/mcp-server/internal/definitionDrift.js.map +1 -1
  144. package/mcp-server/useMcpServerConnect.d.ts +8 -5
  145. package/mcp-server/useMcpServerConnect.d.ts.map +1 -1
  146. package/mcp-server/useMcpServerConnect.js +2 -1
  147. package/mcp-server/useMcpServerConnect.js.map +1 -1
  148. package/mcp-server/useMcpServerOAuthConnect.d.ts.map +1 -1
  149. package/mcp-server/useMcpServerOAuthConnect.js +7 -2
  150. package/mcp-server/useMcpServerOAuthConnect.js.map +1 -1
  151. package/mcp-server/useUpdateMcpServer.d.ts +3 -3
  152. package/mcp-server/useUpdateMcpServer.js +3 -3
  153. package/models/ModelSelector.d.ts +33 -1
  154. package/models/ModelSelector.d.ts.map +1 -1
  155. package/models/ModelSelector.js +37 -4
  156. package/models/ModelSelector.js.map +1 -1
  157. package/models/index.d.ts +2 -0
  158. package/models/index.d.ts.map +1 -1
  159. package/models/index.js +1 -0
  160. package/models/index.js.map +1 -1
  161. package/models/registry.d.ts +16 -0
  162. package/models/registry.d.ts.map +1 -1
  163. package/models/registry.js +13 -0
  164. package/models/registry.js.map +1 -1
  165. package/models/thinking-mode.d.ts +27 -0
  166. package/models/thinking-mode.d.ts.map +1 -0
  167. package/models/thinking-mode.js +32 -0
  168. package/models/thinking-mode.js.map +1 -0
  169. package/oauth-app/CreateOAuthAppForm.d.ts +2 -2
  170. package/oauth-app/CreateOAuthAppForm.d.ts.map +1 -1
  171. package/oauth-app/CreateOAuthAppForm.js +13 -4
  172. package/oauth-app/CreateOAuthAppForm.js.map +1 -1
  173. package/oauth-app/OAuthAppDetailPanel.d.ts.map +1 -1
  174. package/oauth-app/OAuthAppDetailPanel.js +50 -22
  175. package/oauth-app/OAuthAppDetailPanel.js.map +1 -1
  176. package/organization/OrgPreferencesPanel.d.ts +32 -0
  177. package/organization/OrgPreferencesPanel.d.ts.map +1 -0
  178. package/organization/OrgPreferencesPanel.js +90 -0
  179. package/organization/OrgPreferencesPanel.js.map +1 -0
  180. package/organization/OrgProfilePanel.d.ts.map +1 -1
  181. package/organization/OrgProfilePanel.js +5 -4
  182. package/organization/OrgProfilePanel.js.map +1 -1
  183. package/organization/index.d.ts +2 -0
  184. package/organization/index.d.ts.map +1 -1
  185. package/organization/index.js +1 -0
  186. package/organization/index.js.map +1 -1
  187. package/package.json +4 -4
  188. package/platform-client/PlatformClientDetailPanel.d.ts.map +1 -1
  189. package/platform-client/PlatformClientDetailPanel.js +12 -13
  190. package/platform-client/PlatformClientDetailPanel.js.map +1 -1
  191. package/schedule/ScheduleDetailView.d.ts.map +1 -1
  192. package/schedule/ScheduleDetailView.js +21 -10
  193. package/schedule/ScheduleDetailView.js.map +1 -1
  194. package/schedule/ScheduleForm.d.ts.map +1 -1
  195. package/schedule/ScheduleForm.js +13 -3
  196. package/schedule/ScheduleForm.js.map +1 -1
  197. package/session/NewSessionViewer.d.ts +10 -1
  198. package/session/NewSessionViewer.d.ts.map +1 -1
  199. package/session/NewSessionViewer.js +2 -1
  200. package/session/NewSessionViewer.js.map +1 -1
  201. package/session/run-config.d.ts +9 -0
  202. package/session/run-config.d.ts.map +1 -1
  203. package/session/run-config.js +5 -0
  204. package/session/run-config.js.map +1 -1
  205. package/session/useNewSessionFlow.d.ts +27 -1
  206. package/session/useNewSessionFlow.d.ts.map +1 -1
  207. package/session/useNewSessionFlow.js +51 -8
  208. package/session/useNewSessionFlow.js.map +1 -1
  209. package/session/useSessionConversation.d.ts +12 -1
  210. package/session/useSessionConversation.d.ts.map +1 -1
  211. package/session/useSessionConversation.js +15 -24
  212. package/session/useSessionConversation.js.map +1 -1
  213. package/session/useSessionPageFlow.d.ts.map +1 -1
  214. package/session/useSessionPageFlow.js +14 -10
  215. package/session/useSessionPageFlow.js.map +1 -1
  216. package/session/useUpdateSession.d.ts +18 -24
  217. package/session/useUpdateSession.d.ts.map +1 -1
  218. package/session/useUpdateSession.js +18 -24
  219. package/session/useUpdateSession.js.map +1 -1
  220. package/settings/AccountPreferencesSection.d.ts +3 -0
  221. package/settings/AccountPreferencesSection.d.ts.map +1 -0
  222. package/settings/AccountPreferencesSection.js +10 -0
  223. package/settings/AccountPreferencesSection.js.map +1 -0
  224. package/settings/OrgPreferencesSection.d.ts +3 -0
  225. package/settings/OrgPreferencesSection.d.ts.map +1 -0
  226. package/settings/OrgPreferencesSection.js +13 -0
  227. package/settings/OrgPreferencesSection.js.map +1 -0
  228. package/settings/index.d.ts +2 -0
  229. package/settings/index.d.ts.map +1 -1
  230. package/settings/index.js +2 -0
  231. package/settings/index.js.map +1 -1
  232. package/settings/settings-nav.d.ts.map +1 -1
  233. package/settings/settings-nav.js +17 -1
  234. package/settings/settings-nav.js.map +1 -1
  235. package/src/agent/AgentDetailView.tsx +2 -2
  236. package/src/agent/index.ts +0 -2
  237. package/src/agent/useUpdateAgent.ts +3 -3
  238. package/src/agent-instance/AgentInstanceDetailPanel.tsx +5 -7
  239. package/src/agent-instance/__tests__/AgentInstanceDetailPanel.test.tsx +75 -0
  240. package/src/agent-instance/useUpdateAgentInstance.ts +1 -1
  241. package/src/attachment/AttachmentChipList.tsx +19 -8
  242. package/src/attachment/__tests__/AttachmentChipList.test.tsx +12 -0
  243. package/src/attachment/__tests__/useAttachments.test.ts +293 -0
  244. package/src/attachment/index.ts +1 -0
  245. package/src/attachment/useAttachments.ts +143 -11
  246. package/src/channel/AgentChannelsPanel.tsx +26 -1
  247. package/src/channel/ChannelRunConfigDialog.tsx +351 -0
  248. package/src/channel/__tests__/ChannelRunConfigDialog.test.tsx +210 -0
  249. package/src/channel/index.ts +2 -0
  250. package/src/channel/useSaveAgentChannel.ts +6 -3
  251. package/src/channel-app/ChannelAppDetailPanel.tsx +9 -9
  252. package/src/channel-app/__tests__/channelAppWhatsApp.test.tsx +2 -0
  253. package/src/channel-app/__tests__/channelAppWipeSafety.test.tsx +87 -0
  254. package/src/composer/ComposerToolbar.tsx +9 -0
  255. package/src/composer/SessionComposer.tsx +59 -16
  256. package/src/composer/__tests__/SessionComposer-thinkingMode.test.tsx +176 -0
  257. package/src/conversation/ConversationComposer.tsx +38 -4
  258. package/src/conversation/ConversationTemplatePickerDialog.tsx +441 -0
  259. package/src/conversation/ConversationsWorkbench.tsx +40 -4
  260. package/src/conversation/__tests__/ConversationComposer.test.tsx +56 -1
  261. package/src/conversation/__tests__/ConversationTemplatePickerDialog.test.tsx +224 -0
  262. package/src/conversation/__tests__/useConversationParticipation.test.tsx +45 -4
  263. package/src/conversation/index.ts +4 -0
  264. package/src/conversation/useConversationParticipation.ts +58 -6
  265. package/src/cursor-accounts/CursorAccountsConsole.tsx +40 -5
  266. package/src/cursor-accounts/__tests__/CursorAccountsConsole.test.tsx +32 -0
  267. package/src/cursor-accounts/__tests__/cursor-account-coverage.test.ts +58 -1
  268. package/src/cursor-accounts/cursor-account-coverage.ts +55 -0
  269. package/src/execution/useCreateAgentExecution.ts +19 -0
  270. package/src/identity-account/AccountPreferencesPanel.tsx +532 -0
  271. package/src/identity-account/__tests__/AccountPreferencesPanel.test.tsx +267 -0
  272. package/src/identity-account/__tests__/useAccountExecutionDefaults.test.tsx +116 -0
  273. package/src/identity-account/__tests__/useMyIdentityAccount.test.tsx +121 -0
  274. package/src/identity-account/index.ts +11 -0
  275. package/src/identity-account/useAccountExecutionDefaults.ts +63 -0
  276. package/src/identity-account/useMyIdentityAccount.ts +75 -0
  277. package/src/identity-account/useUpdateIdentityAccount.ts +73 -0
  278. package/src/identity-provider/IdentityProviderDetailPanel.tsx +18 -15
  279. package/src/identity-provider/__tests__/IdentityProviderDetailPanel.test.tsx +80 -0
  280. package/src/index.ts +26 -4
  281. package/src/internal/StandingContextField.tsx +92 -0
  282. package/src/library/InstanceVisibilitySelector.tsx +9 -2
  283. package/src/library/ResourceVisibilityControl.tsx +46 -13
  284. package/src/library/VisibilityOptionRow.tsx +28 -6
  285. package/src/library/VisibilitySelector.tsx +14 -2
  286. package/src/library/__tests__/VisibilitySelector.test.tsx +48 -1
  287. package/src/library/__tests__/visibilityLevels.test.ts +67 -1
  288. package/src/library/index.ts +6 -1
  289. package/src/library/useCanSetPublicVisibility.ts +56 -0
  290. package/src/library/visibilityLevels.ts +65 -14
  291. package/src/mcp-server/McpServerDetailView.tsx +2 -2
  292. package/src/mcp-server/__tests__/useMcpServerConnect.asyncLane.test.tsx +117 -0
  293. package/src/mcp-server/index.ts +0 -2
  294. package/src/mcp-server/internal/definitionDrift.ts +22 -20
  295. package/src/mcp-server/useMcpServerConnect.ts +9 -6
  296. package/src/mcp-server/useMcpServerOAuthConnect.ts +7 -2
  297. package/src/mcp-server/useUpdateMcpServer.ts +3 -3
  298. package/src/models/ModelSelector.tsx +94 -1
  299. package/src/models/index.ts +2 -0
  300. package/src/models/registry.ts +29 -0
  301. package/src/models/thinking-mode.ts +48 -0
  302. package/src/oauth-app/CreateOAuthAppForm.tsx +58 -3
  303. package/src/oauth-app/OAuthAppDetailPanel.tsx +103 -20
  304. package/src/oauth-app/__tests__/OAuthAppDetailPanel.test.tsx +94 -0
  305. package/src/organization/OrgPreferencesPanel.tsx +221 -0
  306. package/src/organization/OrgProfilePanel.tsx +5 -4
  307. package/src/organization/__tests__/OrgPreferencesPanel.test.tsx +145 -0
  308. package/src/organization/__tests__/OrgProfilePanel.test.tsx +108 -0
  309. package/src/organization/index.ts +2 -0
  310. package/src/platform-client/PlatformClientDetailPanel.tsx +14 -13
  311. package/src/platform-client/__tests__/PlatformClientDetailPanel.test.tsx +82 -0
  312. package/src/schedule/ScheduleDetailView.tsx +29 -4
  313. package/src/schedule/ScheduleForm.tsx +14 -1
  314. package/src/session/NewSessionViewer.tsx +12 -0
  315. package/src/session/__tests__/useNewSessionFlow.test.tsx +151 -0
  316. package/src/session/run-config.ts +16 -0
  317. package/src/session/useNewSessionFlow.ts +82 -9
  318. package/src/session/useSessionConversation.ts +32 -40
  319. package/src/session/useSessionPageFlow.ts +14 -11
  320. package/src/session/useUpdateSession.ts +18 -24
  321. package/src/settings/AccountPreferencesSection.tsx +25 -0
  322. package/src/settings/OrgPreferencesSection.tsx +35 -0
  323. package/src/settings/__tests__/settings-nav.test.ts +27 -0
  324. package/src/settings/index.ts +2 -0
  325. package/src/settings/settings-nav.ts +18 -0
  326. package/src/workflow/ApprovalFormBuilder.tsx +20 -27
  327. package/src/workflow/WorkflowDetailView.tsx +2 -2
  328. package/src/workflow/__tests__/WorkflowInstanceDetailPanel.test.tsx +83 -0
  329. package/src/workflow/index.ts +0 -2
  330. package/src/workflow/instance/WorkflowInstanceDetailPanel.tsx +6 -7
  331. package/src/workflow/useUpdateWorkflow.ts +3 -3
  332. package/styles.css +1 -1
  333. package/workflow/ApprovalFormBuilder.d.ts.map +1 -1
  334. package/workflow/ApprovalFormBuilder.js +10 -5
  335. package/workflow/ApprovalFormBuilder.js.map +1 -1
  336. package/workflow/WorkflowDetailView.js +2 -2
  337. package/workflow/WorkflowDetailView.js.map +1 -1
  338. package/workflow/index.d.ts +0 -1
  339. package/workflow/index.d.ts.map +1 -1
  340. package/workflow/index.js +0 -1
  341. package/workflow/index.js.map +1 -1
  342. package/workflow/instance/WorkflowInstanceDetailPanel.d.ts.map +1 -1
  343. package/workflow/instance/WorkflowInstanceDetailPanel.js +6 -7
  344. package/workflow/instance/WorkflowInstanceDetailPanel.js.map +1 -1
  345. package/workflow/useUpdateWorkflow.d.ts +3 -3
  346. package/workflow/useUpdateWorkflow.js +3 -3
  347. package/agent/internal/agentToInput.d.ts +0 -15
  348. package/agent/internal/agentToInput.d.ts.map +0 -1
  349. package/agent/internal/agentToInput.js +0 -84
  350. package/agent/internal/agentToInput.js.map +0 -1
  351. package/mcp-server/internal/mcpServerToInput.d.ts +0 -12
  352. package/mcp-server/internal/mcpServerToInput.d.ts.map +0 -1
  353. package/mcp-server/internal/mcpServerToInput.js +0 -84
  354. package/mcp-server/internal/mcpServerToInput.js.map +0 -1
  355. package/session/session-spec-converters.d.ts +0 -24
  356. package/session/session-spec-converters.d.ts.map +0 -1
  357. package/session/session-spec-converters.js +0 -72
  358. package/session/session-spec-converters.js.map +0 -1
  359. package/src/agent/internal/__tests__/agentToInput.test.ts +0 -145
  360. package/src/agent/internal/agentToInput.ts +0 -102
  361. package/src/mcp-server/__tests__/mcpServerToInput.test.ts +0 -201
  362. package/src/mcp-server/internal/mcpServerToInput.ts +0 -98
  363. package/src/session/__tests__/session-spec-converters.test.ts +0 -183
  364. package/src/session/session-spec-converters.ts +0 -86
  365. package/src/workflow/internal/workflowToInput.ts +0 -96
  366. package/workflow/internal/workflowToInput.d.ts +0 -12
  367. package/workflow/internal/workflowToInput.d.ts.map +0 -1
  368. package/workflow/internal/workflowToInput.js +0 -73
  369. package/workflow/internal/workflowToInput.js.map +0 -1
@@ -37,7 +37,7 @@ import {
37
37
  type RunConfig,
38
38
  } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/invocation_pb";
39
39
  import { Harness } from "@stigmer/protos/ai/stigmer/agentic/session/v1/enum_pb";
40
- import { ServiceTier } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
40
+ import { ServiceTier, ThinkingMode } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
41
41
  import type { WorkspaceEntry } from "@stigmer/protos/ai/stigmer/agentic/session/v1/workspace_pb";
42
42
  import {
43
43
  cadenceToCron,
@@ -60,6 +60,11 @@ import {
60
60
  toProtoServiceTier,
61
61
  type ServiceTierOption,
62
62
  } from "../models/service-tier.js";
63
+ import {
64
+ fromProtoThinkingMode,
65
+ toProtoThinkingMode,
66
+ type ThinkingModeOption,
67
+ } from "../models/thinking-mode.js";
63
68
  import { deriveScheduleState, formatNextFire } from "./scheduleState.js";
64
69
  import {
65
70
  ScheduleRunsCompactList,
@@ -599,10 +604,10 @@ export function ScheduleDetailView({
599
604
  {editable && target ? (
600
605
  <EngineModelInlineEditor
601
606
  invocation={target}
602
- onSave={(harness, modelName, serviceTier) =>
607
+ onSave={(harness, modelName, serviceTier, thinkingMode) =>
603
608
  saveSpecField("engine-model", (s) => {
604
609
  if (s.target.case === "agent") {
605
- applyEngineModel(s.target.value, harness, modelName, serviceTier);
610
+ applyEngineModel(s.target.value, harness, modelName, serviceTier, thinkingMode);
606
611
  }
607
612
  })
608
613
  }
@@ -1016,6 +1021,7 @@ function EngineModelInlineEditor({
1016
1021
  harness: Harness,
1017
1022
  modelName: string,
1018
1023
  serviceTier: ServiceTierOption,
1024
+ thinkingMode: ThinkingModeOption,
1019
1025
  ) => Promise<boolean>;
1020
1026
  readonly isSaving: boolean;
1021
1027
  readonly error?: string;
@@ -1024,6 +1030,7 @@ function EngineModelInlineEditor({
1024
1030
  const [modelName, setModelName] = useState("");
1025
1031
  const [harness, setHarness] = useState<HarnessOption>("cursor");
1026
1032
  const [serviceTier, setServiceTier] = useState<ServiceTierOption>("standard");
1033
+ const [thinkingMode, setThinkingMode] = useState<ThinkingModeOption>("disabled");
1027
1034
 
1028
1035
  const startEdit = () => {
1029
1036
  setModelName(invocation.runConfig?.modelName ?? "");
@@ -1035,6 +1042,9 @@ function EngineModelInlineEditor({
1035
1042
  setServiceTier(
1036
1043
  fromProtoServiceTier(invocation.runConfig?.serviceTier) ?? "standard",
1037
1044
  );
1045
+ setThinkingMode(
1046
+ fromProtoThinkingMode(invocation.runConfig?.thinkingMode) ?? "disabled",
1047
+ );
1038
1048
  setIsEditing(true);
1039
1049
  };
1040
1050
 
@@ -1056,6 +1066,8 @@ function EngineModelInlineEditor({
1056
1066
  onHarnessChange={setHarness}
1057
1067
  serviceTier={serviceTier}
1058
1068
  onServiceTierChange={setServiceTier}
1069
+ thinkingMode={thinkingMode}
1070
+ onThinkingModeChange={setThinkingMode}
1059
1071
  placeholderLabel="Platform default"
1060
1072
  disabled={isSaving}
1061
1073
  />
@@ -1065,6 +1077,7 @@ function EngineModelInlineEditor({
1065
1077
  onClick={() => {
1066
1078
  setModelName("");
1067
1079
  setServiceTier("standard");
1080
+ setThinkingMode("disabled");
1068
1081
  }}
1069
1082
  disabled={isSaving}
1070
1083
  className="stg:rounded-md stg:px-2 stg:py-1 stg:text-[0.65rem] stg:text-muted-foreground stg:hover:text-foreground stg:focus-visible:outline-none stg:focus-visible:ring-2 stg:focus-visible:ring-ring stg:disabled:pointer-events-none stg:disabled:opacity-50"
@@ -1084,6 +1097,7 @@ function EngineModelInlineEditor({
1084
1097
  modelName !== "" ? toProtoHarness(harness) : Harness.UNSPECIFIED,
1085
1098
  modelName,
1086
1099
  serviceTier,
1100
+ thinkingMode,
1087
1101
  );
1088
1102
  if (ok) setIsEditing(false);
1089
1103
  }}
@@ -1169,14 +1183,17 @@ function applyEngineModel(
1169
1183
  harness: Harness,
1170
1184
  modelName: string,
1171
1185
  serviceTier: ServiceTierOption,
1186
+ thinkingMode: ThinkingModeOption,
1172
1187
  ): void {
1173
1188
  invocation.harness = harness;
1174
1189
  invocation.runConfig = normalizeRunConfig(
1175
1190
  modelName,
1176
1191
  invocation.runConfig?.maxCostUsd ?? 0,
1177
1192
  invocation.runConfig?.maxToolRounds ?? 0,
1178
- // The tier rides the model choice: no model, no tier (#357).
1193
+ // The variant attributes ride the model choice: no model, no tier and
1194
+ // no thinking (#357/#772).
1179
1195
  modelName.trim() !== "" ? serviceTier : "standard",
1196
+ modelName.trim() !== "" ? thinkingMode : "disabled",
1180
1197
  );
1181
1198
  }
1182
1199
 
@@ -1190,6 +1207,7 @@ function applyBudget(
1190
1207
  maxCostUsd ?? 0,
1191
1208
  invocation.runConfig?.maxToolRounds ?? 0,
1192
1209
  fromProtoServiceTier(invocation.runConfig?.serviceTier) ?? "standard",
1210
+ fromProtoThinkingMode(invocation.runConfig?.thinkingMode) ?? "disabled",
1193
1211
  );
1194
1212
  }
1195
1213
 
@@ -1198,12 +1216,14 @@ function normalizeRunConfig(
1198
1216
  maxCostUsd: number,
1199
1217
  maxToolRounds: number,
1200
1218
  serviceTier: ServiceTierOption,
1219
+ thinkingMode: ThinkingModeOption,
1201
1220
  ): RunConfig | undefined {
1202
1221
  const fields: {
1203
1222
  modelName?: string;
1204
1223
  maxCostUsd?: number;
1205
1224
  maxToolRounds?: number;
1206
1225
  serviceTier?: ServiceTier;
1226
+ thinkingMode?: ThinkingMode;
1207
1227
  } = {};
1208
1228
  if (modelName.trim() !== "") fields.modelName = modelName.trim();
1209
1229
  if (maxCostUsd > 0) fields.maxCostUsd = maxCostUsd;
@@ -1211,6 +1231,8 @@ function normalizeRunConfig(
1211
1231
  // Only an active fast choice is carried — an untouched tier stays
1212
1232
  // absent, preserving the unspecified-vs-explicit ledger distinction (#357).
1213
1233
  if (serviceTier === "fast") fields.serviceTier = toProtoServiceTier(serviceTier);
1234
+ // The tier's #772 twin: only an active enabled choice is carried.
1235
+ if (thinkingMode === "enabled") fields.thinkingMode = toProtoThinkingMode(thinkingMode);
1214
1236
 
1215
1237
  return Object.keys(fields).length > 0
1216
1238
  ? create(RunConfigSchema, fields)
@@ -1429,6 +1451,9 @@ function EngineModelSummary({
1429
1451
  if (invocation?.runConfig?.serviceTier === ServiceTier.FAST) {
1430
1452
  parts.push("Fast tier");
1431
1453
  }
1454
+ if (invocation?.runConfig?.thinkingMode === ThinkingMode.ENABLED) {
1455
+ parts.push("Thinking");
1456
+ }
1432
1457
  return <span className="stg:text-sm stg:text-foreground">{parts.join(" · ")}</span>;
1433
1458
  }
1434
1459
 
@@ -16,6 +16,7 @@ import { useGitHubConnection } from "../github/useGitHubConnection.js";
16
16
  import { ModelSelector } from "../models/ModelSelector.js";
17
17
  import { toProtoHarness, type HarnessOption } from "../models/harness.js";
18
18
  import { toProtoServiceTier, type ServiceTierOption } from "../models/service-tier.js";
19
+ import { toProtoThinkingMode, type ThinkingModeOption } from "../models/thinking-mode.js";
19
20
  import { Switch } from "../switch/Switch.js";
20
21
  import { useStigmerPortalContainer } from "../portal-container.js";
21
22
  import { useWorkspaceEntries } from "../workspace/useWorkspaceEntries.js";
@@ -116,6 +117,8 @@ export function ScheduleForm({
116
117
  // is picked. No model pinned = no tier pinned (fast requires a model,
117
118
  // and the form's reset button clears both).
118
119
  const [serviceTier, setServiceTier] = useState<ServiceTierOption>("standard");
120
+ // Thinking mode: the tier's #772 twin, capability-scoped the same way.
121
+ const [thinkingMode, setThinkingMode] = useState<ThinkingModeOption>("disabled");
119
122
 
120
123
  const [budgetUsd, setBudgetUsd] = useState("");
121
124
 
@@ -152,7 +155,7 @@ export function ScheduleForm({
152
155
  if (!canSubmit || !agentRef) return;
153
156
 
154
157
  clearError();
155
- const runConfig = buildRunConfig(modelName, budgetUsd, serviceTier);
158
+ const runConfig = buildRunConfig(modelName, budgetUsd, serviceTier, thinkingMode);
156
159
  try {
157
160
  const schedule = await create({
158
161
  name: trimmedName,
@@ -195,6 +198,7 @@ export function ScheduleForm({
195
198
  modelName,
196
199
  modelHarness,
197
200
  serviceTier,
201
+ thinkingMode,
198
202
  budgetUsd,
199
203
  workspace,
200
204
  onComplete,
@@ -362,6 +366,8 @@ export function ScheduleForm({
362
366
  onHarnessChange={setModelHarness}
363
367
  serviceTier={serviceTier}
364
368
  onServiceTierChange={setServiceTier}
369
+ thinkingMode={thinkingMode}
370
+ onThinkingModeChange={setThinkingMode}
365
371
  placeholderLabel="Platform default"
366
372
  disabled={isCreating}
367
373
  />
@@ -371,6 +377,7 @@ export function ScheduleForm({
371
377
  onClick={() => {
372
378
  setModelName("");
373
379
  setServiceTier("standard");
380
+ setThinkingMode("disabled");
374
381
  }}
375
382
  disabled={isCreating}
376
383
  className={cn(
@@ -514,6 +521,7 @@ function buildRunConfig(
514
521
  modelName: string,
515
522
  budgetUsd: string,
516
523
  serviceTier: ServiceTierOption,
524
+ thinkingMode: ThinkingModeOption,
517
525
  ): RunConfigInput | undefined {
518
526
  const model = modelName.trim();
519
527
  const cost = Number.parseFloat(budgetUsd);
@@ -528,6 +536,11 @@ function buildRunConfig(
528
536
  if (serviceTier === "fast" && model !== "") {
529
537
  config.serviceTier = toProtoServiceTier(serviceTier);
530
538
  }
539
+ // The tier's #772 twin: thinking is a per-model capability, same
540
+ // only-explicit-enabled + requires-a-model contract.
541
+ if (thinkingMode === "enabled" && model !== "") {
542
+ config.thinkingMode = toProtoThinkingMode(thinkingMode);
543
+ }
531
544
 
532
545
  return Object.keys(config).length > 0 ? config : undefined;
533
546
  }
@@ -9,6 +9,7 @@ import type { WorkspaceContentSearcher } from "../workspace/WorkspaceContentSear
9
9
  import type { InteractionModeOption } from "../composer/index.js";
10
10
  import { SessionComposer } from "../composer/index.js";
11
11
  import type { HarnessOption } from "../models/harness.js";
12
+ import type { AccountExecutionDefaults } from "../identity-account/useAccountExecutionDefaults.js";
12
13
  import { SessionViewerLayout } from "./SessionViewerLayout.js";
13
14
  import { useWorkspaceEditors } from "../internal/store/index.js";
14
15
  import { WorkspaceSurface } from "../workspace/WorkspaceSurface.js";
@@ -163,6 +164,15 @@ export interface NewSessionViewerProps {
163
164
  */
164
165
  readonly defaultHarness?: HarnessOption;
165
166
 
167
+ /**
168
+ * The user's account-level execution defaults, typically from
169
+ * `useAccountExecutionDefaults()`. Seeds the harness and model pickers
170
+ * under the layered precedence documented on
171
+ * {@link UseNewSessionFlowOptions.accountDefaults}; explicit device
172
+ * picks always win. Ignored for the `"guest"` audience.
173
+ */
174
+ readonly accountDefaults?: AccountExecutionDefaults;
175
+
166
176
  /** Agent to auto-select on mount (used for draft flows). */
167
177
  readonly initialAgentRef?: ResourceRef;
168
178
  /**
@@ -253,6 +263,7 @@ export function NewSessionViewer({
253
263
  panelOpen,
254
264
  onPanelOpenChange,
255
265
  defaultHarness,
266
+ accountDefaults,
256
267
  initialAgentRef,
257
268
  initialInstanceId,
258
269
  initialAttachments,
@@ -269,6 +280,7 @@ export function NewSessionViewer({
269
280
  onError,
270
281
  getRuntimeEnv,
271
282
  defaultHarness,
283
+ accountDefaults,
272
284
  audience,
273
285
  runConfig,
274
286
  });
@@ -805,6 +805,157 @@ describe("useNewSessionFlow", () => {
805
805
  });
806
806
  });
807
807
 
808
+ describe("accountDefaults (oss#293 Phase 1.5 layered seed)", () => {
809
+ // Two native models so "stored pick outranks account default" is
810
+ // distinguishable; the shared TEST_MODELS carries one per harness.
811
+ const SEED_MODELS = parseRegistryJson({
812
+ models: [
813
+ { id: "claude-sonnet-4.6", displayName: "Claude Sonnet 4.6", shortDescription: "", speedTier: "fast", provider: "anthropic", harness: "native", costTier: "standard", featured: true, pricing: { inputPricePerMillion: 3, outputPricePerMillion: 15, cacheWritePricePerMillion: 3.75, cacheReadPricePerMillion: 0.3 } },
814
+ { id: "gpt-5.3", displayName: "GPT 5.3", shortDescription: "", speedTier: "fast", provider: "openai", harness: "native", costTier: "standard", featured: false, pricing: { inputPricePerMillion: 2, outputPricePerMillion: 8, cacheWritePricePerMillion: 2, cacheReadPricePerMillion: 0.2 } },
815
+ { id: "default", displayName: "Cursor Auto", shortDescription: "", speedTier: "fast", provider: "cursor", harness: "cursor", costTier: "standard", featured: true, pricing: { inputPricePerMillion: 1.25, outputPricePerMillion: 6, cacheWritePricePerMillion: 1.25, cacheReadPricePerMillion: 0.25 } },
816
+ { id: "composer-2.5", displayName: "Composer 2.5", shortDescription: "", speedTier: "fast", provider: "cursor", harness: "cursor", costTier: "standard", featured: false, pricing: { inputPricePerMillion: 1, outputPricePerMillion: 5, cacheWritePricePerMillion: 1, cacheReadPricePerMillion: 0.1 } },
817
+ ],
818
+ });
819
+
820
+ function seedWrapper() {
821
+ const state: ModelRegistryState = { models: SEED_MODELS, isLoading: false, error: null, refetch: () => {} };
822
+ return function Wrapper({ children }: { children: ReactNode }) {
823
+ return (
824
+ <ModelRegistryContext.Provider value={state}>
825
+ {children}
826
+ </ModelRegistryContext.Provider>
827
+ );
828
+ };
829
+ }
830
+
831
+ it("seeds the harness when nothing is stored", () => {
832
+ const opts = { ...defaultOptions(), accountDefaults: { harness: "cursor" as const } };
833
+ const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
834
+
835
+ expect(result.current.harness).toBe("cursor");
836
+ });
837
+
838
+ it("a stored harness choice outranks the account default", () => {
839
+ localStorage.setItem(STORAGE_KEY_HARNESS, "native");
840
+ const opts = { ...defaultOptions(), accountDefaults: { harness: "cursor" as const } };
841
+ const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
842
+
843
+ expect(result.current.harness).toBe("native");
844
+ });
845
+
846
+ it("the account harness outranks the embedder defaultHarness", () => {
847
+ const opts = {
848
+ ...defaultOptions(),
849
+ defaultHarness: "native" as const,
850
+ accountDefaults: { harness: "cursor" as const },
851
+ };
852
+ const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
853
+
854
+ expect(result.current.harness).toBe("cursor");
855
+ });
856
+
857
+ it("never persists the seeded harness — only explicit choices", () => {
858
+ const opts = { ...defaultOptions(), accountDefaults: { harness: "cursor" as const } };
859
+ renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
860
+
861
+ expect(localStorage.getItem(STORAGE_KEY_HARNESS)).toBeNull();
862
+ });
863
+
864
+ it("a late-arriving harness seed applies when the user has not picked (whoAmI resolves after mount)", () => {
865
+ const base: Parameters<typeof useNewSessionFlow>[0] = defaultOptions();
866
+ const { result, rerender } = renderHook(
867
+ (opts: Parameters<typeof useNewSessionFlow>[0]) => useNewSessionFlow(opts),
868
+ { wrapper: seedWrapper(), initialProps: base },
869
+ );
870
+ expect(result.current.harness).toBe("native");
871
+
872
+ rerender({ ...base, accountDefaults: { harness: "cursor" as const } });
873
+
874
+ expect(result.current.harness).toBe("cursor");
875
+ expect(localStorage.getItem(STORAGE_KEY_HARNESS)).toBeNull();
876
+ });
877
+
878
+ it("a late-arriving harness seed never overrides an explicit pick this mount", () => {
879
+ const base: Parameters<typeof useNewSessionFlow>[0] = defaultOptions();
880
+ const { result, rerender } = renderHook(
881
+ (opts: Parameters<typeof useNewSessionFlow>[0]) => useNewSessionFlow(opts),
882
+ { wrapper: seedWrapper(), initialProps: base },
883
+ );
884
+ act(() => result.current.setHarness("native"));
885
+
886
+ rerender({ ...base, accountDefaults: { harness: "cursor" as const } });
887
+
888
+ expect(result.current.harness).toBe("native");
889
+ });
890
+
891
+ it("seeds the model for the active harness when nothing is stored", () => {
892
+ const opts = { ...defaultOptions(), accountDefaults: { nativeModel: "gpt-5.3" } };
893
+ const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
894
+
895
+ expect(result.current.modelId).toBe("gpt-5.3");
896
+ });
897
+
898
+ it("a stored model pick outranks the account default", async () => {
899
+ localStorage.setItem(STORAGE_KEY_MODEL_NATIVE, "claude-sonnet-4.6");
900
+ const opts = { ...defaultOptions(), accountDefaults: { nativeModel: "gpt-5.3" } };
901
+ const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
902
+
903
+ // The stored restore lands in a passive effect once the registry is
904
+ // ready; the account seed must not win the race before it.
905
+ await act(async () => {});
906
+ expect(result.current.modelId).toBe("claude-sonnet-4.6");
907
+ });
908
+
909
+ it("self-heals a stale account model to the platform default (undefined)", () => {
910
+ const opts = { ...defaultOptions(), accountDefaults: { nativeModel: "retired-model" } };
911
+ const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
912
+
913
+ expect(result.current.modelId).toBeUndefined();
914
+ });
915
+
916
+ it("never persists the seeded model — only explicit choices", () => {
917
+ const opts = { ...defaultOptions(), accountDefaults: { nativeModel: "gpt-5.3" } };
918
+ renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
919
+
920
+ expect(localStorage.getItem(STORAGE_KEY_MODEL_NATIVE)).toBeNull();
921
+ });
922
+
923
+ it("follows the active harness: cursorModel seeds cursor sessions", () => {
924
+ const opts = {
925
+ ...defaultOptions(),
926
+ accountDefaults: { harness: "cursor" as const, nativeModel: "gpt-5.3", cursorModel: "composer-2.5" },
927
+ };
928
+ const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
929
+
930
+ expect(result.current.harness).toBe("cursor");
931
+ expect(result.current.modelId).toBe("composer-2.5");
932
+ });
933
+
934
+ it("submits the seeded model explicitly — the pill promise (#663) and the DD-003 seed rule", async () => {
935
+ const opts = { ...defaultOptions(), accountDefaults: { nativeModel: "gpt-5.3" } };
936
+ const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
937
+
938
+ await act(async () => {
939
+ await result.current.submit("Hello");
940
+ });
941
+
942
+ expect(mockCreateExecution.mock.calls[0][0].modelName).toBe("gpt-5.3");
943
+ });
944
+
945
+ it("guest audience ignores accountDefaults entirely", () => {
946
+ const opts = {
947
+ ...defaultOptions(),
948
+ audience: "guest" as const,
949
+ accountDefaults: { harness: "native" as const, nativeModel: "gpt-5.3", cursorModel: "composer-2.5" },
950
+ };
951
+ const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
952
+
953
+ // Platform share policy: cursor harness, no client model.
954
+ expect(result.current.harness).toBe("cursor");
955
+ expect(result.current.modelId).toBeUndefined();
956
+ });
957
+ });
958
+
808
959
  describe("submit while default agent is loading", () => {
809
960
  it("awaits default agent and creates session when fetch resolves", async () => {
810
961
  const resolvedAgent = { status: { defaultInstanceId: "awaited-inst" } };
@@ -1,4 +1,5 @@
1
1
  import type { ServiceTierOption } from "../models/service-tier.js";
2
+ import type { ThinkingModeOption } from "../models/thinking-mode.js";
2
3
 
3
4
  /**
4
5
  * Owner-pinned execution config for a session surface
@@ -39,6 +40,14 @@ export interface SessionRunConfig {
39
40
  * pin is a host configuration error and throws at submit.
40
41
  */
41
42
  readonly serviceTier?: ServiceTierOption;
43
+ /**
44
+ * Thinking mode for every execution (stigmer/stigmer#772).
45
+ * `"enabled"` requires {@link modelName} under the same contract as
46
+ * {@link serviceTier}: thinking is a per-model capability (the server
47
+ * refuses it fail-closed for Auto), so a mode pin without a model pin
48
+ * is a host configuration error and throws at submit.
49
+ */
50
+ readonly thinkingMode?: ThinkingModeOption;
42
51
  }
43
52
 
44
53
  /**
@@ -56,4 +65,11 @@ export function assertValidRunConfig(runConfig: SessionRunConfig): void {
56
65
  + "dimension. Pin the model the surface should run.",
57
66
  );
58
67
  }
68
+ if (runConfig.thinkingMode === "enabled" && !runConfig.modelName) {
69
+ throw new Error(
70
+ "SessionRunConfig: thinkingMode \"enabled\" requires modelName — "
71
+ + "thinking is a per-model capability and Auto (no pinned model) has "
72
+ + "no variant dimensions. Pin the model the surface should run.",
73
+ );
74
+ }
59
75
  }
@@ -1,7 +1,8 @@
1
1
  "use client";
2
2
 
3
- import { useCallback, useEffect, useState } from "react";
3
+ import { useCallback, useEffect, useRef, useState } from "react";
4
4
  import { getUserMessage, type McpServerUsageInput, type ResourceRef } from "@stigmer/sdk";
5
+ import type { AccountExecutionDefaults } from "../identity-account/useAccountExecutionDefaults.js";
5
6
  import type { AgentResolution } from "../agent/index.js";
6
7
  import { useDefaultAgent } from "../agent/index.js";
7
8
  import { useModelRegistry } from "../models/index.js";
@@ -102,6 +103,26 @@ export interface UseNewSessionFlowOptions {
102
103
  * @default DEFAULT_HARNESS ("native")
103
104
  */
104
105
  readonly defaultHarness?: HarnessOption;
106
+ /**
107
+ * The user's account-level execution defaults
108
+ * (`IdentityAccountPreferences.default_*`), typically from
109
+ * `useAccountExecutionDefaults()`. A SEED in the layered precedence —
110
+ * explicit device-local choices always outrank it:
111
+ *
112
+ * - harness: stored choice > `accountDefaults.harness` >
113
+ * {@link defaultHarness} > platform default. May arrive after mount
114
+ * (whoAmI resolves async); a late value still seeds unless the user
115
+ * has already picked a harness this mount.
116
+ * - model: stored per-harness choice > the account's model for the
117
+ * active harness (validated against the registry; a stale model
118
+ * silently falls through) > the harness default.
119
+ *
120
+ * Seeded values are never persisted to localStorage — the account
121
+ * preference keeps applying until the user decides. Ignored for the
122
+ * `"guest"` audience (platform share policy owns guest config), and
123
+ * consumers must not fetch identity for guest/embed surfaces.
124
+ */
125
+ readonly accountDefaults?: AccountExecutionDefaults;
105
126
  /**
106
127
  * Who this flow serves. `"guest"` adapts the orchestration to the
107
128
  * guest principal's permission model: the org default-agent lookup
@@ -162,7 +183,12 @@ export interface UseNewSessionFlowReturn {
162
183
  /** Switch the harness. Resets the model if invalid for the new harness. */
163
184
  readonly setHarness: (harness: HarnessOption) => void;
164
185
 
165
- /** Currently selected model ID (persisted per-harness to localStorage). */
186
+ /**
187
+ * The model an untouched send will run: the explicit device pick when
188
+ * one exists (persisted per-harness to localStorage), else the account
189
+ * default for the active harness. `undefined` resolves to the harness
190
+ * default downstream.
191
+ */
166
192
  readonly modelId: string | undefined;
167
193
  /** Update the selected model. Automatically persists to localStorage. */
168
194
  readonly setModelId: (id: string) => void;
@@ -269,6 +295,10 @@ export function useNewSessionFlow(
269
295
  sessionContext,
270
296
  } = options;
271
297
  const isGuest = options.audience === "guest";
298
+ // Guests never inherit account defaults — the platform share policy owns
299
+ // guest execution config (GUEST_HARNESS reasoning), and identity-derived
300
+ // preferences must never shape a share/embed surface.
301
+ const accountDefaults = isGuest ? undefined : options.accountDefaults;
272
302
  // Guests never carry a client pin: guest execution config is owned by
273
303
  // the server-side share policy (GUEST_HARNESS reasoning). Validated at
274
304
  // render so a statically-wrong pin (fast tier, no model) fails in the
@@ -277,6 +307,7 @@ export function useNewSessionFlow(
277
307
  if (runConfig) assertValidRunConfig(runConfig);
278
308
  const pinnedModelName = runConfig?.modelName;
279
309
  const pinnedServiceTier = runConfig?.serviceTier;
310
+ const pinnedThinkingMode = runConfig?.thinkingMode;
280
311
  const contextTarget = useExecutionTarget();
281
312
  const executionTarget = options.executionTarget ?? contextTarget;
282
313
  const adapter = useRunnerAdapter();
@@ -293,13 +324,30 @@ export function useNewSessionFlow(
293
324
  // touch localStorage: a browser previously used in the Console must not
294
325
  // leak its stored harness into a share/embed session.
295
326
  if (isGuest) return GUEST_HARNESS;
296
- if (typeof window === "undefined") return defaultHarness ?? DEFAULT_HARNESS;
327
+ if (typeof window === "undefined")
328
+ return accountDefaults?.harness ?? defaultHarness ?? DEFAULT_HARNESS;
297
329
  // Only explicit user choices are persisted (see setHarness), so a
298
- // stored value always outranks the embedder's defaultHarness.
330
+ // stored value always outranks the account default and the embedder's
331
+ // defaultHarness.
299
332
  const stored = localStorage.getItem(STORAGE_KEY_HARNESS);
300
333
  if (stored === "native" || stored === "cursor") return stored;
301
- return defaultHarness ?? DEFAULT_HARNESS;
334
+ return accountDefaults?.harness ?? defaultHarness ?? DEFAULT_HARNESS;
302
335
  });
336
+ // Set once the user picks a harness this mount — a late-arriving account
337
+ // default must never override an explicit choice (the composer's
338
+ // userOverrodeModel idiom).
339
+ const harnessTouchedRef = useRef(false);
340
+
341
+ // Account defaults resolve async (whoAmI): when the harness seed arrives
342
+ // after mount, apply it once — unless the user has picked or a stored
343
+ // choice exists. Never persisted: seeding must not masquerade as a user
344
+ // choice, or the account preference would stop applying elsewhere.
345
+ useEffect(() => {
346
+ const seed = accountDefaults?.harness;
347
+ if (isGuest || harnessTouchedRef.current || !seed) return;
348
+ if (typeof window !== "undefined" && localStorage.getItem(STORAGE_KEY_HARNESS)) return;
349
+ setHarnessRaw(seed);
350
+ }, [isGuest, accountDefaults?.harness]);
303
351
 
304
352
  const stigmer = useStigmer();
305
353
  const { getModel, isLoading: isModelsLoading } = useModelRegistry({ harness });
@@ -326,8 +374,26 @@ export function useNewSessionFlow(
326
374
 
327
375
  const validModelId = modelId && getModel(modelId) ? modelId : undefined;
328
376
 
377
+ // The account's model for the active harness, registry-validated the same
378
+ // way as the stored choice (a stale/removed preference silently falls
379
+ // through to the harness default — self-healing). Derived, never written
380
+ // into `modelId` state: the persist effect below stores only explicit
381
+ // choices, and a derived seed cannot leak into localStorage.
382
+ const accountModelForHarness =
383
+ harness === "cursor" ? accountDefaults?.cursorModel : accountDefaults?.nativeModel;
384
+ const accountModelId =
385
+ accountModelForHarness && getModel(accountModelForHarness)
386
+ ? accountModelForHarness
387
+ : undefined;
388
+
389
+ // Layered precedence: explicit device pick > account default. The result
390
+ // feeds the composer's model pill AND the submit path, so the pill always
391
+ // shows what an untouched send will run (#663).
392
+ const effectiveModelId = validModelId ?? accountModelId;
393
+
329
394
  const setHarness = useCallback(
330
395
  (h: HarnessOption) => {
396
+ harnessTouchedRef.current = true;
331
397
  setHarnessRaw(h);
332
398
  // Guests have no harness picker; if a caller invokes this anyway, the
333
399
  // guest surface must never write into the Console's preference keys.
@@ -415,14 +481,20 @@ export function useNewSessionFlow(
415
481
  // The owner pin wins over the composer and the restored
416
482
  // preference (#664); the pinned tier is stamped only as
417
483
  // "fast" — standard stays off the wire, preserving the #357
418
- // UNSPECIFIED-vs-explicit telemetry distinction.
419
- modelName: pinnedModelName ?? selectedModel ?? validModelId,
484
+ // UNSPECIFIED-vs-explicit telemetry distinction. The effective
485
+ // model carries the account-default seed explicitly (DD-003:
486
+ // the preference is a seed; the execution spec is the record).
487
+ modelName: pinnedModelName ?? selectedModel ?? effectiveModelId,
420
488
  runtimeEnv,
421
489
  attachments: context?.attachments,
422
490
  interactionMode: context?.interactionMode,
423
491
  serviceTier: pinnedModelName
424
492
  ? (pinnedServiceTier === "fast" ? "fast" : undefined)
425
493
  : context?.serviceTier,
494
+ // The tier's #772 twin, same pin-wins + only-explicit-enabled rule.
495
+ thinkingMode: pinnedModelName
496
+ ? (pinnedThinkingMode === "enabled" ? "enabled" : undefined)
497
+ : context?.thinkingMode,
426
498
  workspaceFileRefs: context?.workspaceFileRefs,
427
499
  autoApproveAll,
428
500
  };
@@ -514,9 +586,10 @@ export function useNewSessionFlow(
514
586
  autoApproveAll,
515
587
  adapter,
516
588
  getRuntimeEnv,
517
- validModelId,
589
+ effectiveModelId,
518
590
  pinnedModelName,
519
591
  pinnedServiceTier,
592
+ pinnedThinkingMode,
520
593
  workspace,
521
594
  mcpServerUsages,
522
595
  skillRefs,
@@ -539,7 +612,7 @@ export function useNewSessionFlow(
539
612
  return {
540
613
  harness,
541
614
  setHarness,
542
- modelId: validModelId,
615
+ modelId: effectiveModelId,
543
616
  setModelId,
544
617
  agentRef,
545
618
  setAgentRef,