@antelopejs/dms-ai 0.8.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/README.md +2 -1
  2. package/dist/lifecycle/skill-sources.js +19 -146
  3. package/dist/lifecycle/skill-sources.js.map +1 -1
  4. package/dist/pages/settings/availability.js +8 -1
  5. package/dist/pages/settings/availability.js.map +1 -1
  6. package/dist/pages/settings/options.d.ts +2 -1
  7. package/dist/pages/settings/options.js +29 -8
  8. package/dist/pages/settings/options.js.map +1 -1
  9. package/dist/pages/settings/sections.js +25 -4
  10. package/dist/pages/settings/sections.js.map +1 -1
  11. package/dist/routes/builder.d.ts +3 -3
  12. package/dist/routes/builder.js +10 -2
  13. package/dist/routes/builder.js.map +1 -1
  14. package/dist/routes/settings.js +1 -1
  15. package/dist/routes/settings.js.map +1 -1
  16. package/dist/sidecar/settings-values.d.ts +3 -0
  17. package/dist/sidecar/settings-values.js +33 -1
  18. package/dist/sidecar/settings-values.js.map +1 -1
  19. package/dist/vocabulary/enumerations.js +2 -0
  20. package/dist/vocabulary/enumerations.js.map +1 -1
  21. package/dist/vocabulary/tools.js +3 -0
  22. package/dist/vocabulary/tools.js.map +1 -1
  23. package/frontend-vue/app/chat/components/ChatView.vue +53 -85
  24. package/frontend-vue/app/chat/components/Composer.vue +23 -39
  25. package/frontend-vue/app/chat/components/NoticeCard.vue +25 -0
  26. package/frontend-vue/app/chat/components/PanelHeader.vue +2 -6
  27. package/frontend-vue/app/chat/components/ProviderNotice.vue +14 -3
  28. package/frontend-vue/app/chat/composables/conversation-events.ts +4 -3
  29. package/frontend-vue/app/chat/composables/useConversation.ts +6 -0
  30. package/frontend-vue/app/chat/composables/useConversationMode.ts +8 -11
  31. package/frontend-vue/app/chat/composables/useFollowScroll.ts +77 -0
  32. package/frontend-vue/app/chat/constants/modes.ts +15 -0
  33. package/frontend-vue/app/chat/constants/protocol.ts +0 -1
  34. package/frontend-vue/app/chat/constants/settings.ts +1 -1
  35. package/frontend-vue/app/chat/types/protocol.ts +19 -9
  36. package/frontend-vue/app/chat/types/settings.ts +7 -2
  37. package/frontend-vue/app/chat/utils/permission-view.ts +1 -0
  38. package/frontend-vue/app/chat/utils/status-label.ts +50 -0
  39. package/frontend-vue/app/chat/utils/tool-lexicon.ts +16 -0
  40. package/frontend-vue/app/plugins/ai.client.ts +2 -2
  41. package/frontend-vue/app/runtime/assistant-actions.ts +4 -2
  42. package/frontend-vue/app/runtime/assistant-session.ts +5 -1
  43. package/frontend-vue/app/runtime/block-health.ts +135 -0
  44. package/frontend-vue/app/runtime/constants.ts +1 -0
  45. package/frontend-vue/app/runtime/navigation-complete.ts +47 -6
  46. package/frontend-vue/app/runtime/panel-intents.ts +6 -2
  47. package/frontend-vue/app/views/constants.ts +2 -0
  48. package/frontend-vue/app/views/types.ts +3 -1
  49. package/frontend-vue/i18n/locales/dms-ai-pages-en-GB.json +28 -11
  50. package/frontend-vue/i18n/locales/dms-ai-pages-fr-FR.json +28 -11
  51. package/frontend-vue/i18n/locales/dms-ai-panel-en-GB.json +17 -22
  52. package/frontend-vue/i18n/locales/dms-ai-panel-fr-FR.json +17 -22
  53. package/frontend-vue/i18n/locales/dms-ai-views-en-GB.json +2 -0
  54. package/frontend-vue/i18n/locales/dms-ai-views-fr-FR.json +2 -0
  55. package/frontend-vue/tests/assistant-actions.test.ts +37 -0
  56. package/frontend-vue/tests/block-health.test.ts +142 -0
  57. package/frontend-vue/tests/chat/chat-scroll.test.ts +251 -0
  58. package/frontend-vue/tests/chat/conversation-events.test.ts +35 -3
  59. package/frontend-vue/tests/chat/provider-notice.test.ts +33 -0
  60. package/frontend-vue/tests/chat/tool-lexicon.test.ts +1 -0
  61. package/frontend-vue/tests/chat-panel.test.ts +2 -4
  62. package/frontend-vue/tests/navigation.test.ts +67 -2
  63. package/frontend-vue/tests/panel-modes.test.ts +146 -0
  64. package/frontend-vue/tests/panel-questions.test.ts +1 -19
  65. package/frontend-vue/tests/panel-states.test.ts +3 -15
  66. package/frontend-vue/tests/support/fake-layout.ts +119 -0
  67. package/frontend-vue/tests/support/panel-harness.ts +16 -8
  68. package/frontend-vue/tests/support/setup-layout.ts +3 -0
  69. package/frontend-vue/tests/support/stubs.ts +2 -0
  70. package/frontend-vue/vitest.config.ts +1 -0
  71. package/package.json +6 -5
  72. package/sidecar/dist/agent/always-ask-files.d.ts +2 -0
  73. package/sidecar/dist/agent/always-ask-files.js +34 -0
  74. package/sidecar/dist/agent/always-ask-files.js.map +1 -0
  75. package/sidecar/dist/agent/conversation-modes.d.ts +3 -12
  76. package/sidecar/dist/agent/conversation-modes.js +16 -69
  77. package/sidecar/dist/agent/conversation-modes.js.map +1 -1
  78. package/sidecar/dist/agent/effective-mode.d.ts +2 -5
  79. package/sidecar/dist/agent/effective-mode.js +1 -15
  80. package/sidecar/dist/agent/effective-mode.js.map +1 -1
  81. package/sidecar/dist/agent/permission-bus.d.ts +1 -2
  82. package/sidecar/dist/agent/permission-bus.js +1 -3
  83. package/sidecar/dist/agent/permission-bus.js.map +1 -1
  84. package/sidecar/dist/agent/permission-preview.d.ts +6 -0
  85. package/sidecar/dist/agent/permission-preview.js +35 -10
  86. package/sidecar/dist/agent/permission-preview.js.map +1 -1
  87. package/sidecar/dist/agent/permission-rules.js +2 -2
  88. package/sidecar/dist/agent/permission-rules.js.map +1 -1
  89. package/sidecar/dist/agent/project-secrets.d.ts +7 -0
  90. package/sidecar/dist/agent/project-secrets.js +61 -0
  91. package/sidecar/dist/agent/project-secrets.js.map +1 -0
  92. package/sidecar/dist/agent/provider.d.ts +10 -4
  93. package/sidecar/dist/agent/runner.d.ts +8 -2
  94. package/sidecar/dist/agent/runner.js +11 -3
  95. package/sidecar/dist/agent/runner.js.map +1 -1
  96. package/sidecar/dist/agent/session.d.ts +3 -3
  97. package/sidecar/dist/agent/session.js.map +1 -1
  98. package/sidecar/dist/agent/tool-kinds.d.ts +7 -1
  99. package/sidecar/dist/agent/tool-kinds.js +24 -5
  100. package/sidecar/dist/agent/tool-kinds.js.map +1 -1
  101. package/sidecar/dist/audit/activity-query.js +2 -0
  102. package/sidecar/dist/audit/activity-query.js.map +1 -1
  103. package/sidecar/dist/audit/activity.js +1 -0
  104. package/sidecar/dist/audit/activity.js.map +1 -1
  105. package/sidecar/dist/builder/builder-client.js +14 -2
  106. package/sidecar/dist/builder/builder-client.js.map +1 -1
  107. package/sidecar/dist/constants/audit.d.ts +1 -3
  108. package/sidecar/dist/constants/audit.js +2 -1
  109. package/sidecar/dist/constants/audit.js.map +1 -1
  110. package/sidecar/dist/constants/builder.d.ts +5 -1
  111. package/sidecar/dist/constants/builder.js +15 -0
  112. package/sidecar/dist/constants/builder.js.map +1 -1
  113. package/sidecar/dist/constants/claude.d.ts +8 -0
  114. package/sidecar/dist/constants/claude.js +8 -0
  115. package/sidecar/dist/constants/claude.js.map +1 -1
  116. package/sidecar/dist/constants/codex.d.ts +4 -0
  117. package/sidecar/dist/constants/codex.js +4 -0
  118. package/sidecar/dist/constants/codex.js.map +1 -1
  119. package/sidecar/dist/constants/mcp.d.ts +1 -1
  120. package/sidecar/dist/constants/mcp.js +1 -1
  121. package/sidecar/dist/constants/mcp.js.map +1 -1
  122. package/sidecar/dist/constants/native-binary.d.ts +5 -2
  123. package/sidecar/dist/constants/native-binary.js +5 -2
  124. package/sidecar/dist/constants/native-binary.js.map +1 -1
  125. package/sidecar/dist/constants/permissions.d.ts +2 -0
  126. package/sidecar/dist/constants/permissions.js +23 -0
  127. package/sidecar/dist/constants/permissions.js.map +1 -1
  128. package/sidecar/dist/constants/project-secrets.d.ts +5 -0
  129. package/sidecar/dist/constants/project-secrets.js +20 -0
  130. package/sidecar/dist/constants/project-secrets.js.map +1 -0
  131. package/sidecar/dist/constants/providers.d.ts +2 -0
  132. package/sidecar/dist/constants/providers.js +1 -0
  133. package/sidecar/dist/constants/providers.js.map +1 -1
  134. package/sidecar/dist/constants/settings.d.ts +2 -2
  135. package/sidecar/dist/constants/settings.js +4 -9
  136. package/sidecar/dist/constants/settings.js.map +1 -1
  137. package/sidecar/dist/constants/timing.d.ts +1 -0
  138. package/sidecar/dist/constants/timing.js +1 -0
  139. package/sidecar/dist/constants/timing.js.map +1 -1
  140. package/sidecar/dist/constants/tool-kinds.d.ts +67 -2
  141. package/sidecar/dist/constants/tool-kinds.js +111 -33
  142. package/sidecar/dist/constants/tool-kinds.js.map +1 -1
  143. package/sidecar/dist/mcp/tools/builder-compose.d.ts +51 -0
  144. package/sidecar/dist/mcp/tools/builder-compose.js +96 -0
  145. package/sidecar/dist/mcp/tools/builder-compose.js.map +1 -0
  146. package/sidecar/dist/mcp/tools/builder-gate.js +3 -1
  147. package/sidecar/dist/mcp/tools/builder-gate.js.map +1 -1
  148. package/sidecar/dist/mcp/tools/builder-project.js +119 -4
  149. package/sidecar/dist/mcp/tools/builder-project.js.map +1 -1
  150. package/sidecar/dist/mcp/tools/builder-queries.d.ts +31 -0
  151. package/sidecar/dist/mcp/tools/builder-queries.js +30 -13
  152. package/sidecar/dist/mcp/tools/builder-queries.js.map +1 -1
  153. package/sidecar/dist/mcp/tools/builder-table-view-schema.d.ts +99 -0
  154. package/sidecar/dist/mcp/tools/builder-table-view-schema.js +118 -0
  155. package/sidecar/dist/mcp/tools/builder-table-view-schema.js.map +1 -0
  156. package/sidecar/dist/mcp/tools/builder-table-view.d.ts +102 -0
  157. package/sidecar/dist/mcp/tools/builder-table-view.js +24 -0
  158. package/sidecar/dist/mcp/tools/builder-table-view.js.map +1 -0
  159. package/sidecar/dist/mcp/tools/builder.d.ts +135 -1
  160. package/sidecar/dist/mcp/tools/builder.js +17 -4
  161. package/sidecar/dist/mcp/tools/builder.js.map +1 -1
  162. package/sidecar/dist/mcp/tools/navigate-to-page.js +12 -4
  163. package/sidecar/dist/mcp/tools/navigate-to-page.js.map +1 -1
  164. package/sidecar/dist/pages/block-health.d.ts +14 -0
  165. package/sidecar/dist/pages/block-health.js +60 -0
  166. package/sidecar/dist/pages/block-health.js.map +1 -0
  167. package/sidecar/dist/prompts/agent.d.ts +1 -1
  168. package/sidecar/dist/prompts/agent.js +4 -3
  169. package/sidecar/dist/prompts/agent.js.map +1 -1
  170. package/sidecar/dist/protocol/events.d.ts +140 -63
  171. package/sidecar/dist/protocol/events.js +24 -8
  172. package/sidecar/dist/protocol/events.js.map +1 -1
  173. package/sidecar/dist/protocol/messages.d.ts +111 -49
  174. package/sidecar/dist/protocol/messages.js +30 -13
  175. package/sidecar/dist/protocol/messages.js.map +1 -1
  176. package/sidecar/dist/providers/claude/config.d.ts +19 -5
  177. package/sidecar/dist/providers/claude/config.js +21 -7
  178. package/sidecar/dist/providers/claude/config.js.map +1 -1
  179. package/sidecar/dist/providers/claude/model-fallback.d.ts +9 -0
  180. package/sidecar/dist/providers/claude/model-fallback.js +37 -0
  181. package/sidecar/dist/providers/claude/model-fallback.js.map +1 -0
  182. package/sidecar/dist/providers/claude/provider.js +35 -40
  183. package/sidecar/dist/providers/claude/provider.js.map +1 -1
  184. package/sidecar/dist/providers/claude/resolve-binary.js +18 -13
  185. package/sidecar/dist/providers/claude/resolve-binary.js.map +1 -1
  186. package/sidecar/dist/providers/claude/safe-mode.d.ts +5 -5
  187. package/sidecar/dist/providers/claude/safe-mode.js +49 -30
  188. package/sidecar/dist/providers/claude/safe-mode.js.map +1 -1
  189. package/sidecar/dist/providers/claude/secret-files.d.ts +2 -0
  190. package/sidecar/dist/providers/claude/secret-files.js +50 -0
  191. package/sidecar/dist/providers/claude/secret-files.js.map +1 -0
  192. package/sidecar/dist/providers/claude/session-stream.d.ts +18 -0
  193. package/sidecar/dist/providers/claude/session-stream.js +80 -0
  194. package/sidecar/dist/providers/claude/session-stream.js.map +1 -0
  195. package/sidecar/dist/providers/claude/tool-guard.d.ts +14 -0
  196. package/sidecar/dist/providers/claude/tool-guard.js +112 -0
  197. package/sidecar/dist/providers/claude/tool-guard.js.map +1 -0
  198. package/sidecar/dist/providers/codex/adapter.d.ts +10 -0
  199. package/sidecar/dist/providers/codex/adapter.js +20 -5
  200. package/sidecar/dist/providers/codex/adapter.js.map +1 -1
  201. package/sidecar/dist/providers/codex/config.d.ts +6 -17
  202. package/sidecar/dist/providers/codex/config.js +9 -56
  203. package/sidecar/dist/providers/codex/config.js.map +1 -1
  204. package/sidecar/dist/providers/codex/mcp-elicitation.d.ts +21 -0
  205. package/sidecar/dist/providers/codex/mcp-elicitation.js +66 -0
  206. package/sidecar/dist/providers/codex/mcp-elicitation.js.map +1 -0
  207. package/sidecar/dist/providers/codex/module.js +1 -1
  208. package/sidecar/dist/providers/codex/module.js.map +1 -1
  209. package/sidecar/dist/providers/codex/patch-directories.d.ts +6 -0
  210. package/sidecar/dist/providers/codex/patch-directories.js +53 -0
  211. package/sidecar/dist/providers/codex/patch-directories.js.map +1 -0
  212. package/sidecar/dist/providers/codex/permission-profiles.d.ts +11 -0
  213. package/sidecar/dist/providers/codex/permission-profiles.js +37 -0
  214. package/sidecar/dist/providers/codex/permission-profiles.js.map +1 -0
  215. package/sidecar/dist/providers/codex/permissions.d.ts +13 -4
  216. package/sidecar/dist/providers/codex/permissions.js +28 -2
  217. package/sidecar/dist/providers/codex/permissions.js.map +1 -1
  218. package/sidecar/dist/providers/codex/process.d.ts +1 -0
  219. package/sidecar/dist/providers/codex/process.js +3 -1
  220. package/sidecar/dist/providers/codex/process.js.map +1 -1
  221. package/sidecar/dist/providers/codex/protocol/common.d.ts +16 -4
  222. package/sidecar/dist/providers/codex/protocol/index.d.ts +2 -2
  223. package/sidecar/dist/providers/codex/protocol/index.js +1 -1
  224. package/sidecar/dist/providers/codex/protocol/index.js.map +1 -1
  225. package/sidecar/dist/providers/codex/protocol/v2.d.ts +23 -32
  226. package/sidecar/dist/providers/codex/provider.js +13 -12
  227. package/sidecar/dist/providers/codex/provider.js.map +1 -1
  228. package/sidecar/dist/providers/codex/secret-file-globs.d.ts +2 -0
  229. package/sidecar/dist/providers/codex/secret-file-globs.js +45 -0
  230. package/sidecar/dist/providers/codex/secret-file-globs.js.map +1 -0
  231. package/sidecar/dist/providers/types.d.ts +3 -1
  232. package/sidecar/dist/providers/types.js +2 -2
  233. package/sidecar/dist/providers/types.js.map +1 -1
  234. package/sidecar/dist/server/chat-events.js +1 -0
  235. package/sidecar/dist/server/chat-events.js.map +1 -1
  236. package/sidecar/dist/server/http-routes.js +1 -1
  237. package/sidecar/dist/server/http-routes.js.map +1 -1
  238. package/sidecar/dist/server/navigation-completer.d.ts +15 -2
  239. package/sidecar/dist/server/navigation-completer.js +42 -41
  240. package/sidecar/dist/server/navigation-completer.js.map +1 -1
  241. package/sidecar/dist/server/permission-events.d.ts +1 -1
  242. package/sidecar/dist/server/permission-events.js +5 -8
  243. package/sidecar/dist/server/permission-events.js.map +1 -1
  244. package/sidecar/dist/server/routing.js +11 -6
  245. package/sidecar/dist/server/routing.js.map +1 -1
  246. package/sidecar/dist/server/tool-calls.d.ts +0 -2
  247. package/sidecar/dist/server/tool-calls.js +7 -8
  248. package/sidecar/dist/server/tool-calls.js.map +1 -1
  249. package/sidecar/dist/server/turns.js +17 -1
  250. package/sidecar/dist/server/turns.js.map +1 -1
  251. package/sidecar/dist/server/ws.js +4 -15
  252. package/sidecar/dist/server/ws.js.map +1 -1
  253. package/sidecar/dist/skills/skill-usage.js +2 -2
  254. package/sidecar/dist/skills/skill-usage.js.map +1 -1
  255. package/sidecar/dist/state/conversations.d.ts +1 -0
  256. package/sidecar/dist/state/conversations.js +8 -0
  257. package/sidecar/dist/state/conversations.js.map +1 -1
  258. package/sidecar/dist/state/settings-store.d.ts +14 -5
  259. package/sidecar/dist/state/settings-store.js +34 -8
  260. package/sidecar/dist/state/settings-store.js.map +1 -1
  261. package/sidecar/dist/state/settings-types.d.ts +16 -2
  262. package/sidecar/dist/state/settings-types.js +14 -1
  263. package/sidecar/dist/state/settings-types.js.map +1 -1
  264. package/sidecar/dist/state/types.d.ts +14 -6
  265. package/sidecar/dist/state/types.js.map +1 -1
  266. package/sidecar/package.json +3 -3
  267. package/skills/dms-ai/SKILL.md +2 -1
  268. package/skills/dms-builder-safe/REFERENCE.md +5 -6
  269. package/skills/dms-builder-safe/SKILL.md +12 -10
  270. package/skills/dms-external-database/REFERENCE.md +20 -8
  271. package/skills/dms-external-database/SKILL.md +69 -20
  272. package/skills/dms-page-design/SKILL.md +192 -0
  273. package/skills/dms-page-design/cases.json +57 -0
  274. package/frontend-vue/app/chat/components/FullAutoBanner.vue +0 -76
  275. package/frontend-vue/app/chat/components/FullAutoDialog.vue +0 -103
