@xenosystem/agent-interface-ui 0.1.24 → 0.1.26

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 (380) hide show
  1. package/dist/adapters/agentHostPlatformBridge.d.ts.map +1 -1
  2. package/dist/adapters/agentHostPlatformBridge.js +96 -16
  3. package/dist/adapters/agentHostPlatformBridge.js.map +1 -1
  4. package/dist/adapters/hubAgentPlatformBridge.d.ts.map +1 -1
  5. package/dist/adapters/hubAgentPlatformBridge.js +2 -0
  6. package/dist/adapters/hubAgentPlatformBridge.js.map +1 -1
  7. package/dist/adapters/scopedBackupBridge.d.ts +4 -0
  8. package/dist/adapters/scopedBackupBridge.d.ts.map +1 -0
  9. package/dist/adapters/scopedBackupBridge.js +49 -0
  10. package/dist/adapters/scopedBackupBridge.js.map +1 -0
  11. package/dist/adapters/xenoAgentCompatibilityBridge.d.ts.map +1 -1
  12. package/dist/adapters/xenoAgentCompatibilityBridge.js +9 -1
  13. package/dist/adapters/xenoAgentCompatibilityBridge.js.map +1 -1
  14. package/dist/agent.css +13227 -0
  15. package/dist/components/agent/AgentIdentityGenerator.d.ts +16 -0
  16. package/dist/components/agent/AgentIdentityGenerator.d.ts.map +1 -0
  17. package/dist/components/agent/AgentIdentityGenerator.js +80 -0
  18. package/dist/components/agent/AgentIdentityGenerator.js.map +1 -0
  19. package/dist/components/agent/AgentInterface.d.ts +1 -0
  20. package/dist/components/agent/AgentInterface.d.ts.map +1 -1
  21. package/dist/components/agent/AgentInterface.js +1816 -643
  22. package/dist/components/agent/AgentInterface.js.map +1 -1
  23. package/dist/components/agent/AgentNotificationBanner.d.ts +10 -0
  24. package/dist/components/agent/AgentNotificationBanner.d.ts.map +1 -0
  25. package/dist/components/agent/AgentNotificationBanner.js +28 -0
  26. package/dist/components/agent/AgentNotificationBanner.js.map +1 -0
  27. package/dist/components/agent/AgentOnboarding.d.ts +16 -2
  28. package/dist/components/agent/AgentOnboarding.d.ts.map +1 -1
  29. package/dist/components/agent/AgentOnboarding.js +93 -201
  30. package/dist/components/agent/AgentOnboarding.js.map +1 -1
  31. package/dist/components/agent/AgentView.d.ts.map +1 -1
  32. package/dist/components/agent/AgentView.js +533 -308
  33. package/dist/components/agent/AgentView.js.map +1 -1
  34. package/dist/components/agent/AgentWorkbenchPanel.d.ts +3 -1
  35. package/dist/components/agent/AgentWorkbenchPanel.d.ts.map +1 -1
  36. package/dist/components/agent/AgentWorkbenchPanel.js +3 -2
  37. package/dist/components/agent/AgentWorkbenchPanel.js.map +1 -1
  38. package/dist/components/agent/AgentWorkspaceBrowserPanel.d.ts +4 -1
  39. package/dist/components/agent/AgentWorkspaceBrowserPanel.d.ts.map +1 -1
  40. package/dist/components/agent/AgentWorkspaceBrowserPanel.js +23 -195
  41. package/dist/components/agent/AgentWorkspaceBrowserPanel.js.map +1 -1
  42. package/dist/components/agent/AgentsWorkspaceView.d.ts +12 -0
  43. package/dist/components/agent/AgentsWorkspaceView.d.ts.map +1 -0
  44. package/dist/components/agent/AgentsWorkspaceView.js +129 -0
  45. package/dist/components/agent/AgentsWorkspaceView.js.map +1 -0
  46. package/dist/components/agent/DevelopmentCoordinationPanel.d.ts +7 -0
  47. package/dist/components/agent/DevelopmentCoordinationPanel.d.ts.map +1 -1
  48. package/dist/components/agent/DevelopmentCoordinationPanel.js +57 -49
  49. package/dist/components/agent/DevelopmentCoordinationPanel.js.map +1 -1
  50. package/dist/components/agent/KnowledgePanel.d.ts.map +1 -1
  51. package/dist/components/agent/KnowledgePanel.js +17 -67
  52. package/dist/components/agent/KnowledgePanel.js.map +1 -1
  53. package/dist/components/agent/LiveConversationCollaboration.d.ts +27 -0
  54. package/dist/components/agent/LiveConversationCollaboration.d.ts.map +1 -0
  55. package/dist/components/agent/LiveConversationCollaboration.js +127 -0
  56. package/dist/components/agent/LiveConversationCollaboration.js.map +1 -0
  57. package/dist/components/agent/MonacoDiffWorkbenchEditor.d.ts.map +1 -1
  58. package/dist/components/agent/MonacoDiffWorkbenchEditor.js +1 -1
  59. package/dist/components/agent/MonacoDiffWorkbenchEditor.js.map +1 -1
  60. package/dist/components/agent/MonacoWorkbenchEditor.d.ts.map +1 -1
  61. package/dist/components/agent/MonacoWorkbenchEditor.js +3 -3
  62. package/dist/components/agent/MonacoWorkbenchEditor.js.map +1 -1
  63. package/dist/components/agent/OwnedBrowserController.d.ts +55 -0
  64. package/dist/components/agent/OwnedBrowserController.d.ts.map +1 -0
  65. package/dist/components/agent/OwnedBrowserController.js +166 -0
  66. package/dist/components/agent/OwnedBrowserController.js.map +1 -0
  67. package/dist/components/agent/OwnedWorkforceView.d.ts +10 -0
  68. package/dist/components/agent/OwnedWorkforceView.d.ts.map +1 -0
  69. package/dist/components/agent/OwnedWorkforceView.js +256 -0
  70. package/dist/components/agent/OwnedWorkforceView.js.map +1 -0
  71. package/dist/components/agent/PluginManager.d.ts +34 -0
  72. package/dist/components/agent/PluginManager.d.ts.map +1 -1
  73. package/dist/components/agent/PluginManager.js +187 -126
  74. package/dist/components/agent/PluginManager.js.map +1 -1
  75. package/dist/components/agent/ProjectsWorkspaceView.d.ts +14 -0
  76. package/dist/components/agent/ProjectsWorkspaceView.d.ts.map +1 -0
  77. package/dist/components/agent/ProjectsWorkspaceView.js +176 -0
  78. package/dist/components/agent/ProjectsWorkspaceView.js.map +1 -0
  79. package/dist/components/agent/RunReviewPanel.d.ts +8 -13
  80. package/dist/components/agent/RunReviewPanel.d.ts.map +1 -1
  81. package/dist/components/agent/RunReviewPanel.js +120 -106
  82. package/dist/components/agent/RunReviewPanel.js.map +1 -1
  83. package/dist/components/agent/ScheduledWorkspaceView.d.ts +19 -0
  84. package/dist/components/agent/ScheduledWorkspaceView.d.ts.map +1 -0
  85. package/dist/components/agent/ScheduledWorkspaceView.js +150 -0
  86. package/dist/components/agent/ScheduledWorkspaceView.js.map +1 -0
  87. package/dist/components/agent/SdkSessionPanel.d.ts +25 -0
  88. package/dist/components/agent/SdkSessionPanel.d.ts.map +1 -0
  89. package/dist/components/agent/SdkSessionPanel.js +15 -0
  90. package/dist/components/agent/SdkSessionPanel.js.map +1 -0
  91. package/dist/components/agent/SlashCommandAutocomplete.d.ts +12 -0
  92. package/dist/components/agent/SlashCommandAutocomplete.d.ts.map +1 -0
  93. package/dist/components/agent/SlashCommandAutocomplete.js +33 -0
  94. package/dist/components/agent/SlashCommandAutocomplete.js.map +1 -0
  95. package/dist/components/agent/TeamsWorkspaceView.d.ts +12 -0
  96. package/dist/components/agent/TeamsWorkspaceView.d.ts.map +1 -0
  97. package/dist/components/agent/TeamsWorkspaceView.js +127 -0
  98. package/dist/components/agent/TeamsWorkspaceView.js.map +1 -0
  99. package/dist/components/agent/WorkspacePersistenceNotice.d.ts +3 -0
  100. package/dist/components/agent/WorkspacePersistenceNotice.d.ts.map +1 -0
  101. package/dist/components/agent/WorkspacePersistenceNotice.js +23 -0
  102. package/dist/components/agent/WorkspacePersistenceNotice.js.map +1 -0
  103. package/dist/components/agent/acp/AcpAgentConfigForm.d.ts +1 -0
  104. package/dist/components/agent/acp/AcpAgentConfigForm.d.ts.map +1 -1
  105. package/dist/components/agent/acp/AcpAgentConfigForm.js +47 -14
  106. package/dist/components/agent/acp/AcpAgentConfigForm.js.map +1 -1
  107. package/dist/components/agent/acp/AcpAgentDiagnosticsPanel.js +1 -1
  108. package/dist/components/agent/acp/AcpAgentDiagnosticsPanel.js.map +1 -1
  109. package/dist/components/agent/acp/AcpAgentManager.d.ts.map +1 -1
  110. package/dist/components/agent/acp/AcpAgentManager.js +18 -18
  111. package/dist/components/agent/acp/AcpAgentManager.js.map +1 -1
  112. package/dist/components/agent/acp/AcpAgentTestResultPanel.js +1 -1
  113. package/dist/components/agent/acp/AcpAgentTestResultPanel.js.map +1 -1
  114. package/dist/components/agent/acp/AcpApprovalPanel.js +2 -2
  115. package/dist/components/agent/acp/AcpApprovalPanel.js.map +1 -1
  116. package/dist/components/agent/acp/AcpCertificationPanel.js +1 -1
  117. package/dist/components/agent/acp/AcpCertificationPanel.js.map +1 -1
  118. package/dist/components/agent/acp/AcpLiveProviderWorkflowPanel.js +1 -1
  119. package/dist/components/agent/acp/AcpLiveProviderWorkflowPanel.js.map +1 -1
  120. package/dist/components/agent/acp/AcpProviderManagerPanel.js +1 -1
  121. package/dist/components/agent/acp/AcpProviderManagerPanel.js.map +1 -1
  122. package/dist/components/agent/acp/AcpProviderModelsPanel.js +1 -1
  123. package/dist/components/agent/acp/AcpProviderModelsPanel.js.map +1 -1
  124. package/dist/components/agent/acp/AcpSupportBundlePanel.js +1 -1
  125. package/dist/components/agent/acp/AcpSupportBundlePanel.js.map +1 -1
  126. package/dist/components/agent/collaborationWindow.d.ts +11 -0
  127. package/dist/components/agent/collaborationWindow.d.ts.map +1 -0
  128. package/dist/components/agent/collaborationWindow.js +10 -0
  129. package/dist/components/agent/collaborationWindow.js.map +1 -0
  130. package/dist/components/agent/conversationCollaborationAppendJournal.d.ts +25 -0
  131. package/dist/components/agent/conversationCollaborationAppendJournal.d.ts.map +1 -0
  132. package/dist/components/agent/conversationCollaborationAppendJournal.js +118 -0
  133. package/dist/components/agent/conversationCollaborationAppendJournal.js.map +1 -0
  134. package/dist/components/agent/conversationCollaborationController.d.ts +96 -0
  135. package/dist/components/agent/conversationCollaborationController.d.ts.map +1 -0
  136. package/dist/components/agent/conversationCollaborationController.js +597 -0
  137. package/dist/components/agent/conversationCollaborationController.js.map +1 -0
  138. package/dist/components/agent/destructiveConfirmation.d.ts +76 -0
  139. package/dist/components/agent/destructiveConfirmation.d.ts.map +1 -0
  140. package/dist/components/agent/destructiveConfirmation.js +231 -0
  141. package/dist/components/agent/destructiveConfirmation.js.map +1 -0
  142. package/dist/components/agent/developmentCoordinationController.d.ts +43 -0
  143. package/dist/components/agent/developmentCoordinationController.d.ts.map +1 -0
  144. package/dist/components/agent/developmentCoordinationController.js +94 -0
  145. package/dist/components/agent/developmentCoordinationController.js.map +1 -0
  146. package/dist/components/agent/developmentCoordinationProjection.d.ts +24 -0
  147. package/dist/components/agent/developmentCoordinationProjection.d.ts.map +1 -1
  148. package/dist/components/agent/developmentCoordinationProjection.js +34 -5
  149. package/dist/components/agent/developmentCoordinationProjection.js.map +1 -1
  150. package/dist/components/agent/editorOperationAuthority.d.ts +29 -0
  151. package/dist/components/agent/editorOperationAuthority.d.ts.map +1 -0
  152. package/dist/components/agent/editorOperationAuthority.js +73 -0
  153. package/dist/components/agent/editorOperationAuthority.js.map +1 -0
  154. package/dist/components/agent/knowledgePagination.d.ts +7 -0
  155. package/dist/components/agent/knowledgePagination.d.ts.map +1 -0
  156. package/dist/components/agent/knowledgePagination.js +7 -0
  157. package/dist/components/agent/knowledgePagination.js.map +1 -0
  158. package/dist/components/agent/knowledgePanelController.d.ts +32 -0
  159. package/dist/components/agent/knowledgePanelController.d.ts.map +1 -0
  160. package/dist/components/agent/knowledgePanelController.js +119 -0
  161. package/dist/components/agent/knowledgePanelController.js.map +1 -0
  162. package/dist/components/agent/monacoWorkbenchShared.js +1 -1
  163. package/dist/components/agent/onboardingModels.d.ts +31 -0
  164. package/dist/components/agent/onboardingModels.d.ts.map +1 -0
  165. package/dist/components/agent/onboardingModels.js +107 -0
  166. package/dist/components/agent/onboardingModels.js.map +1 -0
  167. package/dist/components/agent/personalConversationScope.d.ts +26 -0
  168. package/dist/components/agent/personalConversationScope.d.ts.map +1 -0
  169. package/dist/components/agent/personalConversationScope.js +43 -0
  170. package/dist/components/agent/personalConversationScope.js.map +1 -0
  171. package/dist/components/agent/reviewRequestScope.d.ts +16 -0
  172. package/dist/components/agent/reviewRequestScope.d.ts.map +1 -0
  173. package/dist/components/agent/reviewRequestScope.js +101 -0
  174. package/dist/components/agent/reviewRequestScope.js.map +1 -0
  175. package/dist/components/agent/scheduleCreationAttempt.d.ts +12 -0
  176. package/dist/components/agent/scheduleCreationAttempt.d.ts.map +1 -0
  177. package/dist/components/agent/scheduleCreationAttempt.js +30 -0
  178. package/dist/components/agent/scheduleCreationAttempt.js.map +1 -0
  179. package/dist/components/agent/settings/EntitySettingsLayout.d.ts +1 -1
  180. package/dist/components/agent/settings/EntitySettingsLayout.d.ts.map +1 -1
  181. package/dist/components/agent/settings/EntitySettingsLayout.js +64 -44
  182. package/dist/components/agent/settings/EntitySettingsLayout.js.map +1 -1
  183. package/dist/components/agent/settings/SettingsNavigation.d.ts.map +1 -1
  184. package/dist/components/agent/settings/SettingsNavigation.js +17 -17
  185. package/dist/components/agent/settings/SettingsNavigation.js.map +1 -1
  186. package/dist/components/agent/settings/entityArchiveState.d.ts +24 -0
  187. package/dist/components/agent/settings/entityArchiveState.d.ts.map +1 -0
  188. package/dist/components/agent/settings/entityArchiveState.js +12 -0
  189. package/dist/components/agent/settings/entityArchiveState.js.map +1 -0
  190. package/dist/components/agent/settings/sections/AccessMembersSection.d.ts.map +1 -1
  191. package/dist/components/agent/settings/sections/AccessMembersSection.js +10 -25
  192. package/dist/components/agent/settings/sections/AccessMembersSection.js.map +1 -1
  193. package/dist/components/agent/settings/sections/AccountWorkspacePanel.d.ts +16 -0
  194. package/dist/components/agent/settings/sections/AccountWorkspacePanel.d.ts.map +1 -0
  195. package/dist/components/agent/settings/sections/AccountWorkspacePanel.js +265 -0
  196. package/dist/components/agent/settings/sections/AccountWorkspacePanel.js.map +1 -0
  197. package/dist/components/agent/settings/sections/AgentPermissionRulesPanel.d.ts.map +1 -1
  198. package/dist/components/agent/settings/sections/AgentPermissionRulesPanel.js +47 -32
  199. package/dist/components/agent/settings/sections/AgentPermissionRulesPanel.js.map +1 -1
  200. package/dist/components/agent/settings/sections/DangerZoneSection.d.ts.map +1 -1
  201. package/dist/components/agent/settings/sections/DangerZoneSection.js +30 -6
  202. package/dist/components/agent/settings/sections/DangerZoneSection.js.map +1 -1
  203. package/dist/components/agent/settings/sections/DefaultAgentConfigSection.d.ts.map +1 -1
  204. package/dist/components/agent/settings/sections/DefaultAgentConfigSection.js +47 -37
  205. package/dist/components/agent/settings/sections/DefaultAgentConfigSection.js.map +1 -1
  206. package/dist/components/agent/settings/sections/EnvironmentSecretsSection.d.ts.map +1 -1
  207. package/dist/components/agent/settings/sections/EnvironmentSecretsSection.js +30 -43
  208. package/dist/components/agent/settings/sections/EnvironmentSecretsSection.js.map +1 -1
  209. package/dist/components/agent/settings/sections/ExportBackupSection.d.ts +3 -1
  210. package/dist/components/agent/settings/sections/ExportBackupSection.d.ts.map +1 -1
  211. package/dist/components/agent/settings/sections/ExportBackupSection.js +14 -12
  212. package/dist/components/agent/settings/sections/ExportBackupSection.js.map +1 -1
  213. package/dist/components/agent/settings/sections/GeneralSection.d.ts.map +1 -1
  214. package/dist/components/agent/settings/sections/GeneralSection.js +47 -4
  215. package/dist/components/agent/settings/sections/GeneralSection.js.map +1 -1
  216. package/dist/components/agent/settings/sections/IntegrationsSection.d.ts.map +1 -1
  217. package/dist/components/agent/settings/sections/IntegrationsSection.js +14 -21
  218. package/dist/components/agent/settings/sections/IntegrationsSection.js.map +1 -1
  219. package/dist/components/agent/settings/sections/NotificationsSection.d.ts.map +1 -1
  220. package/dist/components/agent/settings/sections/NotificationsSection.js +125 -20
  221. package/dist/components/agent/settings/sections/NotificationsSection.js.map +1 -1
  222. package/dist/components/agent/settings/sections/ResourceLimitsSection.d.ts.map +1 -1
  223. package/dist/components/agent/settings/sections/ResourceLimitsSection.js +7 -7
  224. package/dist/components/agent/settings/sections/ResourceLimitsSection.js.map +1 -1
  225. package/dist/components/agent/settings/sections/SecurityComplianceSection.d.ts.map +1 -1
  226. package/dist/components/agent/settings/sections/SecurityComplianceSection.js +5 -4
  227. package/dist/components/agent/settings/sections/SecurityComplianceSection.js.map +1 -1
  228. package/dist/components/agent/settings/sections/UsageAnalyticsSection.d.ts.map +1 -1
  229. package/dist/components/agent/settings/sections/UsageAnalyticsSection.js +2 -3
  230. package/dist/components/agent/settings/sections/UsageAnalyticsSection.js.map +1 -1
  231. package/dist/components/agent/settings/sections/WorkspaceDirectoryAccessSection.d.ts.map +1 -1
  232. package/dist/components/agent/settings/sections/WorkspaceDirectoryAccessSection.js +39 -26
  233. package/dist/components/agent/settings/sections/WorkspaceDirectoryAccessSection.js.map +1 -1
  234. package/dist/components/agent/settings/sections/WorkspaceKeysPanel.d.ts +6 -0
  235. package/dist/components/agent/settings/sections/WorkspaceKeysPanel.d.ts.map +1 -0
  236. package/dist/components/agent/settings/sections/WorkspaceKeysPanel.js +205 -0
  237. package/dist/components/agent/settings/sections/WorkspaceKeysPanel.js.map +1 -0
  238. package/dist/components/agent/settings/sections/environmentDraftAction.d.ts +3 -0
  239. package/dist/components/agent/settings/sections/environmentDraftAction.d.ts.map +1 -0
  240. package/dist/components/agent/settings/sections/environmentDraftAction.js +6 -0
  241. package/dist/components/agent/settings/sections/environmentDraftAction.js.map +1 -0
  242. package/dist/components/agent/settings/sections/membershipOperationProjection.d.ts +3 -0
  243. package/dist/components/agent/settings/sections/membershipOperationProjection.d.ts.map +1 -0
  244. package/dist/components/agent/settings/sections/membershipOperationProjection.js +9 -0
  245. package/dist/components/agent/settings/sections/membershipOperationProjection.js.map +1 -0
  246. package/dist/components/agent/settings/sections/workspaceKeyOperationProjection.d.ts +6 -0
  247. package/dist/components/agent/settings/sections/workspaceKeyOperationProjection.d.ts.map +1 -0
  248. package/dist/components/agent/settings/sections/workspaceKeyOperationProjection.js +8 -0
  249. package/dist/components/agent/settings/sections/workspaceKeyOperationProjection.js.map +1 -0
  250. package/dist/components/agent/settings/shared/InAppConfirmationDialog.d.ts +25 -0
  251. package/dist/components/agent/settings/shared/InAppConfirmationDialog.d.ts.map +1 -0
  252. package/dist/components/agent/settings/shared/InAppConfirmationDialog.js +89 -0
  253. package/dist/components/agent/settings/shared/InAppConfirmationDialog.js.map +1 -0
  254. package/dist/components/agent/settings/shared/InputField.d.ts +1 -1
  255. package/dist/components/agent/settings/shared/InputField.d.ts.map +1 -1
  256. package/dist/components/agent/settings/shared/InputField.js +4 -3
  257. package/dist/components/agent/settings/shared/InputField.js.map +1 -1
  258. package/dist/components/agent/settings/shared/MembersTable.d.ts +3 -3
  259. package/dist/components/agent/settings/shared/MembersTable.d.ts.map +1 -1
  260. package/dist/components/agent/settings/shared/MembersTable.js +1 -1
  261. package/dist/components/agent/settings/shared/MembersTable.js.map +1 -1
  262. package/dist/components/agent/settings/shared/ScopedAuditPanel.d.ts +5 -0
  263. package/dist/components/agent/settings/shared/ScopedAuditPanel.d.ts.map +1 -0
  264. package/dist/components/agent/settings/shared/ScopedAuditPanel.js +70 -0
  265. package/dist/components/agent/settings/shared/ScopedAuditPanel.js.map +1 -0
  266. package/dist/components/agent/settings/shared/SettingsCard.d.ts +2 -1
  267. package/dist/components/agent/settings/shared/SettingsCard.d.ts.map +1 -1
  268. package/dist/components/agent/settings/shared/SettingsCard.js +2 -2
  269. package/dist/components/agent/settings/shared/SettingsCard.js.map +1 -1
  270. package/dist/components/agent/settings/shared/ToggleSwitch.d.ts.map +1 -1
  271. package/dist/components/agent/settings/shared/ToggleSwitch.js +1 -1
  272. package/dist/components/agent/settings/shared/ToggleSwitch.js.map +1 -1
  273. package/dist/components/agent/settings/shared/UsageChart.d.ts +10 -0
  274. package/dist/components/agent/settings/shared/UsageChart.d.ts.map +1 -1
  275. package/dist/components/agent/settings/shared/UsageChart.js +16 -10
  276. package/dist/components/agent/settings/shared/UsageChart.js.map +1 -1
  277. package/dist/components/agent/settings/shared/WorkspaceRulesControl.d.ts +8 -0
  278. package/dist/components/agent/settings/shared/WorkspaceRulesControl.d.ts.map +1 -0
  279. package/dist/components/agent/settings/shared/WorkspaceRulesControl.js +26 -0
  280. package/dist/components/agent/settings/shared/WorkspaceRulesControl.js.map +1 -0
  281. package/dist/components/agent/settings/shared/useScopedConfirmation.d.ts +8 -0
  282. package/dist/components/agent/settings/shared/useScopedConfirmation.d.ts.map +1 -0
  283. package/dist/components/agent/settings/shared/useScopedConfirmation.js +53 -0
  284. package/dist/components/agent/settings/shared/useScopedConfirmation.js.map +1 -0
  285. package/dist/components/agent/settings/shared/useSettingsConfirmation.d.ts +8 -0
  286. package/dist/components/agent/settings/shared/useSettingsConfirmation.d.ts.map +1 -0
  287. package/dist/components/agent/settings/shared/useSettingsConfirmation.js +51 -0
  288. package/dist/components/agent/settings/shared/useSettingsConfirmation.js.map +1 -0
  289. package/dist/components/agent/settings/shared/workspaceRulesController.d.ts +28 -0
  290. package/dist/components/agent/settings/shared/workspaceRulesController.d.ts.map +1 -0
  291. package/dist/components/agent/settings/shared/workspaceRulesController.js +82 -0
  292. package/dist/components/agent/settings/shared/workspaceRulesController.js.map +1 -0
  293. package/dist/components/agent/sidebarEntityPins.d.ts +11 -0
  294. package/dist/components/agent/sidebarEntityPins.d.ts.map +1 -0
  295. package/dist/components/agent/sidebarEntityPins.js +37 -0
  296. package/dist/components/agent/sidebarEntityPins.js.map +1 -0
  297. package/dist/components/agent/workspaceHierarchy.d.ts +24 -0
  298. package/dist/components/agent/workspaceHierarchy.d.ts.map +1 -0
  299. package/dist/components/agent/workspaceHierarchy.js +50 -0
  300. package/dist/components/agent/workspaceHierarchy.js.map +1 -0
  301. package/dist/components/product/XenoAgentProductHeader.d.ts +4 -2
  302. package/dist/components/product/XenoAgentProductHeader.d.ts.map +1 -1
  303. package/dist/components/product/XenoAgentProductHeader.js +22 -4
  304. package/dist/components/product/XenoAgentProductHeader.js.map +1 -1
  305. package/dist/components/product/XenoAgentSessionTabs.js +1 -1
  306. package/dist/components/product/XenoAgentSessionTabs.js.map +1 -1
  307. package/dist/components/product/XenoAgentWorkspaceSelector.d.ts +7 -0
  308. package/dist/components/product/XenoAgentWorkspaceSelector.d.ts.map +1 -0
  309. package/dist/components/product/XenoAgentWorkspaceSelector.js +237 -0
  310. package/dist/components/product/XenoAgentWorkspaceSelector.js.map +1 -0
  311. package/dist/components/workspace/WorkspaceCreationWizard.d.ts +6 -0
  312. package/dist/components/workspace/WorkspaceCreationWizard.d.ts.map +1 -0
  313. package/dist/components/workspace/WorkspaceCreationWizard.js +48 -0
  314. package/dist/components/workspace/WorkspaceCreationWizard.js.map +1 -0
  315. package/dist/hooks/useSidebarLayoutPreference.d.ts +29 -0
  316. package/dist/hooks/useSidebarLayoutPreference.d.ts.map +1 -0
  317. package/dist/hooks/useSidebarLayoutPreference.js +83 -0
  318. package/dist/hooks/useSidebarLayoutPreference.js.map +1 -0
  319. package/dist/hooks/useWorkspaceCreation.d.ts +8 -0
  320. package/dist/hooks/useWorkspaceCreation.d.ts.map +1 -0
  321. package/dist/hooks/useWorkspaceCreation.js +40 -0
  322. package/dist/hooks/useWorkspaceCreation.js.map +1 -0
  323. package/dist/index.d.ts +3 -0
  324. package/dist/index.d.ts.map +1 -1
  325. package/dist/index.js +3 -0
  326. package/dist/index.js.map +1 -1
  327. package/dist/platformApiTypes.d.ts +77 -36
  328. package/dist/platformApiTypes.d.ts.map +1 -1
  329. package/dist/platformBridge.d.ts +4 -0
  330. package/dist/platformBridge.d.ts.map +1 -1
  331. package/dist/platformBridge.js +10 -0
  332. package/dist/platformBridge.js.map +1 -1
  333. package/dist/stores/agentChatStore.d.ts +120 -2
  334. package/dist/stores/agentChatStore.d.ts.map +1 -1
  335. package/dist/stores/agentChatStore.js +344 -35
  336. package/dist/stores/agentChatStore.js.map +1 -1
  337. package/dist/stores/agentCreationDefaults.d.ts +25 -0
  338. package/dist/stores/agentCreationDefaults.d.ts.map +1 -0
  339. package/dist/stores/agentCreationDefaults.js +11 -0
  340. package/dist/stores/agentCreationDefaults.js.map +1 -0
  341. package/dist/stores/entitySettingsStore.d.ts +37 -12
  342. package/dist/stores/entitySettingsStore.d.ts.map +1 -1
  343. package/dist/stores/entitySettingsStore.js +558 -585
  344. package/dist/stores/entitySettingsStore.js.map +1 -1
  345. package/dist/stores/suggestionStore.d.ts +9 -2
  346. package/dist/stores/suggestionStore.d.ts.map +1 -1
  347. package/dist/stores/suggestionStore.js +51 -24
  348. package/dist/stores/suggestionStore.js.map +1 -1
  349. package/dist/stores/workspaceCreationAttempt.d.ts +14 -0
  350. package/dist/stores/workspaceCreationAttempt.d.ts.map +1 -0
  351. package/dist/stores/workspaceCreationAttempt.js +35 -0
  352. package/dist/stores/workspaceCreationAttempt.js.map +1 -0
  353. package/dist/stores/workspaceReconciliation.d.ts +6 -0
  354. package/dist/stores/workspaceReconciliation.d.ts.map +1 -0
  355. package/dist/stores/workspaceReconciliation.js +33 -0
  356. package/dist/stores/workspaceReconciliation.js.map +1 -0
  357. package/dist/stores/workspaceStore.d.ts +44 -9
  358. package/dist/stores/workspaceStore.d.ts.map +1 -1
  359. package/dist/stores/workspaceStore.js +238 -99
  360. package/dist/stores/workspaceStore.js.map +1 -1
  361. package/dist/types/agentEditor.d.ts +1 -0
  362. package/dist/types/agentEditor.d.ts.map +1 -1
  363. package/dist/utils/advertisedReasoning.d.ts +25 -0
  364. package/dist/utils/advertisedReasoning.d.ts.map +1 -0
  365. package/dist/utils/advertisedReasoning.js +62 -0
  366. package/dist/utils/advertisedReasoning.js.map +1 -0
  367. package/dist/utils/clipboardCopy.d.ts +4 -0
  368. package/dist/utils/clipboardCopy.d.ts.map +1 -0
  369. package/dist/utils/clipboardCopy.js +27 -0
  370. package/dist/utils/clipboardCopy.js.map +1 -0
  371. package/dist/utils/providerCommandArgs.d.ts +11 -0
  372. package/dist/utils/providerCommandArgs.d.ts.map +1 -0
  373. package/dist/utils/providerCommandArgs.js +18 -0
  374. package/dist/utils/providerCommandArgs.js.map +1 -0
  375. package/dist/utils/rendererTeardown.d.ts +6 -0
  376. package/dist/utils/rendererTeardown.d.ts.map +1 -0
  377. package/dist/utils/rendererTeardown.js +18 -0
  378. package/dist/utils/rendererTeardown.js.map +1 -0
  379. package/package.json +20 -8
  380. package/src/agent.css +39 -9