@@ -44,7 +44,9 @@ const MODULE_TOOLS = {
44
44
  isDestructive: true,
45
45
  },
46
46
  BuilderAddBlock: { icon: "i-ph-squares-four", source: "builder" },
47
+ BuilderComposePage: { icon: "i-ph-layout", source: "builder" },
47
48
  BuilderConfigureBlock: { icon: "i-ph-sliders", source: "builder" },
49
+ BuilderConfigureTableView: { icon: "i-ph-table", source: "builder" },
48
50
  BuilderMoveBlock: { icon: "i-ph-arrows-out-cardinal", source: "builder" },
49
51
  BuilderRemoveBlock: {
50
52
  icon: "i-ph-trash",
@@ -76,6 +78,7 @@ const MODULE_TOOLS = {
76
78
  },
77
79
  BuilderQueryTemplates: { icon: "i-ph-books", source: "builder" },
78
80
  BuilderAddQuery: { icon: "i-ph-database", source: "builder" },
81
+ BuilderPreviewQuery: { icon: "i-ph-eye", source: "builder" },
79
82
  BuilderConfigureQuery: { icon: "i-ph-database", source: "builder" },
80
83
  BuilderRemoveQuery: {
81
84
  icon: "i-ph-trash",
@@ -1 +1 @@
1
- {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/vocabulary/tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/vocabulary/tools.ts"],"names":[],"mappings":"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"}
@@ -8,8 +8,11 @@ import {
8
8
  watch,
9
9
  } from "vue";
10
10
  import type { ChatTransport } from "../../runtime/chat-transport";
11
- import type { ConversationStartMode } from "../../runtime/assistant-session";
12
- import type { PanelIntent, PanelIntents } from "../../runtime/panel-intents";
11
+ import type {
12
+ PanelIntent,
13
+ PanelIntents,
14
+ StartConversationIntent,
15
+ } from "../../runtime/panel-intents";
13
16
  import {
14
17
  useChangeSetActions,
15
18
  type ChatApi,
@@ -23,6 +26,7 @@ import {
23
26
  } from "../composables/useConversationId";
24
27
  import { useConversationList } from "../composables/useConversationList";
25
28
  import { useConversationMode } from "../composables/useConversationMode";
29
+ import { useFollowScroll } from "../composables/useFollowScroll";
26
30
  import { usePermissionQueue } from "../composables/usePermissionQueue";
27
31
  import { useQuestionQueue } from "../composables/useQuestionQueue";
28
32
  import { useQueueActions } from "../composables/useQueueActions";
@@ -41,9 +45,10 @@ import type { ConversationSummary, CurrentPage } from "../types/conversation";
41
45
  import type { ExpiredRequest } from "../types/permission";
42
46
  import type { QuestionReply } from "../types/question";
43
47
  import type { PendingAttachment } from "../utils/attachments";
44
- import { formatClock, formatTokens } from "../utils/format";
48
+ import { formatTokens } from "../utils/format";
45
49
  import { newUuid } from "../utils/ids";
46
50
  import { isRunStalled, runElapsedMs } from "../utils/run-status";
51
+ import { describeStatus } from "../utils/status-label";
47
52
  import { bareToolName } from "../utils/tool-lexicon";
48
53
  import { latestTodos } from "../utils/todos";
49
54
  import ApprovalDock from "./ApprovalDock.vue";
@@ -51,7 +56,6 @@ import ChatEmpty from "./ChatEmpty.vue";
51
56
  import Composer from "./Composer.vue";
52
57
  import ConnectionBanner from "./ConnectionBanner.vue";
53
58
  import ConversationDrawer from "./ConversationDrawer.vue";
54
- import FullAutoBanner from "./FullAutoBanner.vue";
55
59
  import MessageList from "./MessageList.vue";
56
60
  import PanelHeader, { type PanelStatusKind } from "./PanelHeader.vue";
57
61
  import QuestionDock from "./QuestionDock.vue";
@@ -90,7 +94,6 @@ const { t } = useChatI18n();
90
94
 
91
95
  const HISTORY_KEY = "j";
92
96
  const ESCAPE_KEY = "Escape";
93
- const SCROLL_STICKY_THRESHOLD_PX = 80;
94
97
  const NAVIGATION_TARGETS: Record<string, string> = {
95
98
  changes: CHANGES_PAGE_PATH,
96
99
  activity: ACTIVITY_PAGE_PATH,
@@ -141,6 +144,7 @@ const nowMs = useRunClock(computed(() => true));
141
144
  const composerRef = ref<FocusableComposer | null>(null);
142
145
  const approvalDockRef = ref<FocusableDock | null>(null);
143
146
  const scrollEl = ref<HTMLElement | null>(null);
147
+ const { follow } = useFollowScroll(scrollEl);
144
148
 
145
149
  const isConnected = channel.isConnected;
146
150
  const isRunning = conversation.isRunning;
@@ -176,27 +180,18 @@ const status = computed<PanelStatusKind>(() => {
176
180
  return isRunning.value ? "working" : "ready";
177
181
  });
178
182
 
179
- const statusLabel = computed<string>(() => {
180
- const labels: Record<PanelStatusKind, () => string> = {
181
- ready: () => t("dms_ai.panel.status.ready"),
182
- working: () =>
183
- t("dms_ai.panel.status.working", {
184
- time: formatClock(
185
- runElapsedMs(conversation.progress.value, nowMs.value),
186
- ),
187
- }),
188
- waiting: () =>
189
- t(
190
- "dms_ai.panel.status.waiting",
191
- { count: pendingCount.value },
192
- pendingCount.value,
193
- ),
194
- connecting: () => t("dms_ai.panel.status.connecting"),
195
- offline: () => t("dms_ai.panel.status.offline"),
196
- };
197
- const label = labels[status.value]();
198
- return status.value === "offline" ? label : `${label} · ${agentName.value}`;
199
- });
183
+ const statusLabel = computed<string>(() =>
184
+ describeStatus(
185
+ {
186
+ kind: status.value,
187
+ elapsedMs: runElapsedMs(conversation.progress.value, nowMs.value),
188
+ pendingCount: pendingCount.value,
189
+ agentName: agentName.value,
190
+ model: conversation.model.value,
191
+ },
192
+ t,
193
+ ),
194
+ );
200
195
 
201
196
  const usageLabel = computed<string>(() => {
202
197
  if (!isConnected.value) return t("dms_ai.panel.composer.usage_offline");
@@ -221,19 +216,10 @@ const isEmpty = computed(
221
216
  () => conversation.messages.value.length === 0 && !isRunning.value,
222
217
  );
223
218
 
224
- // Sent on the tab's stream itself: the chat's own channel is already closed
225
- // when the panel unmounts it.
226
- function leave(conversationId: string): void {
227
- props.transport.send({
228
- type: CLIENT_MESSAGE_TYPES.LEAVE_CONVERSATION,
229
- conversationId,
230
- });
231
- }
232
-
233
219
  function switchConversation(id: string): void {
220
+ follow();
234
221
  isDrawerOpen.value = false;
235
222
  if (id === activeId.value) return;
236
- leave(activeId.value);
237
223
  activeId.value = id;
238
224
  persistConversationId(id);
239
225
  conversation.reset();
@@ -270,12 +256,19 @@ function reviewChangeSet(changeSetId: string): void {
270
256
  navigate(`${CHANGES_PAGE_PATH}?${query.toString()}`);
271
257
  }
272
258
 
259
+ function sendUserMessage(
260
+ ...args: Parameters<typeof conversation.sendUserMessage>
261
+ ): void {
262
+ follow();
263
+ conversation.sendUserMessage(...args);
264
+ }
265
+
273
266
  function submit(
274
267
  content: string,
275
268
  attachments: PendingAttachment[],
276
269
  includePage: boolean,
277
270
  ): void {
278
- conversation.sendUserMessage(
271
+ sendUserMessage(
279
272
  content,
280
273
  attachments,
281
274
  includePage ? {} : { includePageContext: false },
@@ -299,9 +292,7 @@ function stopAutoFix(): void {
299
292
  }
300
293
 
301
294
  function askAgain(summary: string): void {
302
- conversation.sendUserMessage(
303
- t("dms_ai.panel.approvals.ask_again_message", { summary }),
304
- );
295
+ sendUserMessage(t("dms_ai.panel.approvals.ask_again_message", { summary }));
305
296
  }
306
297
 
307
298
  function askAgainExpired(request: ExpiredRequest): void {
@@ -318,23 +309,20 @@ function runPlan(): void {
318
309
  permissions.respond(planRequest.requestId, { decision: "allow_once" });
319
310
  return;
320
311
  }
321
- conversation.sendUserMessage(t("dms_ai.panel.plan.go_ahead"));
312
+ sendUserMessage(t("dms_ai.panel.plan.go_ahead"));
322
313
  }
323
314
 
324
315
  function setDraft(text: string): void {
325
316
  composerRef.value?.setDraft(text);
326
317
  }
327
318
 
328
- /** Sets the new conversation's mode as soon as the stream can carry it, unless the chat moved on. */
329
- function setModeWhenConnected(next: ConversationStartMode): void {
319
+ /** Runs `run` once the stream is up, if still here. */
320
+ function whenConnected(run: () => void): void {
330
321
  const conversationId = activeId.value;
331
322
  const apply = (): void => {
332
- if (activeId.value === conversationId) mode.setMode(next);
323
+ if (activeId.value === conversationId) run();
333
324
  };
334
- if (isConnected.value) {
335
- apply();
336
- return;
337
- }
325
+ if (isConnected.value) return apply();
338
326
  const stop = watch(isConnected, (connected) => {
339
327
  if (!connected) return;
340
328
  stop();
@@ -342,6 +330,20 @@ function setModeWhenConnected(next: ConversationStartMode): void {
342
330
  });
343
331
  }
344
332
 
333
+ function startConversation(intent: StartConversationIntent): void {
334
+ newConversation();
335
+ const { prompt = "", mode: next } = intent;
336
+ const sends = intent.send === true && prompt !== "";
337
+ if (next !== undefined || sends)
338
+ whenConnected(() => {
339
+ if (next !== undefined) mode.setMode(next);
340
+ if (sends) sendUserMessage(prompt);
341
+ });
342
+ if (sends) return;
343
+ if (prompt) void nextTick(() => setDraft(prompt));
344
+ else void nextTick(() => composerRef.value?.focus());
345
+ }
346
+
345
347
  const INTENT_HANDLERS: Record<
346
348
  PanelIntent["kind"],
347
349
  (intent: PanelIntent) => void
@@ -350,12 +352,7 @@ const INTENT_HANDLERS: Record<
350
352
  if (intent.kind === "open") switchConversation(intent.conversationId);
351
353
  },
352
354
  start: (intent) => {
353
- newConversation();
354
- if (intent.kind === "start" && intent.mode)
355
- setModeWhenConnected(intent.mode);
356
- if (intent.kind === "start" && intent.prompt)
357
- void nextTick(() => setDraft(intent.prompt ?? ""));
358
- else void nextTick(() => composerRef.value?.focus());
355
+ if (intent.kind === "start") startConversation(intent);
359
356
  },
360
357
  focus: () => void nextTick(() => composerRef.value?.focus()),
361
358
  approvals: () => {
@@ -406,26 +403,6 @@ function refreshListAfterTurn(msg: unknown): void {
406
403
 
407
404
  channel.onMessage(refreshListAfterTurn);
408
405
 
409
- function isNearBottom(el: HTMLElement): boolean {
410
- return (
411
- el.scrollHeight - el.scrollTop - el.clientHeight <=
412
- SCROLL_STICKY_THRESHOLD_PX
413
- );
414
- }
415
-
416
- function scrollToBottom(): void {
417
- const el = scrollEl.value;
418
- if (el !== null) el.scrollTop = el.scrollHeight;
419
- }
420
-
421
- watch(
422
- () => [conversation.messages.value, isRunning.value],
423
- () => {
424
- const el = scrollEl.value;
425
- if (el === null || isNearBottom(el)) void nextTick(scrollToBottom);
426
- },
427
- );
428
-
429
406
  // The DMS mounts the panel open on a reload, often before the tab's stream
430
407
  // is up: the list (and the chat's title) is asked for again once it is.
431
408
  watch(isConnected, (connected) => {
@@ -435,14 +412,10 @@ watch(isConnected, (connected) => {
435
412
  onMounted(() => {
436
413
  document.addEventListener("keydown", onDocumentKeydown);
437
414
  list.refresh();
438
- void nextTick(scrollToBottom);
439
415
  });
440
416
 
441
- // The DMS unmounts the panel's content when the panel closes: the chat is
442
- // left then, which ends a Full auto granted until the chat closes.
443
417
  onBeforeUnmount(() => {
444
418
  document.removeEventListener("keydown", onDocumentKeydown);
445
- leave(activeId.value);
446
419
  });
447
420
  </script>
448
421
 
@@ -465,12 +438,6 @@ onBeforeUnmount(() => {
465
438
  :is-reviving="isReviving"
466
439
  @reconnect="channel.reconnect"
467
440
  />
468
- <FullAutoBanner
469
- v-if="mode.current.value.fullAuto"
470
- :full-auto="mode.current.value.fullAuto"
471
- :now-ms="nowMs"
472
- @turn-off="mode.stopFullAuto"
473
- />
474
441
 
475
442
  <section
476
443
  ref="scrollEl"
@@ -510,6 +477,7 @@ onBeforeUnmount(() => {
510
477
  v-if="providerProblem"
511
478
  :agent-name="agentName"
512
479
  :reason="settings.providers[settings.provider]?.reason ?? ''"
480
+ :code="settings.providers[settings.provider]?.code"
513
481
  @open-settings="navigate(SETTINGS_PAGE_PATH)"
514
482
  />
515
483
  </section>
@@ -552,6 +520,7 @@ onBeforeUnmount(() => {
552
520
  :is-disabled="!isConnected || providerProblem"
553
521
  :is-running="isRunning"
554
522
  :mode="mode.current.value"
523
+ :provider="settings.provider"
555
524
  :builder-available="settings.builderAvailable"
556
525
  :page="page"
557
526
  :usage-label="usageLabel"
@@ -560,7 +529,6 @@ onBeforeUnmount(() => {
560
529
  @stop="stopTurn"
561
530
  @set-scope="mode.setScope"
562
531
  @set-mode="mode.setMode"
563
- @start-full-auto="mode.startFullAuto"
564
532
  @open-settings="navigate(SETTINGS_PAGE_PATH)"
565
533
  />
566
534
  </div>
@@ -4,13 +4,14 @@ import {
4
4
  NEWLINE_HOTKEY_MODIFIER,
5
5
  SEND_HOTKEY,
6
6
  } from "../constants/conversation";
7
+ import { MODES_BY_PROVIDER } from "../constants/modes";
7
8
  import { useChatI18n } from "../composables/useChatI18n";
8
9
  import { useComposerAttachments } from "../composables/useComposerAttachments";
9
10
  import type { CurrentPage } from "../types/conversation";
10
11
  import type {
11
12
  ApprovalMode,
12
13
  ConversationModeState,
13
- FullAutoDuration,
14
+ ProviderName,
14
15
  Scope,
15
16
  } from "../types/protocol";
16
17
  import {
@@ -20,12 +21,12 @@ import {
20
21
  } from "../utils/attachments";
21
22
  import { shortcutLabel } from "../utils/platform";
22
23
  import { pageChipLabel } from "../utils/suggestions";
23
- import FullAutoDialog from "./FullAutoDialog.vue";
24
24
 
25
25
  interface Props {
26
26
  isDisabled: boolean;
27
27
  isRunning: boolean;
28
28
  mode: ConversationModeState;
29
+ provider: ProviderName;
29
30
  builderAvailable: boolean;
30
31
  page: CurrentPage | null;
31
32
  /** "9.6k tokens · this chat", "new chat", "offline". */
@@ -42,7 +43,6 @@ interface Emits {
42
43
  stop: [];
43
44
  setScope: [scope: Scope];
44
45
  setMode: [mode: ApprovalMode];
45
- startFullAuto: [duration: FullAutoDuration];
46
46
  openSettings: [];
47
47
  }
48
48
 
@@ -50,6 +50,8 @@ interface ModeLook {
50
50
  icon: string;
51
51
  labelKey: string;
52
52
  descriptionKey: string;
53
+ /** Where Codex behaves differently from Claude Code in this mode. */
54
+ codexDescriptionKey?: string;
53
55
  }
54
56
 
55
57
  const props = defineProps<Props>();
@@ -58,17 +60,22 @@ const { t } = useChatI18n();
58
60
 
59
61
  const MAX_HEIGHT_PX = 160;
60
62
  const SCOPES: readonly Scope[] = ["safe", "vibe"];
61
- const MODES: readonly ApprovalMode[] = ["normal", "acceptEdits", "plan"];
62
63
  const MODE_LOOKS: Record<ApprovalMode, ModeLook> = {
63
64
  normal: {
64
65
  icon: "i-ph-hand-palm",
65
66
  labelKey: "dms_ai.common.mode.normal",
66
67
  descriptionKey: "dms_ai.panel.composer.mode_desc.normal",
67
68
  },
69
+ auto: {
70
+ icon: "i-ph-seal-check",
71
+ labelKey: "dms_ai.common.mode.auto",
72
+ descriptionKey: "dms_ai.panel.composer.mode_desc.auto",
73
+ },
68
74
  acceptEdits: {
69
75
  icon: "i-ph-pencil-simple-line",
70
76
  labelKey: "dms_ai.common.mode.acceptEdits",
71
77
  descriptionKey: "dms_ai.panel.composer.mode_desc.acceptEdits",
78
+ codexDescriptionKey: "dms_ai.panel.composer.mode_desc.acceptEdits_codex",
72
79
  },
73
80
  plan: {
74
81
  icon: "i-ph-list-checks",
@@ -85,7 +92,6 @@ const historyKbd = shortcutLabel(HISTORY_KEY);
85
92
 
86
93
  const draft = ref("");
87
94
  const isPageIncluded = ref(true);
88
- const isFullAutoOpen = ref(false);
89
95
  const isFocused = ref(false);
90
96
  const textareaRef = ref<HTMLTextAreaElement | null>(null);
91
97
  const fileInputRef = ref<HTMLInputElement | null>(null);
@@ -100,7 +106,6 @@ const isSendDisabled = computed(
100
106
  const modeLook = computed(
101
107
  () => MODE_LOOKS[props.mode.mode] ?? MODE_LOOKS.normal,
102
108
  );
103
- const isFullAuto = computed(() => props.mode.fullAuto !== null);
104
109
 
105
110
  watch(
106
111
  () => props.page?.path,
@@ -123,27 +128,22 @@ const scopeItems = computed(() =>
123
128
  })),
124
129
  );
125
130
 
131
+ function modeDescriptionKey(look: ModeLook): string {
132
+ return props.provider === "codex"
133
+ ? (look.codexDescriptionKey ?? look.descriptionKey)
134
+ : look.descriptionKey;
135
+ }
136
+
126
137
  const modeItems = computed(() => [
127
138
  [{ type: "label" as const, label: t("dms_ai.panel.composer.mode_menu") }],
128
- MODES.map((mode) => ({
139
+ MODES_BY_PROVIDER[props.provider].map((mode) => ({
129
140
  label: t(MODE_LOOKS[mode].labelKey),
130
- description: t(MODE_LOOKS[mode].descriptionKey),
141
+ description: t(modeDescriptionKey(MODE_LOOKS[mode])),
131
142
  icon: MODE_LOOKS[mode].icon,
132
143
  type: "checkbox" as const,
133
- checked: !isFullAuto.value && props.mode.mode === mode,
144
+ checked: props.mode.mode === mode,
134
145
  onSelect: (): void => emit("setMode", mode),
135
146
  })),
136
- [
137
- {
138
- label: t("dms_ai.panel.composer.full_auto_item"),
139
- description: t("dms_ai.panel.composer.mode_desc.auto"),
140
- icon: "i-ph-lightning",
141
- color: "error" as const,
142
- onSelect: (): void => {
143
- isFullAutoOpen.value = true;
144
- },
145
- },
146
- ],
147
147
  [
148
148
  {
149
149
  label: t("dms_ai.panel.composer.default_mode"),
@@ -310,15 +310,9 @@ defineExpose({
310
310
  :items="modeItems"
311
311
  :content="{ side: 'top', align: 'start' }"
312
312
  >
313
- <button
314
- type="button"
315
- class="cb-mode-btn"
316
- :class="{ 'is-danger': isFullAuto }"
317
- >
318
- <UIcon :name="isFullAuto ? 'i-ph-lightning' : modeLook.icon" />
319
- {{
320
- isFullAuto ? t("dms_ai.common.mode.auto") : t(modeLook.labelKey)
321
- }}
313
+ <button type="button" class="cb-mode-btn">
314
+ <UIcon :name="modeLook.icon" />
315
+ {{ t(modeLook.labelKey) }}
322
316
  <UIcon name="i-ph-caret-down" />
323
317
  </button>
324
318
  </UDropdownMenu>
@@ -388,10 +382,6 @@ defineExpose({
388
382
  </span>
389
383
  <span class="cb-composer__usage">{{ usageLabel }}</span>
390
384
  </div>
391
- <FullAutoDialog
392
- v-model:open="isFullAutoOpen"
393
- @confirm="(duration) => emit('startFullAuto', duration)"
394
- />
395
385
  </form>
396
386
  </template>
397
387
 
@@ -556,12 +546,6 @@ defineExpose({
556
546
  color: var(--ui-success);
557
547
  }
558
548
 
559
- .cb-mode-btn.is-danger {
560
- border-color: var(--dms-error-line);
561
- background: var(--dms-error-tint);
562
- color: var(--ui-error);
563
- }
564
-
565
549
  .cb-composer__file {
566
550
  display: none;
567
551
  }
@@ -30,6 +30,8 @@ const LOOKS: Record<Notice["kind"], NoticeLook> = {
30
30
  permission_expired: { tone: "neutral", icon: "i-ph-timer" },
31
31
  question_skipped: { tone: "neutral", icon: "i-ph-arrow-bend-down-right" },
32
32
  full_auto_ended: { tone: "neutral", icon: "i-ph-lightning-slash" },
33
+ model_fallback: { tone: "warning", icon: "i-ph-swap" },
34
+ auto_unavailable: { tone: "warning", icon: "i-ph-seal-warning" },
33
35
  };
34
36
 
35
37
  const showErrors = ref(false);
@@ -116,6 +118,29 @@ const expiredTool = computed<string>(() => {
116
118
  t("dms_ai.panel.notice.question_skipped", { header: notice.header })
117
119
  }}
118
120
  </template>
121
+ <template v-else-if="notice.kind === 'model_fallback'">
122
+ <b>
123
+ {{
124
+ t("dms_ai.panel.notice.model_fallback_title", {
125
+ model: notice.usedModel,
126
+ })
127
+ }}
128
+ </b>
129
+ {{
130
+ t("dms_ai.panel.notice.model_fallback_text", {
131
+ requested: notice.requestedModel,
132
+ model: notice.usedModel,
133
+ })
134
+ }}
135
+ </template>
136
+ <template v-else-if="notice.kind === 'auto_unavailable'">
137
+ <b>{{ t("dms_ai.panel.notice.auto_unavailable_title") }}</b>
138
+ {{
139
+ t("dms_ai.panel.notice.auto_unavailable_text", {
140
+ model: notice.model,
141
+ })
142
+ }}
143
+ </template>
119
144
  <template v-else>
120
145
  {{ t("dms_ai.panel.notice.full_auto_ended", { time }) }}
121
146
  </template>
@@ -4,13 +4,9 @@ import { useChatI18n } from "../composables/useChatI18n";
4
4
  import type { ActiveRule } from "../types/protocol";
5
5
  import { ruleIcon } from "../utils/permission-view";
6
6
  import { shortcutLabel } from "../utils/platform";
7
+ import type { StatusKind } from "../utils/status-label";
7
8
 
8
- export type PanelStatusKind =
9
- | "ready"
10
- | "working"
11
- | "waiting"
12
- | "connecting"
13
- | "offline";
9
+ export type PanelStatusKind = StatusKind;
14
10
 
15
11
  interface Props {
16
12
  title: string;
@@ -1,19 +1,30 @@
1
1
  <script setup lang="ts">
2
+ import { computed } from "vue";
2
3
  import { useChatI18n } from "../composables/useChatI18n";
4
+ import type { ProviderUnavailableCode } from "../types/settings";
3
5
 
4
6
  interface Props {
5
7
  agentName: string;
6
- /** Why the provider cannot run, as the sidecar reported it. */
8
+ /** Why the provider cannot run, as the sidecar reported it, in English. */
7
9
  reason: string;
10
+ /** Set when the panel words the reason itself. */
11
+ code?: ProviderUnavailableCode;
8
12
  }
9
13
 
14
+ const REASON_KEYS: Record<ProviderUnavailableCode, string> = {
15
+ codex_not_signed_in: "dms_ai.panel.errors.codex_not_signed_in",
16
+ };
17
+
10
18
  interface Emits {
11
19
  openSettings: [];
12
20
  }
13
21
 
14
- defineProps<Props>();
22
+ const props = defineProps<Props>();
15
23
  const emit = defineEmits<Emits>();
16
24
  const { t } = useChatI18n();
25
+ const reasonText = computed(() =>
26
+ props.code === undefined ? props.reason : t(REASON_KEYS[props.code]),
27
+ );
17
28
  </script>
18
29
 
19
30
  <template>
@@ -24,7 +35,7 @@ const { t } = useChatI18n();
24
35
  <b>
25
36
  {{ t("dms_ai.panel.errors.agent_cant_run", { agent: agentName }) }}
26
37
  </b>
27
- {{ reason }}
38
+ {{ reasonText }}
28
39
  {{ t("dms_ai.panel.errors.agent_no_fallback") }}
29
40
  <div class="cb-provider__row">
30
41
  <UButton
@@ -10,7 +10,6 @@ import type {
10
10
  BlockPreview,
11
11
  ChangeSetSummary,
12
12
  ConversationModeState,
13
- FullAutoState,
14
13
  Notice,
15
14
  QueuedItemWire,
16
15
  SnapshotMessage,
@@ -65,7 +64,6 @@ interface RunProgressEvent {
65
64
  interface SnapshotModeWire {
66
65
  mode?: ConversationModeState["mode"];
67
66
  generationMode?: ConversationModeState["generationMode"];
68
- fullAuto?: FullAutoState | null;
69
67
  }
70
68
 
71
69
  interface SnapshotEvent {
@@ -73,6 +71,7 @@ interface SnapshotEvent {
73
71
  changeSets?: ChangeSetSummary[];
74
72
  mode?: SnapshotModeWire;
75
73
  totalTokens?: number;
74
+ model?: string;
76
75
  }
77
76
 
78
77
  interface QueueStateEvent {
@@ -99,6 +98,7 @@ interface BlockPreviewEvent {
99
98
 
100
99
  interface UsageEvent {
101
100
  totalTokens?: number;
101
+ model?: string;
102
102
  }
103
103
 
104
104
  type EventHandler = (state: ConversationState, event: never) => void;
@@ -261,7 +261,6 @@ function toModeState(wire: SnapshotModeWire | undefined) {
261
261
  return {
262
262
  mode: wire.mode,
263
263
  generationMode: wire.generationMode,
264
- fullAuto: wire.fullAuto ?? null,
265
264
  };
266
265
  }
267
266
 
@@ -290,6 +289,7 @@ function applySnapshot(state: ConversationState, event: SnapshotEvent): void {
290
289
  state.changeSets.value = byId(event.changeSets ?? []);
291
290
  state.mode.value = toModeState(event.mode) ?? state.mode.value;
292
291
  state.totalTokens.value = event.totalTokens ?? state.totalTokens.value;
292
+ state.model.value = event.model ?? null;
293
293
  state.isRunning.value = false;
294
294
  state.progress.value = null;
295
295
  state.isTurnInFlight.value = false;
@@ -379,6 +379,7 @@ function appendBlockPreview(
379
379
  }
380
380
 
381
381
  function applyUsage(state: ConversationState, event: UsageEvent): void {
382
+ if (event.model !== undefined) state.model.value = event.model;
382
383
  if (typeof event.totalTokens !== "number") return;
383
384
  state.totalTokens.value = event.totalTokens;
384
385
  }
@@ -49,6 +49,8 @@ export interface UseConversationResult {
49
49
  mode: Ref<ConversationModeState | null>;
50
50
  /** Tokens this chat has used so far; null until the sidecar says. */
51
51
  totalTokens: Ref<number | null>;
52
+ /** The model that answered last; null until a reply names it. */
53
+ model: Ref<string | null>;
52
54
  sendUserMessage: (
53
55
  content: string,
54
56
  attachments?: PendingAttachment[],
@@ -76,6 +78,7 @@ export interface ConversationState {
76
78
  changeSets: Ref<Record<string, ChangeSetSummary>>;
77
79
  mode: Ref<ConversationModeState | null>;
78
80
  totalTokens: Ref<number | null>;
81
+ model: Ref<string | null>;
79
82
  /**
80
83
  * When the calls of the stored transcript started and ended. A re-attach
81
84
  * replays the running turn's events, and the replayed calls take their
@@ -285,6 +288,7 @@ function reset(state: ConversationState): void {
285
288
  state.changeSets.value = {};
286
289
  state.mode.value = null;
287
290
  state.totalTokens.value = null;
291
+ state.model.value = null;
288
292
  state.callTimes.clear();
289
293
  }
290
294
 
@@ -302,6 +306,7 @@ function createConversationState(
302
306
  changeSets: ref<Record<string, ChangeSetSummary>>({}),
303
307
  mode: ref<ConversationModeState | null>(null),
304
308
  totalTokens: ref<number | null>(null),
309
+ model: ref<string | null>(null),
305
310
  callTimes: new Map(),
306
311
  };
307
312
  }
@@ -326,6 +331,7 @@ export function useConversation(
326
331
  changeSets: state.changeSets,
327
332
  mode: state.mode,
328
333
  totalTokens: state.totalTokens,
334
+ model: state.model,
329
335
  sendUserMessage: (content, attachments = [], extra = {}) =>
330
336
  sendUserMessage(state, content, attachments, extra),
331
337
  retry: () => retry(state),