@@ -1,5 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { getAgentPlatformBridge, getOptionalAgentPlatformBridge } from '../../platformBridge.js';
3
+ import { copyTextWithFallback } from '../../utils/clipboardCopy.js';
4
+ import { sdkConfirmationActions, usePreparedConfirmation } from './destructiveConfirmation.js';
5
+ import { SdkSessionPanel } from './SdkSessionPanel.js';
6
+ import { LiveConversationCollaboration } from './LiveConversationCollaboration.js';
7
+ import { readCollaborationAccess } from './conversationCollaborationController.js';
3
8
  /*
4
9
  * AgentView.tsx - Active Agent Chat Interface
5
10
  *
@@ -21,14 +26,18 @@ import { useSuggestionStore } from '../../stores/suggestionStore.js';
21
26
  import { GhostTextArea } from './GhostTextArea.js';
22
27
  import { AIStatusIndicator } from './AIStatusIndicator.js';
23
28
  import { CommandToolCard } from './CommandToolCard.js';
29
+ import { AgentNotificationBanner } from './AgentNotificationBanner.js';
30
+ import { SlashCommandAutocomplete } from './SlashCommandAutocomplete.js';
24
31
  import { AssistantTurnErrorNotice, AssistantTurnStatusNotice } from './AssistantTurnStatusNotice.js';
25
32
  import { commandPreviewText, compactCommandPreview, deriveToolInteractionState, hideDuplicateToolTitle, isCommandToolCall } from './toolCardDisplay.js';
26
33
  import { deriveWebJobProgressView, webJobStopAvailability, WEB_JOB_STOP_LABEL, WEB_JOB_STOP_TITLE } from './webJobProgressView.js';
27
34
  import { cloudModelName, cloudModelSortScore } from '../../utils/cloudModels.js';
28
35
  import { isSelectableLiveModel } from '../../utils/modelAvailability.js';
36
+ import { buildProviderCommandArgs } from '../../utils/providerCommandArgs.js';
29
37
  import { availableAcpConfigIds } from '../../utils/providerAvailability.js';
30
38
  import { extractWindowsFilePathsFromToolResult, prepareAgentMarkdown, resolveMarkdownLocalFilePath, } from '../../utils/markdownWindowsPaths.js';
31
- import { agentReasoningEffortLabel, buildExplicitAgentReasoningEffortFamilies, indexAgentReasoningEffortFamilies, preferredAgentReasoningModelId, resolveAgentReasoningEffortFamily, } from '../../utils/agentReasoningEffort.js';
39
+ import { agentReasoningEffortLabel, indexAgentReasoningEffortFamilies, resolveAgentReasoningEffortFamily, } from '../../utils/agentReasoningEffort.js';
40
+ import { projectAdvertisedReasoning, projectAdvertisedModels, resolveAdvertisedReasoning, preferredAdvertisedModel, providerRuntimeModelId } from '../../utils/advertisedReasoning.js';
32
41
  import { acpAgentDisplayName, resolveHubAgentRuntimeProvider } from '../../utils/agentRuntimeProvider.js';
33
42
  import { createConversationRuntimeBinding, reconcileCloudConversationModel, runtimeSelectionForSdk, } from '../../utils/conversationRuntime.js';
34
43
  import { extractUserFileCreateRequest, extractUserFileEditRequest, isAbsoluteOrRootedPath } from '../../utils/fileCreateIntent.js';
@@ -39,23 +48,7 @@ import { AgentProviderSelectorController } from '../../providerSelector.js';
39
48
  import { loadHubAgentProviderCatalog, refreshHubAgentProviderCatalog, subscribeHubAgentProviderCatalog, } from '../../adapters/xenoAgentHostCatalog.js';
40
49
  const AGENT_GPT55_DEFAULT_MODEL = 'gpt-5.5-high';
41
50
  const AGENT_MODEL_MODE_SWITCH_ENABLED = true;
42
- const AGENT_GPT55_MODEL_IDS = new Set([
43
- 'gpt-5.5',
44
- 'gpt-5.5-none',
45
- 'gpt-5.5-low',
46
- 'gpt-5.5-medium',
47
- 'gpt-5.5-high',
48
- 'gpt-5.5-xhigh',
49
- 'gpt-5.5-pro',
50
- 'gpt-5.5-mini',
51
- 'gpt-5.5-nano',
52
- ]);
53
- const normalizeAgentModelId = (id) => {
54
- const base = id.replace(/:thinking$/, '');
55
- return base.includes('/') ? (base.split('/').pop() || base) : base;
56
- };
57
51
  const isAgentCloudModel = (id) => !!id && !id.startsWith('local:');
58
- const isAgentGpt55Model = (id) => AGENT_GPT55_MODEL_IDS.has(normalizeAgentModelId(id));
59
52
  const EMPTY_MESSAGES = [];
60
53
  const EMPTY_STRINGS = [];
61
54
  const EMPTY_ACP_MODEL_CHOICES = [];
@@ -2115,25 +2108,6 @@ function buildConversationDebugSnapshot(params) {
2115
2108
  }
2116
2109
  return lines.join('\n').trim();
2117
2110
  }
2118
- async function copyTextWithFallback(value) {
2119
- if (navigator.clipboard?.writeText) {
2120
- await navigator.clipboard.writeText(value);
2121
- return;
2122
- }
2123
- const textArea = document.createElement('textarea');
2124
- textArea.value = value;
2125
- textArea.setAttribute('readonly', 'true');
2126
- textArea.style.position = 'fixed';
2127
- textArea.style.opacity = '0';
2128
- textArea.style.pointerEvents = 'none';
2129
- document.body.appendChild(textArea);
2130
- textArea.select();
2131
- const copied = document.execCommand('copy');
2132
- document.body.removeChild(textArea);
2133
- if (!copied) {
2134
- throw new Error('Clipboard copy failed');
2135
- }
2136
- }
2137
2111
  function splitPreviewLines(value) {
2138
2112
  if (!value)
2139
2113
  return [];
@@ -2237,17 +2211,43 @@ function trimToolPreviewText(value, maxLines = 10, maxChars = 1200) {
2237
2211
  }
2238
2212
  function DiffCopyButton({ getText, title = 'Copy file contents' }) {
2239
2213
  const [copied, setCopied] = useState(false);
2240
- return (_jsx("button", { type: "button", onClick: async (event) => {
2241
- event.stopPropagation();
2242
- try {
2243
- await copyTextWithFallback(getText());
2244
- setCopied(true);
2245
- window.setTimeout(() => setCopied(false), 1200);
2246
- }
2247
- catch {
2248
- /* clipboard unavailable */
2249
- }
2250
- }, className: "p-1 rounded text-white/20 hover:text-white/50 hover:bg-white/[0.04] active:scale-75 transition-all duration-100", title: copied ? 'Copied' : title, "aria-label": title, children: copied ? _jsx(Check, { className: "w-3 h-3 text-white/60", strokeWidth: 1.7 }) : _jsx(Copy, { className: "w-3 h-3" }) }));
2214
+ const [copyError, setCopyError] = useState(false);
2215
+ const [pending, setPending] = useState(false);
2216
+ const pendingRef = useRef(false);
2217
+ const timer = useRef(null);
2218
+ const mounted = useRef(true);
2219
+ useEffect(() => {
2220
+ mounted.current = true;
2221
+ return () => { mounted.current = false; if (timer.current)
2222
+ clearTimeout(timer.current); };
2223
+ }, []);
2224
+ return (_jsxs("span", { className: "inline-flex items-center gap-1", children: [_jsx("button", { type: "button", disabled: pending, onClick: async (event) => {
2225
+ event.stopPropagation();
2226
+ if (pendingRef.current)
2227
+ return;
2228
+ pendingRef.current = true;
2229
+ setPending(true);
2230
+ setCopyError(false);
2231
+ setCopied(false);
2232
+ if (timer.current)
2233
+ clearTimeout(timer.current);
2234
+ try {
2235
+ await copyTextWithFallback(getText());
2236
+ if (!mounted.current)
2237
+ return;
2238
+ setCopied(true);
2239
+ timer.current = setTimeout(() => setCopied(false), 1200);
2240
+ }
2241
+ catch {
2242
+ if (mounted.current)
2243
+ setCopyError(true);
2244
+ }
2245
+ finally {
2246
+ pendingRef.current = false;
2247
+ if (mounted.current)
2248
+ setPending(false);
2249
+ }
2250
+ }, className: "p-1 rounded text-white/20 hover:text-white/50 hover:bg-white/[0.04] active:scale-75 transition-all duration-100", title: copied ? 'Copied' : title, "aria-label": title, children: copied ? _jsx(Check, { className: "w-3 h-3 text-white/60", strokeWidth: 1.7 }) : _jsx(Copy, { className: "w-3 h-3" }) }), copyError && _jsx("span", { role: "alert", className: "text-[10px] text-red-300", children: "Copy failed. Try again." })] }));
2251
2251
  }
2252
2252
  function ToolInlineDiffCard({ toolCall, onPeekEditorDiff, onPeekEditorPath, embedded = false, showHeaderActions = true, showHeaderStats = true, showHeader = true, }) {
2253
2253
  const diff = toolCall.diff;
@@ -3270,6 +3270,14 @@ export function AgentView(props) {
3270
3270
  const conversations = useAgentChatStore(s => s.conversations);
3271
3271
  const persistenceNotice = useAgentChatStore(s => s.persistenceNotice);
3272
3272
  const conversation = conversationId ? conversations[conversationId] : undefined;
3273
+ const [collaborationAccess, setCollaborationAccess] = useState(() => (readCollaborationAccess(typeof localStorage !== 'undefined' ? localStorage : undefined, conversationId || undefined)));
3274
+ const collaborationRequest = useMemo(() => {
3275
+ const request = getOptionalAgentPlatformBridge()?.account?.request;
3276
+ return request ? (input) => request(input) : undefined;
3277
+ }, []);
3278
+ useEffect(() => {
3279
+ setCollaborationAccess(readCollaborationAccess(typeof localStorage !== 'undefined' ? localStorage : undefined, conversationId || undefined));
3280
+ }, [conversationId]);
3273
3281
  const updateConversation = useAgentChatStore(s => s.updateConversation);
3274
3282
  const [input, setInput] = useState('');
3275
3283
  const [isSelectingConversationWorkspace, setIsSelectingConversationWorkspace] = useState(false);
@@ -3315,22 +3323,13 @@ export function AgentView(props) {
3315
3323
  : 'save failed';
3316
3324
  setToolStatus(`Conversation ${label}: ${persistenceNotice.message || 'Local storage is unavailable.'}`);
3317
3325
  }, [conversationId, persistenceNotice]);
3318
- // Reasoning-capable SDK models use ':thinking' as a UI-only suffix so the request can
3319
- // keep sending the base model ID plus enableThinking=true.
3320
- const canThink = (id) => {
3321
- const normalized = id.includes('/') ? (id.split('/').pop() || id) : id;
3322
- if (normalized.endsWith('-thinking'))
3323
- return false;
3324
- if (/-(none|low|medium|high|xhigh)$/.test(normalized))
3325
- return false;
3326
- if (normalized.startsWith('claude-'))
3327
- return !normalized.includes('haiku');
3328
- return /^gpt-5(?:[.-]|$)/.test(normalized);
3329
- };
3330
- const isThinkingVariant = selectedModel.endsWith(':thinking');
3326
+ // Local runtime supportsThinking is an explicit capability. Cloud and ACP
3327
+ // reasoning choices below come exclusively from their advertised descriptors.
3328
+ const isThinkingVariant = selectedModel.startsWith('local:') && selectedModel.endsWith(':thinking');
3331
3329
  const thinkingEnabled = isThinkingVariant;
3330
+ const [reasoningChoice, setReasoningChoice] = useState(null);
3332
3331
  // Actual model ID sent to API (strip :thinking suffix)
3333
- const actualModelId = selectedModel.replace(/:thinking$/, '');
3332
+ const actualModelId = providerRuntimeModelId(selectedModel);
3334
3333
  const [modeExpanded, setModeExpanded] = useState(false);
3335
3334
  const [modelSelectorVisible, setModelSelectorVisible] = useState(true);
3336
3335
  const [modelListOpen, setModelListOpen] = useState(false);
@@ -3554,7 +3553,7 @@ export function AgentView(props) {
3554
3553
  const authDisplayName = useAuthStore(s => s.user?.display_name ?? null);
3555
3554
  const cloudRuntimeProvider = useMemo(() => sharedRuntimeProviders.find((entry) => entry.id === 'xeno-cloud'), [sharedRuntimeProviders]);
3556
3555
  const cloudModels = useMemo(() => {
3557
- return (cloudRuntimeProvider?.models || [])
3556
+ return projectAdvertisedModels(cloudRuntimeProvider)
3558
3557
  .filter(isSelectableLiveModel)
3559
3558
  .map((modelEntry) => ({
3560
3559
  id: modelEntry.id,
@@ -3578,31 +3577,18 @@ export function AgentView(props) {
3578
3577
  const availableModels = useXenoChatStore(s => s.availableModels);
3579
3578
  const fetchModels = useXenoChatStore(s => s.fetchModels);
3580
3579
  const localModels = useMemo(() => availableModels.filter(m => m.provider === 'local'), [availableModels]);
3581
- const cloudEffortFamilies = useMemo(() => {
3582
- const families = buildExplicitAgentReasoningEffortFamilies(cloudModels.map((modelEntry) => modelEntry.id));
3583
- for (const modelEntry of cloudModels) {
3584
- if (!modelEntry.id.endsWith('-thinking'))
3585
- continue;
3586
- const baseId = modelEntry.id.slice(0, -'-thinking'.length);
3587
- if (families.has(baseId) || !cloudModels.some((candidate) => candidate.id === baseId))
3588
- continue;
3589
- families.set(baseId, [
3590
- { effort: 'auto', modelId: baseId },
3591
- { effort: 'thinking', modelId: modelEntry.id },
3592
- ]);
3593
- }
3594
- for (const modelEntry of cloudModels) {
3595
- if (families.has(modelEntry.id) || !canThink(modelEntry.id) || isAgentGpt55Model(modelEntry.id))
3596
- continue;
3597
- families.set(modelEntry.id, [
3598
- { effort: 'auto', modelId: modelEntry.id },
3599
- { effort: 'thinking', modelId: `${modelEntry.id}:thinking` },
3600
- ]);
3601
- }
3602
- return families;
3603
- }, [cloudModels]);
3604
- const cloudEffortFamilyByModelId = useMemo(() => indexAgentReasoningEffortFamilies(cloudEffortFamilies), [cloudEffortFamilies]);
3605
- const selectedCloudEffortFamily = useMemo(() => resolveAgentReasoningEffortFamily(selectedModel, cloudEffortFamilies, cloudEffortFamilyByModelId), [cloudEffortFamilies, cloudEffortFamilyByModelId, selectedModel]);
3580
+ const reasoningProviderKey = runtimeMode === 'acp' ? `acp:${selectedAcpAgentConfigId}` : runtimeMode;
3581
+ const reasoningRuntimeModel = runtimeMode === 'acp' ? acpProviderModel : selectedModel;
3582
+ const selectedReasoningOptionId = reasoningChoice?.conversationId === (conversationId || null) && reasoningChoice?.providerKey === reasoningProviderKey && reasoningChoice.modelId === reasoningRuntimeModel
3583
+ ? reasoningChoice.optionId
3584
+ : conversation?.runtime && conversation.runtime.model === reasoningRuntimeModel
3585
+ && (conversation.runtime.executionMode === runtimeMode)
3586
+ ? conversation.runtime.reasoning.optionId
3587
+ : undefined;
3588
+ const cloudReasoningCatalog = useMemo(() => projectAdvertisedReasoning(cloudRuntimeProvider), [cloudRuntimeProvider]);
3589
+ const cloudEffortFamilies = cloudReasoningCatalog.families;
3590
+ const cloudEffortFamilyByModelId = cloudReasoningCatalog.byModelId;
3591
+ const selectedCloudEffortFamily = useMemo(() => resolveAdvertisedReasoning(selectedModel, cloudReasoningCatalog, selectedReasoningOptionId), [cloudReasoningCatalog, selectedModel, selectedReasoningOptionId]);
3606
3592
  const localEffortFamilies = useMemo(() => {
3607
3593
  const families = new Map();
3608
3594
  for (const modelEntry of localModels) {
@@ -3617,9 +3603,10 @@ export function AgentView(props) {
3617
3603
  }, [localModels]);
3618
3604
  const localEffortFamilyByModelId = useMemo(() => indexAgentReasoningEffortFamilies(localEffortFamilies), [localEffortFamilies]);
3619
3605
  const selectedLocalEffortFamily = useMemo(() => resolveAgentReasoningEffortFamily(selectedModel, localEffortFamilies, localEffortFamilyByModelId), [localEffortFamilies, localEffortFamilyByModelId, selectedModel]);
3620
- const acpEffortFamilies = useMemo(() => buildExplicitAgentReasoningEffortFamilies(acpModelOptions), [acpModelOptions]);
3621
- const acpEffortFamilyByModelId = useMemo(() => indexAgentReasoningEffortFamilies(acpEffortFamilies), [acpEffortFamilies]);
3622
- const selectedAcpEffortFamily = useMemo(() => resolveAgentReasoningEffortFamily(acpProviderModel, acpEffortFamilies, acpEffortFamilyByModelId), [acpEffortFamilies, acpEffortFamilyByModelId, acpProviderModel]);
3606
+ const acpReasoningCatalog = useMemo(() => projectAdvertisedReasoning(selectedSharedAcpProvider), [selectedSharedAcpProvider]);
3607
+ const acpEffortFamilies = acpReasoningCatalog.families;
3608
+ const acpEffortFamilyByModelId = acpReasoningCatalog.byModelId;
3609
+ const selectedAcpEffortFamily = useMemo(() => resolveAdvertisedReasoning(acpProviderModel, acpReasoningCatalog, selectedReasoningOptionId), [acpReasoningCatalog, acpProviderModel, selectedReasoningOptionId]);
3623
3610
  const acpProviderModelDisplayName = useMemo(() => {
3624
3611
  if (!acpProviderModel)
3625
3612
  return 'CLI default';
@@ -3629,43 +3616,24 @@ export function AgentView(props) {
3629
3616
  const displayModelId = selectedAcpEffortFamily?.baseId || acpProviderModel;
3630
3617
  return presentAcpProviderModelLabel(acpProviderModelOptionById.get(displayModelId), displayModelId);
3631
3618
  }, [acpProviderModel, acpProviderModelOptionById, selectedAcpEffortFamily?.baseId, selectedSharedAcpSnapshot]);
3632
- const activeReasoningEffortFamily = runtimeMode === 'acp'
3633
- ? null
3634
- : runtimeMode === 'local'
3635
- ? selectedLocalEffortFamily
3636
- : selectedCloudEffortFamily;
3637
3619
  const activeReasoningSelector = useMemo(() => {
3638
- if (runtimeMode === 'acp') {
3639
- const selectedSharedModel = selectedSharedAcpSnapshot?.selectedModel;
3640
- if (!selectedSharedModel)
3641
- return null;
3642
- const advertisedReasoning = selectedSharedModel.reasoningOptions || [];
3643
- const baseReasoning = advertisedReasoning.find((option) => (!option.runtimeModelId || option.runtimeModelId === selectedSharedModel.id));
3644
- const variants = advertisedReasoning.filter((option) => (!!option.runtimeModelId && option.runtimeModelId !== selectedSharedModel.id));
3645
- if (variants.length === 0)
3620
+ if (runtimeMode !== 'local') {
3621
+ const family = runtimeMode === 'acp' ? selectedAcpEffortFamily : selectedCloudEffortFamily;
3622
+ if (!family)
3646
3623
  return null;
3647
- const options = [{
3648
- id: baseReasoning?.id || 'provider-default',
3649
- label: baseReasoning?.label || 'Default',
3650
- modelId: selectedSharedModel.id,
3651
- available: selectedSharedModel.availability === 'available' || selectedSharedModel.availability === 'degraded',
3652
- reason: selectedSharedModel.safeUnavailableReason || null,
3653
- }, ...variants.map((option) => ({
3654
- id: option.id,
3655
- label: option.label,
3656
- modelId: option.runtimeModelId,
3657
- available: selectedSharedModel.availability === 'available' || selectedSharedModel.availability === 'degraded',
3658
- reason: selectedSharedModel.safeUnavailableReason || option.description || null,
3659
- }))];
3660
- const selectedRuntimeModel = selectedSharedAcpSnapshot.selection?.runtimeModelId || selectedSharedModel.id;
3661
- const selectedOption = options.find((option) => option.modelId === selectedRuntimeModel) || options[0];
3662
- return { label: selectedOption?.label || 'Default', options };
3663
- }
3664
- if (!activeReasoningEffortFamily)
3624
+ return {
3625
+ label: family.label,
3626
+ options: family.options.map((option) => ({
3627
+ id: option.effort, label: option.label, modelId: option.modelId,
3628
+ available: option.available, reason: option.reason,
3629
+ })),
3630
+ };
3631
+ }
3632
+ if (!selectedLocalEffortFamily)
3665
3633
  return null;
3666
3634
  return {
3667
- label: agentReasoningEffortLabel(activeReasoningEffortFamily.effort),
3668
- options: activeReasoningEffortFamily.options.map((option) => ({
3635
+ label: agentReasoningEffortLabel(selectedLocalEffortFamily.effort),
3636
+ options: selectedLocalEffortFamily.options.map((option) => ({
3669
3637
  id: option.effort,
3670
3638
  label: agentReasoningEffortLabel(option.effort),
3671
3639
  modelId: option.modelId,
@@ -3673,7 +3641,7 @@ export function AgentView(props) {
3673
3641
  reason: null,
3674
3642
  })),
3675
3643
  };
3676
- }, [activeReasoningEffortFamily, runtimeMode, selectedSharedAcpSnapshot]);
3644
+ }, [selectedLocalEffortFamily, selectedCloudEffortFamily, selectedAcpEffortFamily, runtimeMode]);
3677
3645
  const normalizedModelSearch = modelSearchQuery.trim().toLowerCase();
3678
3646
  const filteredCloudModelOptions = useMemo(() => {
3679
3647
  const seenEffortFamilies = new Set();
@@ -3686,17 +3654,17 @@ export function AgentView(props) {
3686
3654
  seenEffortFamilies.add(effortBaseId);
3687
3655
  const selectedOption = selectedCloudEffortFamily?.baseId === effortBaseId
3688
3656
  ? selectedModel
3689
- : preferredAgentReasoningModelId(effortOptions) || effortBaseId;
3657
+ : preferredAdvertisedModel(effortOptions) || effortBaseId;
3690
3658
  return [{
3691
3659
  id: selectedOption,
3692
3660
  selectionKey: effortBaseId,
3693
- name: cloudModelName(effortBaseId),
3694
- searchText: effortOptions.map((option) => `${option.modelId} ${agentReasoningEffortLabel(option.effort)}`).join(' '),
3661
+ name: cloudRuntimeProvider?.models.find((entry) => entry.id === effortBaseId)?.displayName || effortBaseId,
3662
+ searchText: effortOptions.map((option) => `${option.modelId} ${option.label}`).join(' '),
3695
3663
  }];
3696
3664
  }
3697
3665
  return [{ id: modelEntry.id, selectionKey: modelEntry.id, name: modelEntry.name, searchText: modelEntry.id }];
3698
3666
  }).filter((entry) => !normalizedModelSearch || `${entry.name} ${entry.searchText}`.toLowerCase().includes(normalizedModelSearch));
3699
- }, [cloudEffortFamilies, cloudEffortFamilyByModelId, cloudModels, normalizedModelSearch, selectedCloudEffortFamily?.baseId, selectedModel]);
3667
+ }, [cloudEffortFamilies, cloudEffortFamilyByModelId, cloudModels, cloudRuntimeProvider, normalizedModelSearch, selectedCloudEffortFamily?.baseId, selectedModel]);
3700
3668
  const filteredLocalModels = useMemo(() => localModels.filter(modelEntry => (!normalizedModelSearch
3701
3669
  || `${modelEntry.name} ${modelEntry.id} ${modelEntry.parameterSize || ''}`.toLowerCase().includes(normalizedModelSearch))), [localModels, normalizedModelSearch]);
3702
3670
  const filteredAcpModelOptions = useMemo(() => {
@@ -3710,7 +3678,7 @@ export function AgentView(props) {
3710
3678
  seenEffortFamilies.add(effortBaseId);
3711
3679
  const selectedOption = selectedAcpEffortFamily?.baseId === effortBaseId && acpProviderModel
3712
3680
  ? acpProviderModel
3713
- : preferredAgentReasoningModelId(effortOptions) || effortBaseId;
3681
+ : preferredAdvertisedModel(effortOptions) || effortBaseId;
3714
3682
  const selectedModelOption = acpProviderModelOptionById.get(selectedOption);
3715
3683
  return [{
3716
3684
  id: selectedOption,
@@ -3718,7 +3686,7 @@ export function AgentView(props) {
3718
3686
  name: presentAcpProviderModelLabel(acpProviderModelOptionById.get(effortBaseId), effortBaseId),
3719
3687
  searchText: effortOptions.map((option) => {
3720
3688
  const discoveredOption = acpProviderModelOptionById.get(option.modelId);
3721
- return `${option.modelId} ${discoveredOption?.label || ''} ${discoveredOption?.reason || ''} ${agentReasoningEffortLabel(option.effort)}`;
3689
+ return `${option.modelId} ${discoveredOption?.label || ''} ${discoveredOption?.reason || ''} ${option.label}`;
3722
3690
  }).join(' '),
3723
3691
  available: selectedModelOption?.available !== false,
3724
3692
  reason: selectedModelOption?.reason || null,
@@ -3736,11 +3704,11 @@ export function AgentView(props) {
3736
3704
  }).filter((entry) => !normalizedModelSearch || `${entry.name} ${entry.searchText}`.toLowerCase().includes(normalizedModelSearch));
3737
3705
  }, [acpEffortFamilies, acpEffortFamilyByModelId, acpModelOptions, acpProviderModel, acpProviderModelOptionById, normalizedModelSearch, selectedAcpEffortFamily?.baseId]);
3738
3706
  const preferredGpt55Model = useMemo(() => {
3739
- return cloudModels.find(m => m.id === AGENT_GPT55_DEFAULT_MODEL)?.id
3740
- || cloudModels.find(m => m.id === 'gpt-5.5')?.id
3707
+ return cloudModels.find(m => m.id === cloudRuntimeProvider?.defaultModelId)?.id
3708
+ || cloudModels.find(m => cloudRuntimeProvider?.models.some((entry) => entry.id === m.id && entry.isDefault))?.id
3741
3709
  || cloudModels[0]?.id
3742
- || AGENT_GPT55_DEFAULT_MODEL;
3743
- }, [cloudModels]);
3710
+ || '';
3711
+ }, [cloudModels, cloudRuntimeProvider]);
3744
3712
  useEffect(() => {
3745
3713
  if (!lastLocalModel && localModels.length > 0) {
3746
3714
  setLastLocalModel(localModels[0].id);
@@ -3750,11 +3718,11 @@ export function AgentView(props) {
3750
3718
  if (runtimeProvider.kind === 'acp-provider') {
3751
3719
  return `${runtimeProvider.displayName} - ${acpProviderModelDisplayName}`;
3752
3720
  }
3753
- const baseId = selectedModel.replace(/:thinking$/, '');
3721
+ const baseId = providerRuntimeModelId(selectedModel);
3754
3722
  const cloud = cloudModels.find(m => m.id === baseId);
3755
3723
  if (cloud) {
3756
3724
  if (selectedCloudEffortFamily)
3757
- return cloudModelName(selectedCloudEffortFamily.baseId);
3725
+ return cloudRuntimeProvider?.models.find((entry) => entry.id === selectedCloudEffortFamily.baseId)?.displayName || selectedCloudEffortFamily.baseId;
3758
3726
  return isThinkingVariant ? `${cloud.name} (Thinking)` : cloud.name;
3759
3727
  }
3760
3728
  if (inferenceMode === 'cloud' && sharedProviderCatalogLoaded) {
@@ -3762,7 +3730,7 @@ export function AgentView(props) {
3762
3730
  }
3763
3731
  const local = availableModels.find(m => m.id === actualModelId);
3764
3732
  return local?.name || actualModelId;
3765
- }, [cloudModels, availableModels, selectedModel, actualModelId, selectedCloudEffortFamily, isThinkingVariant, runtimeProvider.kind, runtimeProvider.displayName, acpProviderModelDisplayName, inferenceMode, sharedProviderCatalogLoaded, cloudCatalogUnavailableReason]);
3733
+ }, [cloudModels, cloudRuntimeProvider, availableModels, selectedModel, actualModelId, selectedCloudEffortFamily, isThinkingVariant, runtimeProvider.kind, runtimeProvider.displayName, acpProviderModelDisplayName, inferenceMode, sharedProviderCatalogLoaded, cloudCatalogUnavailableReason]);
3766
3734
  const currentCloudModel = useMemo(() => cloudModels.find(m => m.id === actualModelId), [cloudModels, actualModelId]);
3767
3735
  const cloudModelSelectionMissing = runtimeProvider.kind !== 'acp-provider'
3768
3736
  && inferenceMode === 'cloud'
@@ -3829,7 +3797,7 @@ export function AgentView(props) {
3829
3797
  : 'sdk-native',
3830
3798
  ...(providerId ? { providerId } : {}),
3831
3799
  ...(acpAgentConfigId ? { acpAgentConfigId } : {}),
3832
- model: modelId.replace(/:thinking$/, ''),
3800
+ model: providerRuntimeModelId(modelId),
3833
3801
  }).then((result) => {
3834
3802
  if (bindRevision !== providerLaneSelectionRevisionRef.current)
3835
3803
  return;
@@ -3859,7 +3827,7 @@ export function AgentView(props) {
3859
3827
  const previousSelection = conversation?.runtime?.selection;
3860
3828
  const runtime = createConversationRuntimeBinding({
3861
3829
  selection,
3862
- model: uiModel.replace(/:thinking$/, ''),
3830
+ model: providerRuntimeModelId(uiModel),
3863
3831
  reasoningModel: uiModel,
3864
3832
  inferenceMode: mode,
3865
3833
  });
@@ -3945,7 +3913,7 @@ export function AgentView(props) {
3945
3913
  setModelListOpen(false);
3946
3914
  return;
3947
3915
  }
3948
- const rememberedCloudModel = cloudModels.find((modelEntry) => (modelEntry.id === lastCloudModel.replace(/:thinking$/, '')));
3916
+ const rememberedCloudModel = cloudModels.find((modelEntry) => (modelEntry.id === lastCloudModel));
3949
3917
  const fallbackCloudModel = rememberedCloudModel ? lastCloudModel : preferredGpt55Model;
3950
3918
  setToolStatus(null);
3951
3919
  setInferenceMode('cloud');
@@ -4137,6 +4105,56 @@ export function AgentView(props) {
4137
4105
  const truncateToMessage = useAgentChatStore(s => s.truncateToMessage);
4138
4106
  const switchBranch = useAgentChatStore(s => s.switchBranch);
4139
4107
  const getBranchInfo = useAgentChatStore(s => s.getBranchInfo);
4108
+ const activeNotificationsMap = useAgentChatStore(s => s.activeNotifications);
4109
+ const dismissNotification = useAgentChatStore(s => s.dismissNotification);
4110
+ const availableCommandsMap = useAgentChatStore(s => s.availableCommands);
4111
+ const mcpStatusesMap = useAgentChatStore(s => s.mcpStatuses);
4112
+ const activeNotifsList = useMemo(() => {
4113
+ if (!conversationId)
4114
+ return [];
4115
+ const notifsObj = activeNotificationsMap[conversationId] || {};
4116
+ return Object.values(notifsObj);
4117
+ }, [activeNotificationsMap, conversationId]);
4118
+ const activeMcpList = useMemo(() => {
4119
+ if (!conversationId)
4120
+ return [];
4121
+ const mcpObj = mcpStatusesMap[conversationId] || {};
4122
+ return Object.values(mcpObj);
4123
+ }, [mcpStatusesMap, conversationId]);
4124
+ const activeCommandsList = useMemo(() => {
4125
+ const reported = (conversationId ? availableCommandsMap[conversationId] : undefined) || [];
4126
+ const conv = conversationId ? conversations[conversationId] : undefined;
4127
+ const snap = conv?.capabilitySnapshot;
4128
+ const snapshotCommands = (snap?.commands || []).map((c) => ({
4129
+ name: c.name.startsWith('/') ? c.name : `/${c.name}`,
4130
+ description: c.description,
4131
+ origin: c.origin === 'skill' ? 'skill' : 'provider',
4132
+ }));
4133
+ const snapshotSkills = (snap?.skills || []).map((s) => ({
4134
+ name: s.name.startsWith('/') ? s.name : `/${s.name}`,
4135
+ description: s.description,
4136
+ origin: 'skill',
4137
+ }));
4138
+ const builtIn = [
4139
+ { name: '/run', description: 'Run a command in the project terminal', origin: 'xeno' },
4140
+ { name: '/xeno-clear-view', description: 'Clear conversation history and reset view', origin: 'xeno' },
4141
+ { name: '/clear', description: 'Clear conversation history and reset view', origin: 'xeno' },
4142
+ ];
4143
+ const all = [...snapshotCommands, ...snapshotSkills, ...reported, ...builtIn];
4144
+ const names = new Set();
4145
+ const result = [];
4146
+ for (const c of all) {
4147
+ if (!names.has(c.name)) {
4148
+ names.add(c.name);
4149
+ result.push(c);
4150
+ }
4151
+ }
4152
+ return result;
4153
+ }, [availableCommandsMap, conversationId, conversations]);
4154
+ const [slashCommandIndex, setSlashCommandIndex] = useState(0);
4155
+ const [slashCommandsDismissed, setSlashCommandsDismissed] = useState(false);
4156
+ useEffect(() => { setSlashCommandsDismissed(false); setSlashCommandIndex(0); }, [input, conversationId]);
4157
+ const showSlashCommands = !slashCommandsDismissed && input.startsWith('/') && !input.includes(' ') && activeCommandsList.length > 0;
4140
4158
  const isStreaming = activeRequestId !== null && !!conversationId && activeConversationId === conversationId;
4141
4159
  const isBusy = isStreaming || isRunningCommand;
4142
4160
  const activeCloudRunStatus = activeRequestId ? cloudRuns[activeRequestId] : undefined;
@@ -4230,10 +4248,16 @@ export function AgentView(props) {
4230
4248
  const [sdkCheckpoints, setSdkCheckpoints] = useState([]);
4231
4249
  const [sdkSessions, setSdkSessions] = useState([]);
4232
4250
  const [sdkSessionsLoading, setSdkSessionsLoading] = useState(false);
4251
+ const [sdkSessionBindingBusy, setSdkSessionBindingBusy] = useState(false);
4252
+ const sdkSessionBindingBusyRef = useRef(false);
4233
4253
  const [sdkSessionStatus, setSdkSessionStatus] = useState(null);
4234
4254
  const [backgroundTaskBusy, setBackgroundTaskBusy] = useState({});
4235
4255
  const resolvedTerminalCwd = (sessionUi?.terminalCwd || conversation?.rootDirectory || effectiveAllowedDirectories[0] || '').trim();
4236
4256
  const sdkSessionWorkingDirectory = (conversation?.rootDirectory || effectiveAllowedDirectories[0] || '').trim();
4257
+ const sdkConfirmation = usePreparedConfirmation(JSON.stringify([conversationId, sdkSessionWorkingDirectory, sessionUi?.sdkSessionId, sessionDrawerOpen]));
4258
+ const sdkConfirmationSessionsRef = useRef(sdkSessions);
4259
+ sdkConfirmationSessionsRef.current = sdkSessions;
4260
+ const sdkSessionsRefreshRef = useRef(0);
4237
4261
  const terminalCapabilityEnabled = !!props.capabilities?.terminal;
4238
4262
  const terminalReady = terminalCapabilityEnabled && Boolean(resolvedTerminalCwd || conversation?.id);
4239
4263
  const localModelName = actualModelId.startsWith('local:') ? actualModelId.slice('local:'.length) : actualModelId;
@@ -4256,6 +4280,7 @@ export function AgentView(props) {
4256
4280
  selection,
4257
4281
  model: runtimeModel,
4258
4282
  reasoningModel,
4283
+ reasoningOptionId: selectedReasoningOptionId,
4259
4284
  inferenceMode,
4260
4285
  });
4261
4286
  }, [
@@ -4267,6 +4292,7 @@ export function AgentView(props) {
4267
4292
  runtimeProvider.kind,
4268
4293
  selectedAcpAgentConfigId,
4269
4294
  selectedModel,
4295
+ selectedReasoningOptionId,
4270
4296
  ]);
4271
4297
  const skipConversationModelPersistRef = useRef(false);
4272
4298
  useEffect(() => {
@@ -4290,6 +4316,8 @@ export function AgentView(props) {
4290
4316
  const target = event.target;
4291
4317
  if (sessionPanelRef.current?.contains(target))
4292
4318
  return;
4319
+ if (target instanceof Element && target.closest('[role="dialog"]'))
4320
+ return;
4293
4321
  setSessionDrawerOpen(false);
4294
4322
  };
4295
4323
  const timer = window.setTimeout(() => document.addEventListener('mousedown', handleClick), 0);
@@ -4331,29 +4359,36 @@ export function AgentView(props) {
4331
4359
  const loadSdkSessions = useCallback(async () => {
4332
4360
  if (!getAgentPlatformBridge()?.agent?.listSdkSessions)
4333
4361
  return;
4362
+ const viewCurrent = sdkConfirmation.capture();
4363
+ const version = ++sdkSessionsRefreshRef.current;
4364
+ const current = () => viewCurrent() && sdkSessionsRefreshRef.current === version;
4334
4365
  setSdkSessionsLoading(true);
4335
4366
  try {
4336
4367
  const result = await getAgentPlatformBridge().agent.listSdkSessions({
4337
4368
  workingDirectory: sdkSessionWorkingDirectory || undefined,
4338
4369
  limit: 40,
4339
4370
  });
4340
- if (!result.success && sdkSessionWorkingDirectory) {
4341
- const fallback = await getAgentPlatformBridge().agent.listSdkSessions({ limit: 40 });
4342
- setSdkSessions(Array.isArray(fallback.sessions) ? fallback.sessions : []);
4343
- setSdkSessionStatus(fallback.success ? null : (fallback.error || 'Unable to load SDK sessions.'));
4371
+ if (!current())
4344
4372
  return;
4373
+ // A failed scoped read must not silently expose another workspace's sessions.
4374
+ if (!result.success) {
4375
+ setSdkSessionStatus(result.error || 'Unable to load SDK sessions.');
4376
+ return false;
4345
4377
  }
4346
4378
  setSdkSessions(Array.isArray(result.sessions) ? result.sessions : []);
4347
- setSdkSessionStatus(result.success ? null : (result.error || 'Unable to load SDK sessions.'));
4379
+ setSdkSessionStatus(null);
4380
+ return true;
4348
4381
  }
4349
4382
  catch (error) {
4350
- setSdkSessions([]);
4351
- setSdkSessionStatus(error instanceof Error ? error.message : String(error));
4383
+ if (current())
4384
+ setSdkSessionStatus(error instanceof Error ? error.message : String(error));
4385
+ return false;
4352
4386
  }
4353
4387
  finally {
4354
- setSdkSessionsLoading(false);
4388
+ if (current())
4389
+ setSdkSessionsLoading(false);
4355
4390
  }
4356
- }, [sdkSessionWorkingDirectory]);
4391
+ }, [sdkSessionWorkingDirectory, sdkConfirmation.capture]);
4357
4392
  useEffect(() => {
4358
4393
  if (!sessionDrawerOpen)
4359
4394
  return;
@@ -4467,11 +4502,12 @@ export function AgentView(props) {
4467
4502
  requestedModel,
4468
4503
  catalog: cloudModels,
4469
4504
  hasConversationHistory: (conversation?.messages.length || 0) > 0,
4470
- preferredModelIds: [AGENT_GPT55_DEFAULT_MODEL, 'gpt-5.5'],
4505
+ preferredModelIds: preferredGpt55Model ? [preferredGpt55Model] : [],
4471
4506
  })
4472
4507
  : { model: requestedModel, status: 'preserved' };
4473
4508
  const reconciledModel = reconciliation.model;
4474
4509
  const targetModel = reconciliation.status !== 'defaulted'
4510
+ && requestedExecutionMode === 'local'
4475
4511
  && storedRuntime?.reasoning.effort === 'thinking'
4476
4512
  && !requestedModel.endsWith(':thinking')
4477
4513
  && !requestedModel.endsWith('-thinking')
@@ -4494,7 +4530,7 @@ export function AgentView(props) {
4494
4530
  const selection = storedRuntime?.selection || props.runtimeSelection || runtimeSelectionForSdk('migration');
4495
4531
  const runtime = createConversationRuntimeBinding({
4496
4532
  selection,
4497
- model: targetModel.replace(/:thinking$/, ''),
4533
+ model: providerRuntimeModelId(targetModel),
4498
4534
  reasoningModel: targetModel,
4499
4535
  inferenceMode: 'cloud',
4500
4536
  migrationSource: 'model',
@@ -4526,8 +4562,9 @@ export function AgentView(props) {
4526
4562
  const runtimeSelection = effectiveRuntimeSelection || runtimeSelectionForSdk('migration');
4527
4563
  const runtime = createConversationRuntimeBinding({
4528
4564
  selection: runtimeSelection,
4529
- model: selectedModel.replace(/:thinking$/, ''),
4565
+ model: providerRuntimeModelId(selectedModel),
4530
4566
  reasoningModel: selectedModel,
4567
+ reasoningOptionId: selectedReasoningOptionId,
4531
4568
  inferenceMode,
4532
4569
  });
4533
4570
  const isSdkRuntime = runtime.selection.providerKind === 'sdk-native';
@@ -4549,6 +4586,7 @@ export function AgentView(props) {
4549
4586
  effectiveRuntimeSelection,
4550
4587
  inferenceMode,
4551
4588
  selectedModel,
4589
+ selectedReasoningOptionId,
4552
4590
  updateConversation,
4553
4591
  ]);
4554
4592
  useEffect(() => {
@@ -4565,19 +4603,17 @@ export function AgentView(props) {
4565
4603
  return () => window.clearInterval(interval);
4566
4604
  }, [isStreaming, refreshLocalRuntimeState, runtimeStatusRefreshKey, selectedModel]);
4567
4605
  // Suggestion store
4568
- const detectSuggestionModel = useSuggestionStore(s => s.detectSuggestionModel);
4569
4606
  const generateGhostText = useSuggestionStore(s => s.generateGhostText);
4570
4607
  const clearGhostText = useSuggestionStore(s => s.clearGhostText);
4571
4608
  const clearAllSuggestions = useSuggestionStore(s => s.clearAll);
4572
4609
  const ghostText = useSuggestionStore(s => s.ghostText);
4573
- const suggestionMode = useSuggestionStore(s => s.suggestionMode);
4574
- const setSuggestionMode = useSuggestionStore(s => s.setSuggestionMode);
4575
- const localModel = useSuggestionStore(s => s.localModel);
4576
- const suggestionsAvailable = suggestionMode === 'cloud' || !!localModel;
4577
- // Detect suggestion model on mount
4578
- useEffect(() => {
4579
- void detectSuggestionModel();
4580
- }, [detectSuggestionModel]);
4610
+ const [suggestionOptInScope, setSuggestionOptInScope] = useState(null);
4611
+ const suggestionScope = JSON.stringify([conversationId, runtimeMode, actualModelId]);
4612
+ const suggestionModelAvailable = runtimeMode === 'cloud'
4613
+ ? cloudModels.some(model => model.id === actualModelId)
4614
+ : runtimeMode === 'local' && localModels.some(model => model.id === actualModelId);
4615
+ const suggestionsAvailable = suggestionModelAvailable && suggestionOptInScope === suggestionScope;
4616
+ useEffect(() => { clearAllSuggestions(); return () => clearAllSuggestions(); }, [suggestionScope, clearAllSuggestions]);
4581
4617
  // Generate ghost text after assistant finishes responding.
4582
4618
  // Quick-reply pills were removed from the composer surface to keep it clean.
4583
4619
  useEffect(() => {
@@ -4589,11 +4625,13 @@ export function AgentView(props) {
4589
4625
  if (last.role !== 'assistant' || last.isStreaming || last.isCommandResult || last.command)
4590
4626
  return;
4591
4627
  const contextMsgs = runtimeProjectedMessages.slice(-6).map(m => ({ role: m.role, content: m.content }));
4592
- void generateGhostText('', contextMsgs, agentName);
4593
- }, [runtimeProjectedMessages, isBusy, suggestionsAvailable, conversationId, agentName, generateGhostText]);
4628
+ if (runtimeMode === 'acp')
4629
+ return;
4630
+ void generateGhostText('', contextMsgs, agentName, { scopeId: conversationId, model: actualModelId, source: runtimeMode });
4631
+ }, [runtimeProjectedMessages, isBusy, suggestionsAvailable, conversationId, agentName, generateGhostText, actualModelId, runtimeMode]);
4594
4632
  // Ghost text prefix matching
4595
4633
  const effectiveGhostText = useMemo(() => {
4596
- if (!ghostText || isBusy)
4634
+ if (!suggestionsAvailable || !ghostText || isBusy)
4597
4635
  return '';
4598
4636
  if (!input)
4599
4637
  return ghostText;
@@ -4601,7 +4639,7 @@ export function AgentView(props) {
4601
4639
  return ghostText.slice(input.length);
4602
4640
  }
4603
4641
  return '';
4604
- }, [ghostText, input, isBusy]);
4642
+ }, [ghostText, input, isBusy, suggestionsAvailable]);
4605
4643
  // Setup IPC listeners
4606
4644
  useEffect(() => {
4607
4645
  const cleanup = setupAgentChatListeners();
@@ -6144,6 +6182,158 @@ export function AgentView(props) {
6144
6182
  runDeterministicFileCreate,
6145
6183
  workspaceBindingPrompt
6146
6184
  ]);
6185
+ const runCliCommandInTerminal = async (rawCommand, targetConversationId) => {
6186
+ appendMessage(targetConversationId, { role: 'user', content: rawCommand });
6187
+ const command = normalizePowerShellCommand(rawCommand);
6188
+ if (!command) {
6189
+ appendMessage(targetConversationId, { role: 'assistant', content: 'Empty command.', error: 'Invalid command' });
6190
+ if (textareaRef.current)
6191
+ textareaRef.current.style.height = 'auto';
6192
+ return;
6193
+ }
6194
+ if (!capabilities?.terminal) {
6195
+ appendMessage(targetConversationId, { role: 'assistant', content: 'Terminal capability is disabled for this agent.', error: 'Terminal capability is disabled for this agent.' });
6196
+ if (textareaRef.current)
6197
+ textareaRef.current.style.height = 'auto';
6198
+ return;
6199
+ }
6200
+ if (workspaceBinding.mode === 'workspace' && effectiveAllowedDirectories.length === 0) {
6201
+ appendMessage(targetConversationId, { role: 'assistant', content: 'No allowed directories configured. Open agent settings and add one.', error: 'No allowed directories configured.' });
6202
+ if (textareaRef.current)
6203
+ textareaRef.current.style.height = 'auto';
6204
+ return;
6205
+ }
6206
+ if (!getAgentPlatformBridge()?.workspace) {
6207
+ appendMessage(targetConversationId, { role: 'assistant', content: 'Workspace terminal bridge not available. Restart app.', error: 'Workspace terminal bridge not available.' });
6208
+ if (textareaRef.current)
6209
+ textareaRef.current.style.height = 'auto';
6210
+ return;
6211
+ }
6212
+ setIsRunningCommand(true);
6213
+ const result = await getAgentPlatformBridge().workspace.runCommand({
6214
+ command,
6215
+ cwd: effectiveAllowedDirectories[0] || conversation?.rootDirectory || '',
6216
+ allowedDirs: effectiveAllowedDirectories,
6217
+ conversationId: targetConversationId,
6218
+ });
6219
+ setIsRunningCommand(false);
6220
+ const blocks = [];
6221
+ blocks.push(`$ ${command}`);
6222
+ if (result.cwd)
6223
+ blocks.push(`cwd: ${result.cwd}`);
6224
+ if (result.stdout?.trim())
6225
+ blocks.push(result.stdout.trim());
6226
+ if (result.stderr?.trim())
6227
+ blocks.push(`[stderr]\n${result.stderr.trim()}`);
6228
+ if (result.error)
6229
+ blocks.push(`[error] ${result.error}`);
6230
+ blocks.push(`exit: ${result.exitCode ?? 'n/a'}`);
6231
+ appendMessage(targetConversationId, {
6232
+ role: 'assistant',
6233
+ content: `\`\`\`\n${blocks.join('\n\n')}\n\`\`\``,
6234
+ error: result.success ? undefined : (result.error || 'Command failed'),
6235
+ command,
6236
+ isCommandResult: true
6237
+ });
6238
+ if (textareaRef.current)
6239
+ textareaRef.current.style.height = 'auto';
6240
+ };
6241
+ const handleExecuteCommandOrPrompt = async (rawCommand) => {
6242
+ const trimmed = rawCommand.trim();
6243
+ if (!trimmed)
6244
+ return;
6245
+ const targetConversationId = ensureConversationId(conversationId);
6246
+ // 1. Explicitly namespaced UI presentation commands (origin: "xeno-ui")
6247
+ if (trimmed === '/xeno-clear-view' || trimmed === '/clear') {
6248
+ appendMessage(targetConversationId, { role: 'user', content: trimmed });
6249
+ updateConversation(targetConversationId, { messages: [] });
6250
+ if (textareaRef.current)
6251
+ textareaRef.current.style.height = 'auto';
6252
+ return;
6253
+ }
6254
+ // 2. Project terminal CLI execution
6255
+ if (trimmed.startsWith('codex ') || trimmed.startsWith('/run ')) {
6256
+ const cliCmd = trimmed.startsWith('/run ') ? trimmed.slice(5).trim() : trimmed;
6257
+ await runCliCommandInTerminal(cliCmd, targetConversationId);
6258
+ return;
6259
+ }
6260
+ // 3. Provider commands (/compact, /model, /status, /mcp, /help, etc.)
6261
+ // Thin client: Never synthesize fake local message slicing or fake state.
6262
+ appendMessage(targetConversationId, { role: 'user', content: trimmed });
6263
+ if (textareaRef.current)
6264
+ textareaRef.current.style.height = 'auto';
6265
+ const conv = conversations[targetConversationId];
6266
+ const bridge = getAgentPlatformBridge();
6267
+ if (trimmed.startsWith('/')) {
6268
+ const [cmdToken, ...argTokens] = trimmed.split(' ');
6269
+ const commandId = cmdToken.startsWith('/') ? cmdToken.slice(1) : cmdToken;
6270
+ const rawArg = argTokens.join(' ').trim();
6271
+ if (bridge?.acp?.invokeCommand) {
6272
+ const commandRequestId = `command-${crypto.randomUUID()}`;
6273
+ appendMessage(targetConversationId, {
6274
+ id: commandRequestId, role: 'assistant', content: '', isStreaming: true,
6275
+ });
6276
+ const finishCommand = (content, error) => {
6277
+ const current = useAgentChatStore.getState().conversations[targetConversationId];
6278
+ if (!current)
6279
+ return;
6280
+ updateConversation(targetConversationId, {
6281
+ messages: current.messages.map(message => message.id === commandRequestId
6282
+ ? { ...message, content: message.content || content, isStreaming: false, error }
6283
+ : message),
6284
+ });
6285
+ };
6286
+ try {
6287
+ const res = await bridge.acp.invokeCommand({
6288
+ conversationId: targetConversationId,
6289
+ sessionId: conv?.sessionUi?.acpSessionId,
6290
+ commandId,
6291
+ rawInput: trimmed,
6292
+ args: buildProviderCommandArgs(commandId, rawArg),
6293
+ idempotencyKey: commandRequestId,
6294
+ });
6295
+ if (res.success && res.commandEvent) {
6296
+ const ev = res.commandEvent;
6297
+ const outputRecord = ev.output && typeof ev.output === 'object'
6298
+ ? ev.output : undefined;
6299
+ if (ev.phase === 'completed') {
6300
+ const output = typeof ev.output === 'string' ? ev.output
6301
+ : typeof outputRecord?.message === 'string' ? outputRecord.message
6302
+ : outputRecord ? JSON.stringify(outputRecord, null, 2) : undefined;
6303
+ const newModel = typeof outputRecord?.model === 'string' ? outputRecord.model
6304
+ : typeof ev.model === 'string' ? ev.model : undefined;
6305
+ finishCommand(output || `Command \`${trimmed}\` completed.`);
6306
+ if (newModel) {
6307
+ setSelectedModel(newModel);
6308
+ updateConversation(targetConversationId, { model: newModel });
6309
+ }
6310
+ return;
6311
+ }
6312
+ const errObj = ev.error;
6313
+ finishCommand(typeof errObj?.message === 'string' ? errObj.message
6314
+ : ev.phase === 'cancelled' ? 'Command cancelled.' : 'Provider command did not complete.', typeof errObj?.code === 'string' ? errObj.code : ev.phase === 'cancelled' ? 'COMMAND_CANCELLED' : 'COMMAND_FAILED');
6315
+ return;
6316
+ }
6317
+ finishCommand(res.error || 'Provider command returned no terminal result.', 'COMMAND_INVOCATION_FAILED');
6318
+ return;
6319
+ }
6320
+ catch (err) {
6321
+ finishCommand(err instanceof Error ? err.message : String(err), 'COMMAND_EXCEPTION');
6322
+ return;
6323
+ }
6324
+ }
6325
+ else {
6326
+ appendMessage(targetConversationId, {
6327
+ role: 'assistant',
6328
+ content: `Platform bridge does not support command invocation for \`${trimmed}\`.`,
6329
+ error: 'UNSUPPORTED_PLATFORM_BRIDGE',
6330
+ });
6331
+ return;
6332
+ }
6333
+ }
6334
+ // Forward to provider prompt turn
6335
+ void dispatchSend(trimmed, [], targetConversationId, { appendUserMessage: false });
6336
+ };
6147
6337
  const handleSend = async () => {
6148
6338
  clearAllSuggestions();
6149
6339
  const trimmed = input.trim();
@@ -6349,61 +6539,9 @@ export function AgentView(props) {
6349
6539
  setBlockedFileActionPrompt(null);
6350
6540
  setInput('');
6351
6541
  const targetConversationId = ensureConversationId(conversationId);
6352
- if (trimmed.startsWith('/run ') && !hasAttachments) {
6353
- appendMessage(targetConversationId, { role: 'user', content: trimmed });
6354
- const command = normalizePowerShellCommand(trimmed.slice(5).trim());
6355
- if (!command) {
6356
- appendMessage(targetConversationId, { role: 'assistant', content: 'Usage: /run <command>', error: 'Usage: /run <command>' });
6357
- if (textareaRef.current)
6358
- textareaRef.current.style.height = 'auto';
6359
- return;
6360
- }
6361
- if (!capabilities?.terminal) {
6362
- appendMessage(targetConversationId, { role: 'assistant', content: 'Terminal capability is disabled for this agent.', error: 'Terminal capability is disabled for this agent.' });
6363
- if (textareaRef.current)
6364
- textareaRef.current.style.height = 'auto';
6365
- return;
6366
- }
6367
- if (workspaceBinding.mode === 'workspace' && effectiveAllowedDirectories.length === 0) {
6368
- appendMessage(targetConversationId, { role: 'assistant', content: 'No allowed directories configured. Open agent settings and add one.', error: 'No allowed directories configured.' });
6369
- if (textareaRef.current)
6370
- textareaRef.current.style.height = 'auto';
6371
- return;
6372
- }
6373
- if (!getAgentPlatformBridge()?.workspace) {
6374
- appendMessage(targetConversationId, { role: 'assistant', content: 'Workspace terminal bridge not available. Restart app.', error: 'Workspace terminal bridge not available.' });
6375
- if (textareaRef.current)
6376
- textareaRef.current.style.height = 'auto';
6377
- return;
6378
- }
6379
- setIsRunningCommand(true);
6380
- const result = await getAgentPlatformBridge().workspace.runCommand({
6381
- command,
6382
- cwd: effectiveAllowedDirectories[0] || '',
6383
- allowedDirs: effectiveAllowedDirectories,
6384
- conversationId: targetConversationId,
6385
- });
6386
- setIsRunningCommand(false);
6387
- const blocks = [];
6388
- blocks.push(`$ ${command}`);
6389
- if (result.cwd)
6390
- blocks.push(`cwd: ${result.cwd}`);
6391
- if (result.stdout?.trim())
6392
- blocks.push(result.stdout.trim());
6393
- if (result.stderr?.trim())
6394
- blocks.push(`[stderr]\n${result.stderr.trim()}`);
6395
- if (result.error)
6396
- blocks.push(`[error] ${result.error}`);
6397
- blocks.push(`exit: ${result.exitCode ?? 'n/a'}`);
6398
- appendMessage(targetConversationId, {
6399
- role: 'assistant',
6400
- content: `\`\`\`\n${blocks.join('\n\n')}\n\`\`\``,
6401
- error: result.success ? undefined : (result.error || 'Command failed'),
6402
- command,
6403
- isCommandResult: true
6404
- });
6405
- if (textareaRef.current)
6406
- textareaRef.current.style.height = 'auto';
6542
+ if (!hasAttachments && (trimmed.startsWith('/') ||
6543
+ trimmed.startsWith('codex '))) {
6544
+ await handleExecuteCommandOrPrompt(trimmed);
6407
6545
  return;
6408
6546
  }
6409
6547
  if (inferenceMode === 'cloud' && cloudModelUnavailable) {
@@ -6420,6 +6558,39 @@ export function AgentView(props) {
6420
6558
  dispatchSend(trimmed, attachmentsToSend, targetConversationId);
6421
6559
  };
6422
6560
  const handleKeyDown = (e) => {
6561
+ if (showSlashCommands) {
6562
+ const cleanFilter = input.slice(1).toLowerCase();
6563
+ const filtered = activeCommandsList.filter((cmd) => {
6564
+ const nameWithoutSlash = cmd.name.startsWith('/') ? cmd.name.slice(1).toLowerCase() : cmd.name.toLowerCase();
6565
+ return nameWithoutSlash.includes(cleanFilter) || (cmd.description && cmd.description.toLowerCase().includes(cleanFilter));
6566
+ });
6567
+ if (filtered.length > 0) {
6568
+ if (e.key === 'ArrowDown') {
6569
+ e.preventDefault();
6570
+ setSlashCommandIndex((prev) => (prev + 1) % filtered.length);
6571
+ return;
6572
+ }
6573
+ if (e.key === 'ArrowUp') {
6574
+ e.preventDefault();
6575
+ setSlashCommandIndex((prev) => (prev - 1 + filtered.length) % filtered.length);
6576
+ return;
6577
+ }
6578
+ if (e.key === 'Tab' || (e.key === 'Enter' && !e.shiftKey)) {
6579
+ e.preventDefault();
6580
+ const chosen = filtered[slashCommandIndex] || filtered[0];
6581
+ if (chosen) {
6582
+ const cmdText = (chosen.name.startsWith('/') ? chosen.name : `/${chosen.name}`) + ' ';
6583
+ setInput(cmdText);
6584
+ return;
6585
+ }
6586
+ }
6587
+ if (e.key === 'Escape') {
6588
+ e.preventDefault();
6589
+ setSlashCommandsDismissed(true);
6590
+ return;
6591
+ }
6592
+ }
6593
+ }
6423
6594
  if (e.key === 'Enter' && !e.shiftKey) {
6424
6595
  e.preventDefault();
6425
6596
  void handleSend();
@@ -6477,7 +6648,7 @@ export function AgentView(props) {
6477
6648
  appendMessage(conversationId, { role: 'user', content: rerunContent });
6478
6649
  const sendOptions = {
6479
6650
  appendUserMessage: false,
6480
- enableThinking: rerunModel.endsWith(':thinking'),
6651
+ enableThinking: rerunModel.startsWith('local:') && rerunModel.endsWith(':thinking'),
6481
6652
  capabilities,
6482
6653
  permissionProfile: props.permissionProfile || 'standard',
6483
6654
  allowedDirectories: effectiveAllowedDirectories,
@@ -7024,53 +7195,78 @@ export function AgentView(props) {
7024
7195
  };
7025
7196
  }, [backgroundTasks, conversationId, patchBackgroundTask]);
7026
7197
  const handleAttachSdkSession = useCallback(async (sessionId) => {
7027
- if (!conversationId || !getAgentPlatformBridge()?.agent?.attachSdkSession)
7198
+ const service = getOptionalAgentPlatformBridge()?.agent;
7199
+ if (!conversationId || !service?.attachSdkSession || sdkSessionBindingBusyRef.current)
7200
+ return;
7201
+ const viewCurrent = sdkConfirmation.capture();
7202
+ const version = (() => {
7203
+ const item = sdkConfirmationSessionsRef.current.find(entry => entry.id === sessionId || entry.sessionId === sessionId);
7204
+ return item ? JSON.stringify(item) : undefined;
7205
+ })();
7206
+ if (!version) {
7207
+ setSdkSessionStatus('The selected SDK session is no longer in this workspace list.');
7028
7208
  return;
7209
+ }
7210
+ sdkSessionBindingBusyRef.current = true;
7211
+ setSdkSessionBindingBusy(true);
7029
7212
  setSdkSessionStatus('Attaching SDK session...');
7030
7213
  try {
7031
- const result = await getAgentPlatformBridge().agent.attachSdkSession({ conversationId, sessionId });
7032
- if (!result.success) {
7033
- setSdkSessionStatus(result.error || 'Unable to attach SDK session.');
7034
- setToolStatus(result.error || 'Unable to attach SDK session.');
7214
+ const result = await service.attachSdkSession({ conversationId, sessionId });
7215
+ const latest = useAgentChatStore.getState().getConversation(conversationId);
7216
+ const currentItem = sdkConfirmationSessionsRef.current.find(entry => entry.id === sessionId || entry.sessionId === sessionId);
7217
+ if (!viewCurrent() || !latest || JSON.stringify(currentItem) !== version)
7035
7218
  return;
7036
- }
7037
- patchSessionUi({
7038
- sdkSessionId: sessionId,
7039
- sdkSessionDir: result.sessionDir,
7040
- sdkSessionHistoryPath: result.sessionHistoryPath,
7041
- });
7219
+ if (!result.success)
7220
+ throw new Error(result.error || 'Unable to attach SDK session.');
7221
+ updateConversation(conversationId, { sessionUi: { ...(latest.sessionUi || {}), sdkSessionId: sessionId,
7222
+ sdkSessionDir: result.sessionDir, sdkSessionHistoryPath: result.sessionHistoryPath } });
7042
7223
  setSdkCheckpoints(Array.isArray(result.checkpoints) ? result.checkpoints : []);
7043
7224
  setSdkSessionStatus('SDK session attached. The next turn will resume it.');
7044
7225
  setToolStatus('SDK session attached.');
7045
7226
  }
7046
7227
  catch (error) {
7047
- const message = error instanceof Error ? error.message : 'Unable to attach SDK session.';
7048
- setSdkSessionStatus(message);
7049
- setToolStatus(message);
7228
+ if (viewCurrent()) {
7229
+ const message = error instanceof Error ? error.message : 'Unable to attach SDK session.';
7230
+ setSdkSessionStatus(message);
7231
+ setToolStatus(message);
7232
+ }
7050
7233
  }
7051
- }, [conversationId, patchSessionUi, setToolStatus]);
7234
+ finally {
7235
+ sdkSessionBindingBusyRef.current = false;
7236
+ if (viewCurrent())
7237
+ setSdkSessionBindingBusy(false);
7238
+ }
7239
+ }, [conversationId, sdkConfirmation.capture, setToolStatus, updateConversation]);
7052
7240
  const handleDetachSdkSession = useCallback(async () => {
7053
- if (!conversationId || !getAgentPlatformBridge()?.agent?.detachSdkSession)
7241
+ const service = getOptionalAgentPlatformBridge()?.agent;
7242
+ const sessionId = sessionUi?.sdkSessionId;
7243
+ if (!conversationId || !sessionId || !service?.detachSdkSession || sdkSessionBindingBusyRef.current)
7054
7244
  return;
7245
+ const viewCurrent = sdkConfirmation.capture();
7246
+ sdkSessionBindingBusyRef.current = true;
7247
+ setSdkSessionBindingBusy(true);
7055
7248
  setSdkSessionStatus('Detaching SDK session...');
7056
7249
  try {
7057
- const result = await getAgentPlatformBridge().agent.detachSdkSession({ conversationId });
7058
- if (!result.success) {
7059
- setSdkSessionStatus(result.error || 'Unable to detach SDK session.');
7250
+ const result = await service.detachSdkSession({ conversationId });
7251
+ const latest = useAgentChatStore.getState().getConversation(conversationId);
7252
+ if (!viewCurrent() || latest?.sessionUi?.sdkSessionId !== sessionId)
7060
7253
  return;
7061
- }
7062
- patchSessionUi({
7063
- sdkSessionId: undefined,
7064
- sdkSessionDir: undefined,
7065
- sdkSessionHistoryPath: undefined,
7066
- });
7254
+ if (!result.success)
7255
+ throw new Error(result.error || 'Unable to detach SDK session.');
7256
+ updateConversation(conversationId, { sessionUi: { ...latest.sessionUi, sdkSessionId: undefined, sdkSessionDir: undefined, sdkSessionHistoryPath: undefined } });
7067
7257
  setSdkCheckpoints([]);
7068
7258
  setSdkSessionStatus('Detached. The next turn will create a fresh SDK session.');
7069
7259
  }
7070
7260
  catch (error) {
7071
- setSdkSessionStatus(error instanceof Error ? error.message : 'Unable to detach SDK session.');
7261
+ if (viewCurrent())
7262
+ setSdkSessionStatus(error instanceof Error ? error.message : 'Unable to detach SDK session.');
7263
+ }
7264
+ finally {
7265
+ sdkSessionBindingBusyRef.current = false;
7266
+ if (viewCurrent())
7267
+ setSdkSessionBindingBusy(false);
7072
7268
  }
7073
- }, [conversationId, patchSessionUi]);
7269
+ }, [conversationId, sdkConfirmation.capture, sessionUi?.sdkSessionId, updateConversation]);
7074
7270
  const handleRepairRuntimeEventLog = useCallback(async () => {
7075
7271
  if (!conversationId || !getAgentPlatformBridge()?.runtimeEvents?.repair || !getAgentPlatformBridge()?.runtimeEvents?.list)
7076
7272
  return;
@@ -7110,55 +7306,38 @@ export function AgentView(props) {
7110
7306
  setToolStatus(message);
7111
7307
  }
7112
7308
  }, [conversationId, patchSessionUi, setToolStatus]);
7113
- const handleDeleteSdkSession = useCallback(async (sessionId) => {
7114
- if (!getAgentPlatformBridge()?.agent?.deleteSdkSession)
7115
- return;
7116
- if (!window.confirm(`Delete SDK session ${sessionId}? This removes its SDK transcript and checkpoints from disk.`))
7117
- return;
7118
- setSdkSessionStatus('Deleting SDK session...');
7119
- try {
7120
- const result = await getAgentPlatformBridge().agent.deleteSdkSession({ sessionId });
7121
- if (!result.success) {
7122
- setSdkSessionStatus(result.error || 'Unable to delete SDK session.');
7309
+ const sdkDestructiveActions = sdkConfirmationActions({
7310
+ gate: sdkConfirmation,
7311
+ service: () => getOptionalAgentPlatformBridge()?.agent,
7312
+ workingDirectory: sdkSessionWorkingDirectory,
7313
+ attachedId: sessionUi?.sdkSessionId,
7314
+ currentAttachedId: () => conversationId ? useAgentChatStore.getState().getConversation(conversationId)?.sessionUi?.sdkSessionId : undefined,
7315
+ targetVersion: sessionId => {
7316
+ const item = sdkConfirmationSessionsRef.current.find(entry => entry.id === sessionId || entry.sessionId === sessionId);
7317
+ return item ? JSON.stringify(item) : undefined;
7318
+ },
7319
+ collectionVersion: () => JSON.stringify(sdkConfirmationSessionsRef.current),
7320
+ mutationAllowed: () => {
7321
+ if (sdkSessionBindingBusyRef.current)
7322
+ return false;
7323
+ const latest = conversationId ? useAgentChatStore.getState().getConversation(conversationId) : undefined;
7324
+ return !!latest && !useAgentChatStore.getState().activeRequestId
7325
+ && latest.sessionUi?.activeLane?.status !== 'active_native' && latest.sessionUi?.activeLane?.status !== 'active_structured';
7326
+ },
7327
+ detachDeleted: sessionId => {
7328
+ if (!conversationId)
7123
7329
  return;
7124
- }
7125
- if (sessionUi?.sdkSessionId === sessionId) {
7126
- patchSessionUi({
7127
- sdkSessionId: undefined,
7128
- sdkSessionDir: undefined,
7129
- sdkSessionHistoryPath: undefined,
7130
- });
7131
- setSdkCheckpoints([]);
7132
- }
7133
- await loadSdkSessions();
7134
- setSdkSessionStatus('SDK session deleted.');
7135
- }
7136
- catch (error) {
7137
- setSdkSessionStatus(error instanceof Error ? error.message : 'Unable to delete SDK session.');
7138
- }
7139
- }, [loadSdkSessions, patchSessionUi, sessionUi?.sdkSessionId]);
7140
- const handleCleanSdkSessions = useCallback(async () => {
7141
- if (!sdkSessionWorkingDirectory || !getAgentPlatformBridge()?.agent?.cleanSdkSessions)
7142
- return;
7143
- if (!window.confirm(`Delete old SDK sessions for ${sdkSessionWorkingDirectory}? The currently attached session will be kept.`))
7144
- return;
7145
- setSdkSessionStatus('Cleaning old SDK sessions...');
7146
- try {
7147
- const result = await getAgentPlatformBridge().agent.cleanSdkSessions({
7148
- workingDirectory: sdkSessionWorkingDirectory,
7149
- excludeSessionIds: sessionUi?.sdkSessionId ? [sessionUi.sdkSessionId] : [],
7150
- });
7151
- if (!result.success) {
7152
- setSdkSessionStatus(result.error || 'Unable to clean SDK sessions.');
7330
+ const latest = useAgentChatStore.getState().getConversation(conversationId);
7331
+ if (latest?.sessionUi?.sdkSessionId !== sessionId)
7153
7332
  return;
7154
- }
7155
- await loadSdkSessions();
7156
- setSdkSessionStatus('Old SDK sessions cleaned.');
7157
- }
7158
- catch (error) {
7159
- setSdkSessionStatus(error instanceof Error ? error.message : 'Unable to clean SDK sessions.');
7160
- }
7161
- }, [loadSdkSessions, sdkSessionWorkingDirectory, sessionUi?.sdkSessionId]);
7333
+ updateConversation(conversationId, { sessionUi: { ...latest.sessionUi, sdkSessionId: undefined, sdkSessionDir: undefined, sdkSessionHistoryPath: undefined } });
7334
+ setSdkCheckpoints([]);
7335
+ },
7336
+ status: setSdkSessionStatus,
7337
+ refresh: loadSdkSessions,
7338
+ });
7339
+ const handleDeleteSdkSession = sdkDestructiveActions.remove;
7340
+ const handleCleanSdkSessions = sdkDestructiveActions.clean;
7162
7341
  const handleRemoveQueuedConversationTurn = useCallback((queuedTurnId) => {
7163
7342
  if (!conversationId)
7164
7343
  return;
@@ -7286,7 +7465,13 @@ export function AgentView(props) {
7286
7465
  terminalDraftInput,
7287
7466
  updateConversation,
7288
7467
  ]);
7289
- return (_jsxs("div", { className: "xeno-app-shell flex-1 relative min-h-0", children: [_jsx("div", { ref: messagesScrollRef, className: "agent-scrollbar absolute inset-0 overflow-auto pr-1.5", style: { scrollbarGutter: 'stable' }, children: conversationHydrating ? (_jsx(ConversationLoadingSkeleton, {})) : (_jsxs("div", { className: "w-full max-w-[820px] mx-auto px-6 pt-6 min-h-full flex flex-col gap-1.5", style: { paddingBottom: messageViewportBottomPadding }, children: [conversation?.sessionUi?.parentConversationId && props.onNavigateConversation && (_jsx("div", { className: "sticky top-2 z-[21] -mx-1 px-1 pb-2", children: _jsxs("button", { type: "button", onClick: () => props.onNavigateConversation?.(conversation.sessionUi?.parentConversationId || ''), className: "xeno-border-subtle w-full rounded-[6px] border bg-[#111111] px-3 py-2 text-left text-[11px] text-white/48 hover:bg-white/[0.045] hover:text-white/72 transition-colors inline-flex items-center gap-2", children: [_jsx(ChevronLeft, { className: "h-3.5 w-3.5" }), _jsx("span", { children: "Back to parent agent" }), _jsx("span", { className: "ml-auto text-[10px] text-white/22 truncate", children: agentName })] }) })), conversation && devSessionOpen && (_jsx("div", { className: "sticky top-2 z-[20] -mx-1 px-1 pb-2", children: _jsxs("div", { className: "xeno-border-subtle rounded-[6px] border bg-[#111111] px-3 py-2 flex items-center justify-between gap-3", children: [_jsxs("div", { className: "flex items-center gap-3 min-w-0 flex-wrap", children: [_jsx("span", { className: "text-[10px] uppercase tracking-[0.14em] text-white/28", children: "Dev session" }), _jsx("span", { className: `text-[10px] uppercase tracking-[0.14em] ${sessionStatusClassName}`, children: sessionStatusLabel }), _jsxs("span", { className: "text-[10px] text-white/24 tabular-nums", children: [pendingTurns.length, " queued"] }), _jsxs("span", { className: "text-[10px] text-white/24 tabular-nums", children: [checkpoints.length, " checkpoints"] }), _jsxs("span", { className: "text-[10px] text-white/18", children: ["Last active ", new Date(conversation.lastMessageAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })] })] }), _jsxs("div", { className: "flex items-center gap-1.5 flex-shrink-0", children: [_jsxs("button", { type: "button", onClick: () => { void handleCopyDebugSnapshot('standard'); }, disabled: !conversationId || conversationHydrating, className: "h-7 px-2.5 rounded-[4px] bg-white/[0.05] hover:bg-white/[0.08] text-[10px] text-white/55 hover:text-white/78 transition-colors disabled:opacity-35 inline-flex items-center gap-1.5", title: "Copy a redacted support report", children: [_jsx(Copy, { className: "w-3 h-3" }), "Copy report"] }), _jsx("button", { type: "button", onClick: () => { void handleCopyDebugSnapshot('full'); }, disabled: !conversationId || conversationHydrating, className: "h-7 px-2.5 rounded-[4px] bg-white/[0.05] hover:bg-white/[0.08] text-[10px] text-white/45 hover:text-white/72 transition-colors disabled:opacity-35", title: "Copy the full redacted support report", children: "Full report" }), _jsx("button", { type: "button", onClick: toggleDevSession, className: "h-7 px-2.5 rounded-[4px] bg-white/[0.05] hover:bg-white/[0.08] text-[10px] text-white/35 hover:text-white/70 transition-colors", title: "Hide developer session (Ctrl+Shift+D)", children: "Hide" })] })] }) })), runtimeProjectedMessages.length === 0 && (_jsx("div", { className: "flex-1 flex items-center justify-center pt-[20vh]", children: _jsxs("p", { className: "text-[13px] text-white/20", children: ["Message ", agentName, " to get started"] }) })), runtimeProjectedMessages.map((msg, msgIdx) => {
7468
+ if (conversationId && collaborationAccess?.kind === 'participant') {
7469
+ return _jsx(LiveConversationCollaboration, { localConversationId: conversationId, title: conversation?.title || 'Shared conversation', request: collaborationRequest, onAccessChange: setCollaborationAccess, onNavigateConversation: id => {
7470
+ useAgentChatStore.getState().createConversation(agentId, id);
7471
+ props.onNavigateConversation?.(id);
7472
+ } });
7473
+ }
7474
+ return (_jsxs("div", { className: "xeno-app-shell flex-1 relative min-h-0", children: [sdkConfirmation.confirmation, _jsx("div", { ref: messagesScrollRef, className: "agent-scrollbar absolute inset-0 overflow-auto pr-1.5", style: { scrollbarGutter: 'stable' }, children: conversationHydrating ? (_jsx(ConversationLoadingSkeleton, {})) : (_jsxs("div", { className: "w-full max-w-[820px] mx-auto px-6 pt-6 min-h-full flex flex-col gap-1.5", style: { paddingBottom: messageViewportBottomPadding }, children: [conversation?.sessionUi?.parentConversationId && props.onNavigateConversation && (_jsx("div", { className: "sticky top-2 z-[21] -mx-1 px-1 pb-2", children: _jsxs("button", { type: "button", onClick: () => props.onNavigateConversation?.(conversation.sessionUi?.parentConversationId || ''), className: "xeno-border-subtle w-full rounded-[6px] border bg-[#111111] px-3 py-2 text-left text-[11px] text-white/48 hover:bg-white/[0.045] hover:text-white/72 transition-colors inline-flex items-center gap-2", children: [_jsx(ChevronLeft, { className: "h-3.5 w-3.5" }), _jsx("span", { children: "Back to parent agent" }), _jsx("span", { className: "ml-auto text-[10px] text-white/22 truncate", children: agentName })] }) })), conversation && devSessionOpen && (_jsx("div", { className: "sticky top-2 z-[20] -mx-1 px-1 pb-2", children: _jsxs("div", { className: "xeno-border-subtle rounded-[6px] border bg-[#111111] px-3 py-2 flex items-center justify-between gap-3", children: [_jsxs("div", { className: "flex items-center gap-3 min-w-0 flex-wrap", children: [_jsx("span", { className: "text-[10px] uppercase tracking-[0.14em] text-white/28", children: "Dev session" }), _jsx("span", { className: `text-[10px] uppercase tracking-[0.14em] ${sessionStatusClassName}`, children: sessionStatusLabel }), _jsxs("span", { className: "text-[10px] text-white/24 tabular-nums", children: [pendingTurns.length, " queued"] }), _jsxs("span", { className: "text-[10px] text-white/24 tabular-nums", children: [checkpoints.length, " checkpoints"] }), _jsxs("span", { className: "text-[10px] text-white/18", children: ["Last active ", new Date(conversation.lastMessageAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })] })] }), _jsxs("div", { className: "flex items-center gap-1.5 flex-shrink-0", children: [_jsxs("button", { type: "button", onClick: () => { void handleCopyDebugSnapshot('standard'); }, disabled: !conversationId || conversationHydrating, className: "h-7 px-2.5 rounded-[4px] bg-white/[0.05] hover:bg-white/[0.08] text-[10px] text-white/55 hover:text-white/78 transition-colors disabled:opacity-35 inline-flex items-center gap-1.5", title: "Copy a redacted support report", children: [_jsx(Copy, { className: "w-3 h-3" }), "Copy report"] }), _jsx("button", { type: "button", onClick: () => { void handleCopyDebugSnapshot('full'); }, disabled: !conversationId || conversationHydrating, className: "h-7 px-2.5 rounded-[4px] bg-white/[0.05] hover:bg-white/[0.08] text-[10px] text-white/45 hover:text-white/72 transition-colors disabled:opacity-35", title: "Copy the full redacted support report", children: "Full report" }), _jsx("button", { type: "button", onClick: toggleDevSession, className: "h-7 px-2.5 rounded-[4px] bg-white/[0.05] hover:bg-white/[0.08] text-[10px] text-white/35 hover:text-white/70 transition-colors", title: "Hide developer session (Ctrl+Shift+D)", children: "Hide" })] })] }) })), runtimeProjectedMessages.length === 0 && (_jsx("div", { className: "flex-1 flex items-center justify-center pt-[20vh]", children: _jsxs("p", { className: "text-[13px] text-white/20", children: ["Message ", agentName, " to get started"] }) })), runtimeProjectedMessages.map((msg, msgIdx) => {
7290
7475
  const previousMsg = runtimeProjectedMessages[msgIdx - 1];
7291
7476
  const parts = computeMsgParts(msg);
7292
7477
  const addConversationTurnGap = previousMsg !== undefined && msg.role !== previousMsg.role;
@@ -7358,7 +7543,7 @@ export function AgentView(props) {
7358
7543
  requestId: activeRequestId,
7359
7544
  instruction: msg.content,
7360
7545
  });
7361
- }, disabled: !isRunningCommand || !activeRequestId, className: "p-1 rounded text-white/20 hover:text-white/50 hover:bg-white/[0.04] active:scale-75 transition-all duration-100 disabled:cursor-not-allowed disabled:opacity-20", title: "Send now \u2014 deliver this into the running turn instead of waiting", children: _jsx(CornerDownLeft, { className: "w-3 h-3" }) })), _jsx("span", { className: "text-[9px] text-white/15 mr-1", children: new Date(msg.timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) }), _jsx("button", { onClick: () => { navigator.clipboard.writeText(msg.content); }, className: "p-1 rounded text-white/20 hover:text-white/50 hover:bg-white/[0.04] active:scale-75 transition-all duration-100", title: "Copy", children: _jsx(Copy, { className: "w-3 h-3" }) }), _jsx("button", { onClick: () => { setEditingMsgId(msg.id); }, disabled: isRunningCommand, className: "p-1 rounded text-white/20 hover:text-white/50 hover:bg-white/[0.04] active:scale-75 transition-all duration-100 disabled:cursor-not-allowed disabled:opacity-20", title: "Edit", children: _jsx(Pencil, { className: "w-3 h-3" }) }), _jsx("button", { onClick: () => {
7546
+ }, disabled: !isRunningCommand || !activeRequestId, className: "p-1 rounded text-white/20 hover:text-white/50 hover:bg-white/[0.04] active:scale-75 transition-all duration-100 disabled:cursor-not-allowed disabled:opacity-20", title: "Send now \u2014 deliver this into the running turn instead of waiting", children: _jsx(CornerDownLeft, { className: "w-3 h-3" }) })), _jsx("span", { className: "text-[9px] text-white/15 mr-1", children: new Date(msg.timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) }), _jsx(DiffCopyButton, { getText: () => msg.content, title: "Copy message" }), _jsx("button", { onClick: () => { setEditingMsgId(msg.id); }, disabled: isRunningCommand, className: "p-1 rounded text-white/20 hover:text-white/50 hover:bg-white/[0.04] active:scale-75 transition-all duration-100 disabled:cursor-not-allowed disabled:opacity-20", title: "Edit", children: _jsx(Pencil, { className: "w-3 h-3" }) }), _jsx("button", { onClick: () => {
7362
7547
  void rerunUserTurn(msgIdx);
7363
7548
  }, disabled: isRunningCommand, className: "p-1 rounded text-white/20 hover:text-white/50 hover:bg-white/[0.04] active:scale-75 transition-all duration-100 disabled:opacity-20", title: "Rerun from here", children: _jsx(RefreshCw, { className: "w-3 h-3" }) }), (() => {
7364
7549
  if (!conversationId)
@@ -7425,7 +7610,7 @@ export function AgentView(props) {
7425
7610
  return null;
7426
7611
  }
7427
7612
  })() }, `${msg.id}_${laneIdx}_${part.kind}`));
7428
- }) }), showToolbar && !deferToolbarToBlockedPrompt && (_jsxs("div", { className: "mt-0 grid grid-cols-[12px_minmax(0,1fr)] gap-[6px] opacity-0 group-hover/ast:opacity-100 transition-opacity", children: [_jsxs("div", { className: "relative flex justify-center", children: [_jsx("span", { className: "absolute top-[2px] bottom-[10px] w-px -translate-x-[0.5px] bg-[var(--xeno-border-subtle)]" }), _jsx("span", { className: "relative mt-[4px] inline-flex h-3 w-3 items-center justify-center", children: _jsx("span", { className: "block h-1.5 w-1.5 rounded-[2px] bg-[var(--xeno-marker-solid)]" }) })] }), _jsxs("div", { className: "flex items-center gap-1 flex-wrap min-w-0", children: [_jsx("span", { className: "text-[9px] text-white/15 mr-1", children: new Date(msg.timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) }), !!displayMessageModel && (_jsx("span", { className: "text-[9px] text-white/20", title: `Model used for this message: ${messageModel}`, children: displayMessageModel })), _jsx("button", { onClick: () => { navigator.clipboard.writeText(msg.content); }, className: "p-1 rounded text-white/20 hover:text-white/50 hover:bg-white/[0.04] active:scale-75 transition-all duration-100", title: "Copy", children: _jsx(Copy, { className: "w-3 h-3" }) })] })] }))] })) }) }, msg.id));
7613
+ }) }), showToolbar && !deferToolbarToBlockedPrompt && (_jsxs("div", { className: "mt-0 grid grid-cols-[12px_minmax(0,1fr)] gap-[6px] opacity-0 group-hover/ast:opacity-100 transition-opacity", children: [_jsxs("div", { className: "relative flex justify-center", children: [_jsx("span", { className: "absolute top-[2px] bottom-[10px] w-px -translate-x-[0.5px] bg-[var(--xeno-border-subtle)]" }), _jsx("span", { className: "relative mt-[4px] inline-flex h-3 w-3 items-center justify-center", children: _jsx("span", { className: "block h-1.5 w-1.5 rounded-[2px] bg-[var(--xeno-marker-solid)]" }) })] }), _jsxs("div", { className: "flex items-center gap-1 flex-wrap min-w-0", children: [_jsx("span", { className: "text-[9px] text-white/15 mr-1", children: new Date(msg.timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) }), !!displayMessageModel && (_jsx("span", { className: "text-[9px] text-white/20", title: `Model used for this message: ${messageModel}`, children: displayMessageModel })), _jsx(DiffCopyButton, { getText: () => msg.content, title: "Copy message" })] })] }))] })) }) }, msg.id));
7429
7614
  }), blockedNarrationVisible && (_jsx("div", { className: "flex justify-start", children: _jsx("div", { className: "w-full", children: _jsx(ThinkingIndicator, { mode: "response" }) }) })), blockedPromptVisible && (_jsx("div", { className: "flex justify-start -mt-0.5", children: _jsx("div", { className: "w-full", children: _jsxs("div", { className: "-mx-1.5 rounded-[4px] border border-white/[0.08] bg-white/[0.02] px-3 py-2 flex items-center justify-between gap-3", children: [_jsx("p", { className: "text-[12px] text-white/50 whitespace-nowrap overflow-hidden text-ellipsis flex-1 min-w-0", children: blockedFileActionPrompt.reason === 'capability'
7430
7615
  ? 'Enable file writing for this agent before creating this file?'
7431
7616
  : 'Choose a directory for this conversation before continuing?' }), _jsxs("div", { className: "flex items-center gap-1.5 flex-shrink-0", children: [_jsx("button", { onClick: () => {
@@ -7455,7 +7640,7 @@ export function AgentView(props) {
7455
7640
  event.preventDefault();
7456
7641
  void handleRunTerminalCommand();
7457
7642
  }
7458
- }, placeholder: terminalReady ? 'Run a safe workspace command...' : 'Open a folder to use the terminal', disabled: !terminalCapabilityEnabled || isRunningTerminalCommand, className: "h-8 rounded-[4px] border border-white/[0.06] bg-black/20 px-2.5 text-[11px] text-white/78 placeholder:text-white/18 outline-none focus:border-white/[0.12] disabled:opacity-35" }), _jsx("button", { onClick: () => { void handleRunTerminalCommand(); }, disabled: !terminalReady || isRunningTerminalCommand || !terminalDraftInput.trim(), className: "h-8 px-3 rounded-[4px] bg-white/[0.08] hover:bg-white/[0.12] text-[10px] uppercase tracking-[0.12em] text-white/72 transition-colors disabled:opacity-35", children: isRunningTerminalCommand ? 'Running' : 'Run' })] }) })] }))] })] }) })), _jsxs("div", { ref: footerDockRef, className: "xeno-agent-footer-dock absolute inset-x-0 bottom-0 z-[30] isolate px-6 pb-5 pt-3", children: [!isModelReady && (_jsxs("div", { className: "w-full max-w-[820px] mx-auto mb-2 flex items-center justify-between gap-3", children: [_jsx("p", { className: "text-[11px] text-white/35", children: localRuntimeNeedsStart
7643
+ }, placeholder: terminalReady ? 'Run a safe workspace command...' : 'Open a folder to use the terminal', disabled: !terminalCapabilityEnabled || isRunningTerminalCommand, className: "h-8 rounded-[4px] border border-white/[0.06] bg-black/20 px-2.5 text-[11px] text-white/78 placeholder:text-white/18 outline-none focus:border-white/[0.12] disabled:opacity-35" }), _jsx("button", { onClick: () => { void handleRunTerminalCommand(); }, disabled: !terminalReady || isRunningTerminalCommand || !terminalDraftInput.trim(), className: "h-8 px-3 rounded-[4px] bg-white/[0.08] hover:bg-white/[0.12] text-[10px] uppercase tracking-[0.12em] text-white/72 transition-colors disabled:opacity-35", children: isRunningTerminalCommand ? 'Running' : 'Run' })] }) })] }))] })] }) })), _jsxs("div", { ref: footerDockRef, className: "xeno-agent-footer-dock absolute inset-x-0 bottom-0 z-[30] isolate px-6 pb-5 pt-3", children: [_jsx("div", { ref: sessionPanelRef, className: "absolute bottom-full right-6 z-[45] mb-1", children: _jsx(SdkSessionPanel, { open: sessionDrawerOpen, onOpenChange: setSessionDrawerOpen, workingDirectory: sdkSessionWorkingDirectory, attachedId: sessionUi?.sdkSessionId, sessions: sdkSessions, loading: sdkSessionsLoading, busy: sdkConfirmation.busy || sdkSessionBindingBusy || isBusy || isPreparingModel, status: sdkSessionStatus, unavailableReason: !conversationId ? 'Select a conversation before managing SDK sessions.' : undefined, canList: !!getOptionalAgentPlatformBridge()?.agent?.listSdkSessions, canAttach: !!getOptionalAgentPlatformBridge()?.agent?.attachSdkSession, canDetach: !!getOptionalAgentPlatformBridge()?.agent?.detachSdkSession, canDelete: !!getOptionalAgentPlatformBridge()?.agent?.deleteSdkSession, canClean: !!getOptionalAgentPlatformBridge()?.agent?.cleanSdkSessions, onReload: () => { void loadSdkSessions(); }, onAttach: sessionId => { void handleAttachSdkSession(sessionId); }, onDetach: () => { void handleDetachSdkSession(); }, onDelete: sessionId => { void handleDeleteSdkSession(sessionId); }, onClean: () => { void handleCleanSdkSessions(); } }) }), !isModelReady && (_jsxs("div", { className: "w-full max-w-[820px] mx-auto mb-2 flex items-center justify-between gap-3", children: [_jsx("p", { className: "text-[11px] text-white/35", children: localRuntimeNeedsStart
7459
7644
  ? `xeno-rt is off. Click xeno-rt in the footer before loading ${localModelName}.`
7460
7645
  : isPreparingModel
7461
7646
  ? (isStartingLocalRuntime ? 'Starting xeno-rt...' : `Loading local model ${localModelName}...`)
@@ -7484,10 +7669,10 @@ export function AgentView(props) {
7484
7669
  return (_jsxs("button", { onClick: () => { if (selectedAcpAgentConfigId)
7485
7670
  selectAcpRuntime(selectedAcpAgentConfigId, entry.id); }, disabled: !selectedAcpAgentConfigId || !entry.available, role: "option", "aria-selected": selected, className: `w-full flex items-center justify-between px-3 py-1.5 text-left transition-colors cursor-pointer disabled:opacity-30 disabled:cursor-not-allowed ${selected ? 'bg-white/[0.06]' : 'hover:bg-white/[0.04]'}`, title: entry.reason || undefined, children: [_jsx("span", { className: `min-w-0 flex-1 text-[11px] truncate ${selected ? 'text-white/70' : 'text-white/40'}`, children: entry.name }), !entry.available && _jsx("span", { className: "ml-2 flex-shrink-0 text-[8px] uppercase tracking-wide text-[#ff8f8f]", children: "Unavailable" })] }, entry.selectionKey));
7486
7671
  }) : (_jsx("div", { className: "px-3 py-2.5 text-[10px] text-white/25 text-center", children: "No matching models" }))) : (_jsx("div", { className: "px-3 py-2.5 text-[10px] text-white/25 text-center", children: selectedAcpAgentConfigId ? (acpModelMessage || 'No preset models for this ACP CLI') : 'Select a CLI first' }))] })] })), modelListOpen && runtimeMode !== 'acp' && (_jsxs("div", { ref: modelListRef, className: "xeno-elevated-shell xeno-border-subtle absolute left-3 bottom-[44px] z-50 flex max-h-[340px] w-[280px] flex-col overflow-hidden rounded-md border", children: [renderModelSearch(), _jsx("div", { role: "listbox", className: "min-h-0 overflow-y-auto", children: runtimeMode === 'cloud' ? (sharedProviderCatalogRefreshing ? (_jsx("div", { className: "px-3 py-3 text-[10px] text-white/25 text-center", children: "Refreshing available models..." })) : cloudModels.length > 0 ? (filteredCloudModelOptions.length > 0 ? filteredCloudModelOptions.map(entry => ((() => {
7487
- const modelMeta = cloudModels.find(cm => cm.id === entry.id.replace(/:thinking$/, ''));
7672
+ const modelMeta = cloudModels.find(cm => cm.id === entry.id);
7488
7673
  const degraded = modelMeta?.availability === 'degraded';
7489
7674
  const selected = entry.selectionKey === (selectedCloudEffortFamily?.baseId || selectedModel);
7490
- return (_jsxs("button", { onClick: () => { setInferenceMode('cloud'); setSelectedModel(entry.id); setModelListOpen(false); setEffortListOpen(false); }, role: "option", "aria-selected": selected, className: `w-full flex items-center justify-between px-3 py-1.5 text-left transition-colors cursor-pointer ${selected ? 'bg-white/[0.06]' : 'hover:bg-white/[0.04]'}`, title: modelMeta?.availabilityReason || undefined, children: [_jsxs("div", { className: "min-w-0 flex-1 flex items-center gap-2", children: [_jsx("span", { className: `text-[11px] truncate ${selected ? 'text-white/70' : 'text-white/40'}`, children: entry.name }), degraded && _jsx("span", { className: "text-[8px] uppercase tracking-wide text-[#ffd38a]", children: "Fallback" })] }), _jsx("span", { className: "text-[9px] text-white/20 flex-shrink-0 ml-2 tabular-nums", children: (() => { const m = cloudModels.find(cm => cm.id === entry.id.replace(/:thinking$/, '')); return m?.creditsPerKToken != null ? `${m.creditsPerKToken}/1k` : ''; })() })] }, entry.id));
7675
+ return (_jsxs("button", { onClick: () => { setInferenceMode('cloud'); setSelectedModel(entry.id); setModelListOpen(false); setEffortListOpen(false); }, role: "option", "aria-selected": selected, className: `w-full flex items-center justify-between px-3 py-1.5 text-left transition-colors cursor-pointer ${selected ? 'bg-white/[0.06]' : 'hover:bg-white/[0.04]'}`, title: modelMeta?.availabilityReason || undefined, children: [_jsxs("div", { className: "min-w-0 flex-1 flex items-center gap-2", children: [_jsx("span", { className: `text-[11px] truncate ${selected ? 'text-white/70' : 'text-white/40'}`, children: entry.name }), degraded && _jsx("span", { className: "text-[8px] uppercase tracking-wide text-[#ffd38a]", children: "Fallback" })] }), _jsx("span", { className: "text-[9px] text-white/20 flex-shrink-0 ml-2 tabular-nums", children: (() => { const m = cloudModels.find(cm => cm.id === entry.id); return m?.creditsPerKToken != null ? `${m.creditsPerKToken}/1k` : ''; })() })] }, entry.id));
7491
7676
  })())) : (_jsx("div", { className: "px-3 py-3 text-[10px] text-white/25 text-center", children: "No matching models" }))) : (_jsx("div", { className: "px-3 py-3 text-[10px] leading-relaxed text-white/35 text-center", children: cloudCatalogUnavailableReason }))) : (_jsxs(_Fragment, { children: [localModels.length > 0 ? (filteredLocalModels.length > 0 ? filteredLocalModels.map(m => {
7492
7677
  const selected = m.id === (selectedLocalEffortFamily?.baseId || selectedModel);
7493
7678
  return (_jsxs("button", { onClick: () => { setInferenceMode('local'); setSelectedModel(m.id); setModelListOpen(false); setEffortListOpen(false); }, role: "option", "aria-selected": selected, className: `w-full flex items-center gap-2 px-3 py-1.5 text-left transition-colors cursor-pointer ${selected ? 'bg-white/[0.06]' : 'hover:bg-white/[0.04]'}`, children: [_jsx("span", { className: `text-[11px] truncate ${selected ? 'text-white/70' : 'text-white/40'}`, children: m.name }), m.parameterSize && _jsx("span", { className: "text-[8px] text-white/20 flex-shrink-0 ml-auto", children: m.parameterSize })] }, m.id));
@@ -7495,7 +7680,31 @@ export function AgentView(props) {
7495
7680
  ? 'bg-white/[0.12] text-white shadow-sm'
7496
7681
  : 'text-white/45 hover:bg-white/[0.04] hover:text-white/70'}`, "aria-pressed": workspaceBinding.mode !== 'workspace', children: "Chat" }), _jsx("button", { type: "button", onClick: () => { void handleSelectWorkspaceMode('workspace'); }, disabled: isBusy || !!props.externalInputLockReason || isSelectingConversationWorkspace, className: `rounded px-2.5 py-1 font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-40 ${workspaceBinding.mode === 'workspace'
7497
7682
  ? 'bg-white/[0.12] text-white shadow-sm'
7498
- : 'text-white/45 hover:bg-white/[0.04] hover:text-white/70'}`, "aria-pressed": workspaceBinding.mode === 'workspace', children: isSelectingConversationWorkspace && workspaceBinding.mode !== 'workspace' ? 'Choosing…' : 'Agent' })] }), workspaceBinding.mode === 'workspace' ? (_jsxs("div", { className: "flex min-w-0 items-center gap-2 text-[10px]", children: [_jsx("span", { className: "min-w-0 truncate font-mono text-white/45", title: workspaceBinding.rootDirectory || workspaceBinding.allowedDirectories[0], children: workspaceBinding.rootDirectory || workspaceBinding.allowedDirectories[0] }), _jsx("button", { type: "button", onClick: () => { void chooseConversationWorkspace(); }, disabled: isSelectingConversationWorkspace || isBusy || !!props.externalInputLockReason, className: "shrink-0 text-white/35 transition-colors hover:text-white/70 disabled:cursor-not-allowed disabled:opacity-30", children: "Change folder" })] })) : (_jsx("span", { className: "min-w-0 truncate text-[10px] text-white/28", children: "Chat only \u00B7 no project file access" }))] }), props.externalInputLockReason && (_jsx("div", { className: "mb-2 rounded-md border border-amber-400/20 bg-amber-400/[0.06] px-3 py-2 text-[11px] text-amber-100/70", children: props.externalInputLockReason })), _jsxs("div", { className: `xeno-agent-composer-shell border border-white/[0.08] ${pendingTurns.length > 0 ? 'rounded-t-none rounded-b-md' : 'rounded-md'}`, children: [_jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", multiple: true, onChange: (e) => { void handleAttachmentPick(e); }, className: "hidden" }), pendingAttachments.length > 0 && (_jsx("div", { className: "px-3 pt-3 pb-1", children: _jsx("div", { className: "grid grid-cols-4 gap-2", children: pendingAttachments.map(att => (_jsxs("div", { className: "xeno-app-shell xeno-border-subtle relative rounded overflow-hidden border", children: [_jsx("img", { src: att.dataUrl, alt: att.name, className: "w-full h-16 object-cover" }), _jsx("button", { onClick: () => removePendingAttachment(att.id), className: "absolute top-1 right-1 w-5 h-5 rounded-[4px] bg-black/60 text-white/70 hover:text-white flex items-center justify-center transition-colors cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35", "aria-label": `Remove attachment ${att.name}`, title: `Remove ${att.name}`, children: _jsx(X, { className: "w-3 h-3" }) })] }, att.id))) }) })), _jsx(GhostTextArea, { ref: textareaRef, rows: 2, value: input, onChange: handleInputChange, onKeyDown: handleKeyDown, disabled: inputLocked, placeholder: effectiveGhostText
7683
+ : 'text-white/45 hover:bg-white/[0.04] hover:text-white/70'}`, "aria-pressed": workspaceBinding.mode === 'workspace', children: isSelectingConversationWorkspace && workspaceBinding.mode !== 'workspace' ? 'Choosing…' : 'Agent' })] }), workspaceBinding.mode === 'workspace' ? (_jsxs("div", { className: "flex min-w-0 items-center gap-2 text-[10px]", children: [_jsx("span", { className: "min-w-0 truncate font-mono text-white/45", title: workspaceBinding.rootDirectory || workspaceBinding.allowedDirectories[0], children: workspaceBinding.rootDirectory || workspaceBinding.allowedDirectories[0] }), _jsx("button", { type: "button", onClick: () => { void chooseConversationWorkspace(); }, disabled: isSelectingConversationWorkspace || isBusy || !!props.externalInputLockReason, className: "shrink-0 text-white/35 transition-colors hover:text-white/70 disabled:cursor-not-allowed disabled:opacity-30", children: "Change folder" })] })) : (_jsx("span", { className: "min-w-0 truncate text-[10px] text-white/28", children: "Chat only \u00B7 no project file access" })), activeMcpList.length > 0 && (_jsxs("div", { className: "flex items-center gap-1.5 pl-2 border-l border-white/[0.08]", children: [_jsx("span", { className: "text-[10px] text-white/35 font-mono", children: "MCP:" }), activeMcpList.map((mcp) => {
7684
+ const statusDot = mcp.status === 'connected'
7685
+ ? 'bg-emerald-400'
7686
+ : mcp.status === 'auth_required'
7687
+ ? 'bg-amber-400 animate-pulse'
7688
+ : 'bg-rose-400';
7689
+ const statusTitle = `${mcp.server}: ${mcp.status}${mcp.error ? ` (${mcp.error})` : ''}`;
7690
+ return (_jsxs("button", { type: "button", onClick: () => { void handleExecuteCommandOrPrompt(`/mcp ${mcp.server}`); }, className: "inline-flex items-center gap-1 rounded bg-white/[0.04] px-1.5 py-0.5 text-[10px] font-mono text-white/60 hover:bg-white/[0.08] transition-colors cursor-pointer", title: statusTitle, children: [_jsx("span", { className: `h-1.5 w-1.5 rounded-full ${statusDot}` }), _jsx("span", { children: mcp.server })] }, mcp.server));
7691
+ })] }))] }), props.externalInputLockReason && (_jsx("div", { className: "mb-2 rounded-md border border-amber-400/20 bg-amber-400/[0.06] px-3 py-2 text-[11px] text-amber-100/70", children: props.externalInputLockReason })), activeNotifsList.length > 0 && (_jsx(AgentNotificationBanner, { notifications: activeNotifsList, onDismiss: (id) => {
7692
+ if (conversationId)
7693
+ dismissNotification(conversationId, id);
7694
+ }, onAction: (action, cmd, url) => {
7695
+ if (action === 'command' && cmd) {
7696
+ void handleExecuteCommandOrPrompt(cmd);
7697
+ }
7698
+ else if (action === 'link' && url) {
7699
+ window.open(url, '_blank');
7700
+ }
7701
+ } })), _jsxs("div", { className: `xeno-agent-composer-shell relative border border-white/[0.08] ${pendingTurns.length > 0 ? 'rounded-t-none rounded-b-md' : 'rounded-md'}`, children: [showSlashCommands && (_jsx(SlashCommandAutocomplete, { commands: activeCommandsList, filter: input, selectedIndex: slashCommandIndex, onSelect: (cmdName) => {
7702
+ const cmdText = (cmdName.startsWith('/') ? cmdName : `/${cmdName}`) + ' ';
7703
+ setInput(cmdText);
7704
+ if (textareaRef.current) {
7705
+ textareaRef.current.focus();
7706
+ }
7707
+ }, onClose: () => setSlashCommandsDismissed(true) })), _jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", multiple: true, onChange: (e) => { void handleAttachmentPick(e); }, className: "hidden" }), pendingAttachments.length > 0 && (_jsx("div", { className: "px-3 pt-3 pb-1", children: _jsx("div", { className: "grid grid-cols-4 gap-2", children: pendingAttachments.map(att => (_jsxs("div", { className: "xeno-app-shell xeno-border-subtle relative rounded overflow-hidden border", children: [_jsx("img", { src: att.dataUrl, alt: att.name, className: "w-full h-16 object-cover" }), _jsx("button", { onClick: () => removePendingAttachment(att.id), className: "absolute top-1 right-1 w-5 h-5 rounded-[4px] bg-black/60 text-white/70 hover:text-white flex items-center justify-center transition-colors cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35", "aria-label": `Remove attachment ${att.name}`, title: `Remove ${att.name}`, children: _jsx(X, { className: "w-3 h-3" }) })] }, att.id))) }) })), _jsx(GhostTextArea, { ref: textareaRef, rows: 2, value: input, onChange: handleInputChange, onKeyDown: handleKeyDown, disabled: inputLocked, placeholder: effectiveGhostText
7499
7708
  ? ''
7500
7709
  : (isModelReady
7501
7710
  ? `Message ${agentName.replace(/\s*powered by .+$/i, '')}...`
@@ -7534,20 +7743,23 @@ export function AgentView(props) {
7534
7743
  ? 'Loading...'
7535
7744
  : acpProviderModelDisplayName)
7536
7745
  : 'Select model')
7537
- : (currentModelName || 'Select model') }), _jsx(ChevronDown, { className: `w-3 h-3 flex-shrink-0 transition-transform duration-150 ${(runtimeMode === 'acp' ? acpModelListOpen : modelListOpen) ? 'rotate-180' : ''}` })] }), activeReasoningSelector && (_jsxs("div", { ref: effortSelectorRef, className: "relative", onKeyDown: (event) => {
7746
+ : (currentModelName || 'Select model') }), _jsx(ChevronDown, { className: `w-3 h-3 flex-shrink-0 transition-transform duration-150 ${(runtimeMode === 'acp' ? acpModelListOpen : modelListOpen) ? 'rotate-180' : ''}` })] }), _jsxs("button", { type: "button", "aria-pressed": suggestionsAvailable, disabled: !suggestionModelAvailable, title: runtimeMode === 'acp' ? 'Provider-native suggestions are not available through this bridge.' : `Opt in to additional suggestion requests using ${actualModelId}. Cloud requests may incur charges.`, onClick: () => { clearAllSuggestions(); setSuggestionOptInScope(suggestionsAvailable ? null : suggestionScope); }, className: "h-7 rounded bg-white/[0.04] px-2 text-[10px] text-white/45 disabled:opacity-30", children: ["Suggestions: ", suggestionsAvailable ? 'On' : 'Off'] }), activeReasoningSelector && (_jsxs("div", { ref: effortSelectorRef, className: "relative", onKeyDown: (event) => {
7538
7747
  if (event.key !== 'Escape')
7539
7748
  return;
7540
7749
  setEffortListOpen(false);
7541
7750
  effortBtnRef.current?.focus();
7542
7751
  }, children: [_jsxs("button", { ref: effortBtnRef, onClick: () => { setEffortListOpen((open) => !open); setModelListOpen(false); setAcpModelListOpen(false); setAcpCliListOpen(false); setModeExpanded(false); }, disabled: isBusy || modeExpanded, className: "h-7 flex items-center gap-1 rounded bg-white/[0.04] px-2 text-white/40 transition-colors hover:bg-white/[0.08] hover:text-white/60 focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35 disabled:cursor-not-allowed disabled:opacity-30", title: "Select reasoning effort", "aria-label": "Select reasoning effort", "aria-haspopup": "listbox", "aria-expanded": effortListOpen, children: [_jsxs("span", { className: "text-[10px] whitespace-nowrap", children: ["Effort: ", activeReasoningSelector.label] }), _jsx(ChevronDown, { className: `h-3 w-3 flex-shrink-0 transition-transform duration-150 ${effortListOpen ? 'rotate-180' : ''}` })] }), effortListOpen && (_jsx("div", { role: "listbox", className: "xeno-elevated-shell xeno-border-subtle absolute bottom-[34px] right-0 z-50 w-[130px] overflow-hidden rounded-md border py-1", children: activeReasoningSelector.options.map((option) => {
7543
7752
  const selected = runtimeMode === 'acp'
7544
- ? (selectedSharedAcpSnapshot?.selection?.runtimeModelId || selectedSharedAcpSnapshot?.selectedModel?.id) === option.modelId
7545
- : selectedModel === option.modelId;
7753
+ ? selectedAcpEffortFamily?.effort === option.id
7754
+ : runtimeMode === 'cloud'
7755
+ ? selectedCloudEffortFamily?.effort === option.id
7756
+ : selectedModel === option.modelId;
7546
7757
  const acpDiscoveredOption = runtimeMode === 'acp'
7547
7758
  ? acpProviderModelOptionById.get(option.modelId)
7548
7759
  : undefined;
7549
7760
  const unavailable = option.available === false || acpDiscoveredOption?.available === false;
7550
7761
  return (_jsx("button", { type: "button", role: "option", "aria-selected": selected, disabled: unavailable, title: option.reason || acpDiscoveredOption?.reason || undefined, onClick: () => {
7762
+ setReasoningChoice({ conversationId: conversationId || null, providerKey: reasoningProviderKey, modelId: option.modelId, optionId: option.id });
7551
7763
  if (runtimeMode === 'acp') {
7552
7764
  if (selectedAcpAgentConfigId)
7553
7765
  selectAcpRuntime(selectedAcpAgentConfigId, option.modelId);
@@ -7556,7 +7768,14 @@ export function AgentView(props) {
7556
7768
  setSelectedModel(option.modelId);
7557
7769
  setEffortListOpen(false);
7558
7770
  }
7559
- }, className: `w-full px-3 py-1.5 text-left text-[10px] transition-colors disabled:cursor-not-allowed disabled:opacity-30 ${selected ? 'bg-white/[0.06] text-white/70' : 'text-white/40 hover:bg-white/[0.04] hover:text-white/60'}`, children: option.label }, option.modelId));
7771
+ if (conversationId) {
7772
+ const latest = useAgentChatStore.getState().getConversation(conversationId);
7773
+ if (latest?.runtime)
7774
+ updateConversation(conversationId, {
7775
+ runtime: { ...latest.runtime, model: providerRuntimeModelId(option.modelId), reasoning: { ...latest.runtime.reasoning, optionId: option.id } },
7776
+ });
7777
+ }
7778
+ }, className: `w-full px-3 py-1.5 text-left text-[10px] transition-colors disabled:cursor-not-allowed disabled:opacity-30 ${selected ? 'bg-white/[0.06] text-white/70' : 'text-white/40 hover:bg-white/[0.04] hover:text-white/60'}`, children: option.label }, option.id));
7560
7779
  }) }))] })), _jsxs("button", { onClick: () => { if (isAuthenticatedForCloud)
7561
7780
  setCloudRunEnabled(!cloudRunEnabled); }, disabled: isBusy || !isAuthenticatedForCloud, className: `h-7 flex items-center gap-1 px-2 rounded transition-colors cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35 disabled:cursor-not-allowed whitespace-nowrap ${!isAuthenticatedForCloud
7562
7781
  ? 'bg-white/[0.03] text-white/25 opacity-60'
@@ -7570,7 +7789,10 @@ export function AgentView(props) {
7570
7789
  ? _jsxs("span", { className: "text-white/30", children: ["- ", activeCloudRunStatus.creditsSettled, "cr"] })
7571
7790
  : typeof activeCloudRunStatus.creditsHeld === 'number' && activeCloudRunStatus.creditsHeld > 0
7572
7791
  ? _jsxs("span", { className: "text-white/30", children: ["- ", activeCloudRunStatus.creditsHeld, "cr held"] })
7573
- : null] }))] }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [props.onOpenRuntimeSettings && (_jsx("button", { onClick: props.onOpenRuntimeSettings, disabled: isBusy, className: "w-7 h-7 flex items-center justify-center rounded bg-white/[0.04] hover:bg-white/[0.08] text-white/35 hover:text-white/60 transition-colors cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35 disabled:opacity-30 disabled:cursor-not-allowed", title: "Edit runtime provider", "aria-label": "Edit runtime provider", children: _jsx(Pencil, { className: "w-3 h-3" }) })), props.onOpenConversationSettings && (_jsx("button", { onClick: props.onOpenConversationSettings, className: "h-7 px-2.5 rounded-[4px] text-[10px] bg-white/[0.04] hover:bg-white/[0.08] text-white/35 hover:text-white/60 transition-colors cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35", title: "Open chat and workspace settings", children: "Settings" })), _jsx("button", { onClick: (event) => {
7792
+ : null] }))] }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [conversationId && (_jsx(LiveConversationCollaboration, { localConversationId: conversationId, title: conversation?.title || 'Agent conversation', modelId: actualModelId, ownerMessages: runtimeProjectedMessages, request: collaborationRequest, onAccessChange: setCollaborationAccess, onNavigateConversation: id => {
7793
+ useAgentChatStore.getState().createConversation(agentId, id);
7794
+ props.onNavigateConversation?.(id);
7795
+ } })), props.onOpenRuntimeSettings && (_jsx("button", { onClick: props.onOpenRuntimeSettings, disabled: isBusy, className: "w-7 h-7 flex items-center justify-center rounded bg-white/[0.04] hover:bg-white/[0.08] text-white/35 hover:text-white/60 transition-colors cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35 disabled:opacity-30 disabled:cursor-not-allowed", title: "Edit runtime provider", "aria-label": "Edit runtime provider", children: _jsx(Pencil, { className: "w-3 h-3" }) })), props.onOpenConversationSettings && (_jsx("button", { onClick: props.onOpenConversationSettings, className: "h-7 px-2.5 rounded-[4px] text-[10px] bg-white/[0.04] hover:bg-white/[0.08] text-white/35 hover:text-white/60 transition-colors cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35", title: "Open chat and workspace settings", children: "Settings" })), _jsx("button", { onClick: (event) => {
7574
7796
  if (event.shiftKey) {
7575
7797
  event.preventDefault();
7576
7798
  toggleDevSession();
@@ -7579,7 +7801,10 @@ export function AgentView(props) {
7579
7801
  patchSessionUi({ panelOpen: !sessionPanelOpen });
7580
7802
  }, className: `h-7 px-2.5 rounded-[4px] text-[10px] transition-colors cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35 ${sessionPanelOpen
7581
7803
  ? 'bg-white/[0.08] text-white/72'
7582
- : 'bg-white/[0.04] hover:bg-white/[0.08] text-white/35 hover:text-white/60'}`, title: "Toggle workbench panel. Shift+click or Ctrl+Shift+D for the developer session.", children: "Panel" }), _jsx(AIStatusIndicator, { model: actualModelId, className: "justify-end", refreshKey: runtimeStatusRefreshKey, runtimeAvailable: selectedModel.startsWith('local:') ? localRuntimeAvailable : null, onRuntimeClick: selectedModel.startsWith('local:') ? handleRuntimeIndicatorClick : undefined }), isStreaming && !activeCliThreadRun && (_jsx("button", { onClick: () => { abort(); clearAllSuggestions(); }, disabled: isCancelling, className: "w-7 h-7 flex items-center justify-center rounded bg-white/[0.08] hover:bg-white/[0.14] text-white/50 hover:text-white/90 transition-colors cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35 disabled:cursor-wait disabled:opacity-55", title: "Stop current response", "aria-label": "Stop current response", children: isCancelling ? (_jsx(RefreshCw, { className: "w-3 h-3 animate-spin" })) : (_jsx(Square, { className: "w-3 h-3" })) })), activeCliThreadRun && (_jsx("button", { onClick: () => { void cancelCliAppServerMessage(); }, className: "w-7 h-7 flex items-center justify-center rounded bg-white/[0.08] hover:bg-white/[0.14] text-white/50 hover:text-white/90 transition-colors cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35", title: activeCliThreadRun.kind === 'remote' ? 'Stop CLI remote run start' : 'Stop CLI app-server turn', "aria-label": activeCliThreadRun.kind === 'remote' ? 'Stop CLI remote run start' : 'Stop CLI app-server turn', children: _jsx(Square, { className: "w-3 h-3" }) })), _jsx("button", { onClick: () => { void handleSend(); }, disabled: (!input.trim() && pendingAttachments.length === 0) || inputLocked, className: "w-7 h-7 flex items-center justify-center rounded bg-white/[0.08] hover:bg-white/[0.14] text-white/50 hover:text-white/90 transition-colors cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35 disabled:opacity-30 disabled:cursor-not-allowed", title: isStreaming && !inputLocked ? 'Queue message' : 'Send message', "aria-label": isStreaming && !inputLocked ? 'Queue message' : 'Send message', children: _jsx(ArrowUp, { className: "w-3.5 h-3.5" }) })] })] })] })] })] })] })] }));
7804
+ : 'bg-white/[0.04] hover:bg-white/[0.08] text-white/35 hover:text-white/60'}`, title: "Toggle workbench panel. Shift+click or Ctrl+Shift+D for the developer session.", children: "Panel" }), _jsx(AIStatusIndicator, { model: actualModelId, className: "justify-end", refreshKey: runtimeStatusRefreshKey, runtimeAvailable: selectedModel.startsWith('local:') ? localRuntimeAvailable : null, onRuntimeClick: selectedModel.startsWith('local:') ? handleRuntimeIndicatorClick : undefined }), isStreaming && !activeCliThreadRun && (_jsx("button", {
7805
+ // Names the conversation this Stop belongs to: with concurrent turns the
7806
+ // foreground scalar is not necessarily this conversation's turn.
7807
+ onClick: () => { abort(conversationId); clearAllSuggestions(); }, disabled: isCancelling, className: "w-7 h-7 flex items-center justify-center rounded bg-white/[0.08] hover:bg-white/[0.14] text-white/50 hover:text-white/90 transition-colors cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35 disabled:cursor-wait disabled:opacity-55", title: "Stop current response", "aria-label": "Stop current response", children: isCancelling ? (_jsx(RefreshCw, { className: "w-3 h-3 animate-spin" })) : (_jsx(Square, { className: "w-3 h-3" })) })), activeCliThreadRun && (_jsx("button", { onClick: () => { void cancelCliAppServerMessage(); }, className: "w-7 h-7 flex items-center justify-center rounded bg-white/[0.08] hover:bg-white/[0.14] text-white/50 hover:text-white/90 transition-colors cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35", title: activeCliThreadRun.kind === 'remote' ? 'Stop CLI remote run start' : 'Stop CLI app-server turn', "aria-label": activeCliThreadRun.kind === 'remote' ? 'Stop CLI remote run start' : 'Stop CLI app-server turn', children: _jsx(Square, { className: "w-3 h-3" }) })), _jsx("button", { onClick: () => { void handleSend(); }, disabled: (!input.trim() && pendingAttachments.length === 0) || inputLocked, className: "w-7 h-7 flex items-center justify-center rounded bg-white/[0.08] hover:bg-white/[0.14] text-white/50 hover:text-white/90 transition-colors cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35 disabled:opacity-30 disabled:cursor-not-allowed", title: isStreaming && !inputLocked ? 'Queue message' : 'Send message', "aria-label": isStreaming && !inputLocked ? 'Queue message' : 'Send message', children: _jsx(ArrowUp, { className: "w-3.5 h-3.5" }) })] })] })] })] })] })] })] }));
7583
7808
  }
7584
7809
  const ACP_MODEL_ID = /^[A-Za-z0-9._:/+-]{1,120}$/;
7585
7810
  function projectSharedAcpProviderModels(provider) {