talon-agent 4.6.1 → 5.0.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 (310) hide show
  1. package/README.md +3 -3
  2. package/package.json +2 -1
  3. package/prompts/README.md +2 -2
  4. package/prompts/system/memory-recall.md +16 -0
  5. package/src/app.ts +22 -7
  6. package/src/backend/claude-sdk/factory.ts +21 -41
  7. package/src/backend/claude-sdk/handler.ts +28 -7
  8. package/src/backend/claude-sdk/host/in-process.ts +147 -0
  9. package/src/backend/claude-sdk/one-shot.ts +1 -1
  10. package/src/backend/claude-sdk/options.ts +7 -6
  11. package/src/backend/claude-sdk/stream.ts +30 -3
  12. package/src/backend/claude-sdk/warm.ts +1 -1
  13. package/src/backend/codex/constants.ts +1 -1
  14. package/src/backend/codex/factory.ts +2 -2
  15. package/src/backend/codex/handler/events.ts +1 -1
  16. package/src/backend/codex/handler/message.ts +26 -12
  17. package/src/backend/codex/handler/rollout-accounting.ts +1 -1
  18. package/src/backend/codex/init.ts +1 -1
  19. package/src/backend/codex/mcp-config.ts +2 -2
  20. package/src/backend/codex/one-shot.ts +1 -1
  21. package/src/backend/kilo/handler/message.ts +4 -1
  22. package/src/backend/openai-agents/constants.ts +1 -1
  23. package/src/backend/openai-agents/factory.ts +2 -2
  24. package/src/backend/openai-agents/handler/events.ts +1 -1
  25. package/src/backend/openai-agents/handler/message.ts +8 -4
  26. package/src/backend/openai-agents/init.ts +1 -1
  27. package/src/backend/openai-agents/mcp-pool.ts +2 -2
  28. package/src/backend/opencode/handler/message.ts +4 -1
  29. package/src/backend/remote-server/chat-turn.ts +31 -23
  30. package/src/backend/remote-server/events.ts +3 -3
  31. package/src/backend/remote-server/factory.ts +6 -3
  32. package/src/backend/remote-server/index.ts +1 -1
  33. package/src/backend/remote-server/mcp.ts +1 -1
  34. package/src/backend/remote-server/one-shot.ts +1 -1
  35. package/src/backend/remote-server/server-bindings.ts +1 -1
  36. package/src/backend/remote-server/turn.ts +1 -1
  37. package/src/backend/runtime/cache/cache-metrics.ts +126 -0
  38. package/src/backend/{shared → runtime/cache}/cache-telemetry.ts +22 -2
  39. package/src/backend/{shared → runtime}/index.ts +34 -25
  40. package/src/backend/{shared → runtime/prompt}/delivery-contract.ts +1 -1
  41. package/src/backend/{shared → runtime/prompt}/prompt-format.ts +46 -2
  42. package/src/backend/{shared → runtime/prompt}/system-prompt.ts +4 -4
  43. package/src/backend/{shared → runtime/turn}/delivered-text.ts +1 -1
  44. package/src/backend/{shared → runtime/turn}/delivery.ts +3 -3
  45. package/src/backend/{shared → runtime/turn}/handle-retry.ts +5 -5
  46. package/src/backend/{shared → runtime/turn}/handler-to-events.ts +24 -10
  47. package/src/backend/{shared → runtime/turn}/handler-types.ts +7 -1
  48. package/src/backend/{shared → runtime/turn}/model-retry.ts +2 -2
  49. package/src/backend/{shared → runtime/turn}/result-events.ts +2 -2
  50. package/src/backend/{shared → runtime/turn}/stream-state.ts +2 -2
  51. package/src/backend/{shared → runtime/turn}/turn-interrupt.ts +2 -2
  52. package/src/backend/{shared → runtime/turn}/turn-phases.ts +6 -6
  53. package/src/bootstrap.ts +6 -21
  54. package/src/cli.ts +6 -3
  55. package/src/core/agent-runtime/README.md +15 -0
  56. package/src/core/agent-runtime/agent-host.ts +387 -0
  57. package/src/core/agent-runtime/capabilities.ts +11 -0
  58. package/src/core/agent-runtime/contract-tests.ts +92 -1
  59. package/src/core/agent-runtime/events.ts +1 -1
  60. package/src/core/background/{isolated-agent.ts → cron/isolated-agent.ts} +3 -3
  61. package/src/core/background/{job-health.ts → cron/job-health.ts} +1 -1
  62. package/src/core/background/{job-oneshot.ts → cron/job-oneshot.ts} +5 -5
  63. package/src/core/background/{job-prompt.ts → cron/job-prompt.ts} +1 -1
  64. package/src/core/background/{cron.ts → cron/scheduler.ts} +6 -6
  65. package/src/core/background/{cron-spec.ts → cron/spec.ts} +1 -1
  66. package/src/core/background/{dream.ts → dream/index.ts} +10 -15
  67. package/src/core/background/{plan-alerts.ts → pulse/plan-alerts.ts} +3 -3
  68. package/src/core/background/{pulse.ts → pulse/pulse.ts} +8 -5
  69. package/src/core/background/triggers/command.ts +2 -2
  70. package/src/{util → core/config}/harden.ts +1 -1
  71. package/src/core/config/index.ts +16 -12
  72. package/src/{util → core/daemon}/boot-timer.ts +15 -1
  73. package/src/core/daemon/pidfile.ts +1 -1
  74. package/src/core/daemon/resource-sampler.ts +121 -0
  75. package/src/{util → core/daemon}/respawn.ts +1 -1
  76. package/src/core/doctor/index.ts +1 -1
  77. package/src/core/engine/dispatcher.ts +16 -0
  78. package/src/core/engine/gateway-actions/cron.ts +2 -2
  79. package/src/core/engine/gateway-actions/fetch-url.ts +1 -1
  80. package/src/core/engine/gateway-actions/index.ts +4 -1
  81. package/src/core/engine/gateway-actions/memory.ts +335 -0
  82. package/src/core/engine/gateway-actions/native/exec-background.ts +129 -0
  83. package/src/core/engine/gateway-actions/native/exec-remote.ts +85 -0
  84. package/src/core/engine/gateway-actions/native/exec.ts +182 -0
  85. package/src/core/engine/gateway-actions/native/index.ts +46 -0
  86. package/src/core/engine/gateway-actions/native/params.ts +46 -0
  87. package/src/core/engine/gateway-actions/native/read.ts +182 -0
  88. package/src/core/engine/gateway-actions/native/results.ts +34 -0
  89. package/src/core/engine/gateway-actions/native/search.ts +212 -0
  90. package/src/core/engine/gateway-actions/native/shell.ts +39 -0
  91. package/src/core/engine/gateway-actions/native/teleport.ts +55 -0
  92. package/src/core/engine/gateway-actions/native/write.ts +170 -0
  93. package/src/core/engine/gateway.ts +0 -6
  94. package/src/core/frontend-runtime/builtins.ts +2 -2
  95. package/src/{util → core/frontend-runtime}/chat-id.ts +30 -0
  96. package/src/core/mcp-hub/index.ts +1 -1
  97. package/src/core/mcp-hub/talon-server.ts +1 -1
  98. package/src/core/memory/import.ts +3 -2
  99. package/src/core/memory/taps.ts +199 -0
  100. package/src/core/memory/turn-retrieval.ts +222 -0
  101. package/src/core/plugin/mcp.ts +1 -1
  102. package/src/core/prompt/assemble.ts +2 -12
  103. package/src/core/prompt/index.ts +2 -2
  104. package/src/core/prompt/invalidation.ts +1 -1
  105. package/src/core/{scripting/lua-runner.ts → scripts/lua.ts} +1 -1
  106. package/src/core/tasks/index.ts +1 -1
  107. package/src/core/tools/{chat.ts → chat/chat.ts} +1 -1
  108. package/src/core/tools/{cross-send.ts → chat/cross-send.ts} +1 -1
  109. package/src/core/tools/{history.ts → chat/history.ts} +2 -2
  110. package/src/core/tools/{media.ts → chat/media.ts} +1 -1
  111. package/src/core/tools/{members.ts → chat/members.ts} +2 -2
  112. package/src/core/tools/{messaging.ts → chat/messaging.ts} +2 -2
  113. package/src/core/tools/{moderation.ts → chat/moderation.ts} +2 -2
  114. package/src/core/tools/{stickers.ts → chat/stickers.ts} +2 -2
  115. package/src/core/tools/{whatsapp.ts → chat/whatsapp.ts} +1 -1
  116. package/src/core/tools/content/memory.ts +128 -0
  117. package/src/core/tools/{web.ts → content/web.ts} +1 -1
  118. package/src/core/tools/index.ts +21 -19
  119. package/src/core/tools/{admin.ts → ops/admin.ts} +1 -1
  120. package/src/core/tools/{bridge.ts → ops/bridge.ts} +2 -2
  121. package/src/core/tools/{goals.ts → ops/goals.ts} +2 -2
  122. package/src/core/tools/{mesh.ts → ops/mesh.ts} +1 -1
  123. package/src/core/tools/{models.ts → ops/models.ts} +1 -1
  124. package/src/core/tools/{native.ts → ops/native.ts} +1 -1
  125. package/src/core/tools/{scheduling.ts → ops/scheduling.ts} +1 -1
  126. package/src/core/tools/{scripts.ts → ops/scripts.ts} +1 -1
  127. package/src/core/tools/{skills.ts → ops/skills.ts} +1 -1
  128. package/src/core/tools/{triggers.ts → ops/triggers.ts} +1 -1
  129. package/src/core/tools/types.ts +1 -0
  130. package/src/{util → core/vfs}/workspace.ts +2 -2
  131. package/src/core/weaver/turn-cpu.ts +32 -0
  132. package/src/core/weaver/weaver.ts +36 -0
  133. package/src/frontend/discord/admin.ts +1 -1
  134. package/src/frontend/discord/callbacks/components/backend-select.ts +1 -1
  135. package/src/frontend/discord/callbacks/components/effort.ts +1 -1
  136. package/src/frontend/discord/callbacks/components/index.ts +1 -1
  137. package/src/frontend/discord/callbacks/components/pulse.ts +1 -1
  138. package/src/frontend/discord/callbacks/components/settings.ts +2 -2
  139. package/src/frontend/discord/callbacks/modals.ts +4 -1
  140. package/src/frontend/discord/commands/admin.ts +2 -36
  141. package/src/frontend/discord/commands/definitions.ts +0 -11
  142. package/src/frontend/discord/commands/info.ts +1 -1
  143. package/src/frontend/discord/commands/interaction.ts +1 -1
  144. package/src/frontend/discord/commands/router.ts +0 -3
  145. package/src/frontend/discord/commands/session.ts +8 -2
  146. package/src/frontend/discord/commands/settings.ts +2 -2
  147. package/src/frontend/discord/handlers/messages.ts +1 -1
  148. package/src/frontend/discord/handlers/state.ts +1 -1
  149. package/src/frontend/discord/middleware.ts +2 -26
  150. package/src/frontend/discord/ready.ts +1 -1
  151. package/src/frontend/discord/render.ts +41 -259
  152. package/src/frontend/discord/runtime.ts +1 -2
  153. package/src/frontend/native/{auth.ts → bridge/auth.ts} +2 -2
  154. package/src/frontend/native/{discovery.ts → bridge/discovery.ts} +3 -3
  155. package/src/frontend/native/{routes → bridge/routes}/chats.ts +1 -1
  156. package/src/frontend/native/{routes → bridge/routes}/daemon.ts +1 -1
  157. package/src/frontend/native/{routes → bridge/routes}/host.ts +6 -3
  158. package/src/frontend/native/{routes → bridge/routes}/pre-auth.ts +1 -1
  159. package/src/frontend/native/{server.ts → bridge/server.ts} +3 -3
  160. package/src/frontend/native/{tls.ts → bridge/tls.ts} +2 -2
  161. package/src/frontend/native/{chat-lifecycle.ts → chats/chat-lifecycle.ts} +3 -3
  162. package/src/frontend/native/{chat-wire.ts → chats/chat-wire.ts} +4 -4
  163. package/src/frontend/native/{chats.ts → chats/chats.ts} +4 -4
  164. package/src/frontend/native/{empty-chat-sweep.ts → chats/empty-chat-sweep.ts} +4 -4
  165. package/src/frontend/native/{history.ts → chats/history.ts} +7 -7
  166. package/src/frontend/native/{reset.ts → chats/reset.ts} +7 -7
  167. package/src/frontend/native/index.ts +13 -10
  168. package/src/frontend/native/{media.ts → media/media.ts} +3 -3
  169. package/src/frontend/native/runtime.ts +1 -1
  170. package/src/frontend/native/{control.ts → surface/control.ts} +4 -4
  171. package/src/frontend/native/{extensions.ts → surface/extensions.ts} +12 -9
  172. package/src/frontend/native/{handlers.ts → surface/handlers.ts} +19 -14
  173. package/src/frontend/native/{logs.ts → surface/logs.ts} +2 -2
  174. package/src/frontend/native/{memory.ts → surface/memory.ts} +2 -2
  175. package/src/frontend/native/{models.ts → surface/models.ts} +17 -10
  176. package/src/frontend/native/{settings.ts → surface/settings.ts} +9 -9
  177. package/src/frontend/native/{status.ts → surface/status.ts} +3 -3
  178. package/src/frontend/native/{actions.ts → turn/actions.ts} +7 -4
  179. package/src/frontend/native/{context.ts → turn/context.ts} +8 -8
  180. package/src/frontend/native/{emit.ts → turn/emit.ts} +7 -7
  181. package/src/frontend/native/{queue.ts → turn/queue.ts} +3 -3
  182. package/src/frontend/native/{turn-meta.ts → turn/turn-meta.ts} +2 -2
  183. package/src/frontend/native/{turn.ts → turn/turn.ts} +9 -9
  184. package/src/frontend/{shared → presentation}/format.ts +4 -3
  185. package/src/frontend/{shared → presentation}/model-commands.ts +1 -1
  186. package/src/frontend/{shared → presentation}/reasoning-levels.ts +12 -0
  187. package/src/frontend/presentation/reports.ts +493 -0
  188. package/src/frontend/{shared → presentation}/session-status.ts +36 -9
  189. package/src/frontend/{shared → presentation}/status-context.ts +101 -2
  190. package/src/frontend/teams/commands.ts +2 -2
  191. package/src/frontend/teams/turn.ts +1 -1
  192. package/src/frontend/telegram/admin/background.ts +1 -1
  193. package/src/frontend/telegram/admin/health.ts +1 -1
  194. package/src/frontend/telegram/admin/sessions.ts +1 -1
  195. package/src/frontend/telegram/callbacks/effort.ts +2 -2
  196. package/src/frontend/telegram/callbacks/metrics.ts +1 -1
  197. package/src/frontend/telegram/callbacks/model/backend.ts +1 -1
  198. package/src/frontend/telegram/callbacks/model/views.ts +1 -1
  199. package/src/frontend/telegram/callbacks/pulse.ts +1 -1
  200. package/src/frontend/telegram/callbacks/query.ts +1 -1
  201. package/src/frontend/telegram/callbacks/settings.ts +3 -3
  202. package/src/frontend/telegram/commands/admin.ts +6 -41
  203. package/src/frontend/telegram/commands/index.ts +1 -1
  204. package/src/frontend/telegram/commands/info.ts +2 -2
  205. package/src/frontend/telegram/commands/session.ts +9 -3
  206. package/src/frontend/telegram/commands/settings.ts +5 -3
  207. package/src/frontend/telegram/handlers/messages.ts +0 -10
  208. package/src/frontend/telegram/handlers/state.ts +1 -1
  209. package/src/frontend/telegram/index.ts +1 -5
  210. package/src/frontend/telegram/middleware.ts +1 -15
  211. package/src/frontend/telegram/model-menu.ts +1 -1
  212. package/src/frontend/telegram/render/html.ts +30 -0
  213. package/src/frontend/telegram/{helpers → render}/menu.ts +46 -19
  214. package/src/frontend/telegram/render/reports.ts +182 -0
  215. package/src/frontend/terminal/builtins/context.ts +2 -2
  216. package/src/frontend/terminal/builtins/session.ts +1 -1
  217. package/src/frontend/terminal/builtins/status.ts +2 -2
  218. package/src/frontend/terminal/index.ts +2 -2
  219. package/src/frontend/terminal/renderer.ts +1 -1
  220. package/src/frontend/whatsapp/access.ts +2 -2
  221. package/src/frontend/whatsapp/actions/history.ts +2 -2
  222. package/src/frontend/whatsapp/actions/messaging.ts +2 -2
  223. package/src/frontend/whatsapp/actions/moderation.ts +1 -1
  224. package/src/frontend/whatsapp/actions/send.ts +1 -1
  225. package/src/frontend/whatsapp/commands.ts +12 -6
  226. package/src/frontend/whatsapp/{connection.ts → connection/connection.ts} +5 -5
  227. package/src/frontend/whatsapp/{pairing-service.ts → connection/pairing-service.ts} +3 -3
  228. package/src/frontend/whatsapp/{wa-logger.ts → connection/wa-logger.ts} +2 -2
  229. package/src/frontend/whatsapp/index.ts +4 -4
  230. package/src/frontend/whatsapp/{inbound.ts → messages/inbound.ts} +15 -15
  231. package/src/frontend/whatsapp/{media-store.ts → messages/media-store.ts} +4 -4
  232. package/src/frontend/whatsapp/{message-store.ts → messages/message-store.ts} +1 -1
  233. package/src/frontend/whatsapp/{turn-recovery.ts → messages/turn-recovery.ts} +4 -4
  234. package/src/frontend/whatsapp/registry.ts +2 -2
  235. package/src/frontend/whatsapp/runtime.ts +1 -1
  236. package/src/index.ts +6 -3
  237. package/src/storage/db.ts +6 -1
  238. package/src/storage/memory.ts +59 -8
  239. package/src/storage/metrics.ts +38 -0
  240. package/src/storage/repositories/sessions-repo.ts +6 -0
  241. package/src/storage/session-record.ts +13 -2
  242. package/src/storage/sessions.ts +12 -0
  243. package/src/storage/sql/db.sql +5 -0
  244. package/src/storage/sql/schema.sql +4 -0
  245. package/src/storage/sql/sessions.sql +3 -3
  246. package/src/storage/sql/statements.generated.ts +10 -3
  247. package/src/storage/sql/turn-meta.sql +1 -1
  248. package/src/util/log.ts +1 -1
  249. package/src/util/paths.ts +0 -2
  250. package/src/util/runtime.ts +1 -1
  251. package/src/core/engine/gateway-actions/native.ts +0 -1035
  252. package/src/core/soul/README.md +0 -110
  253. package/src/core/soul/RESEARCH.md +0 -98
  254. package/src/core/soul/associative.ts +0 -98
  255. package/src/core/soul/centrality.ts +0 -98
  256. package/src/core/soul/cluster.ts +0 -83
  257. package/src/core/soul/compiler.ts +0 -207
  258. package/src/core/soul/consolidate.ts +0 -179
  259. package/src/core/soul/critic.ts +0 -162
  260. package/src/core/soul/dag.ts +0 -265
  261. package/src/core/soul/delta.ts +0 -123
  262. package/src/core/soul/drift.ts +0 -99
  263. package/src/core/soul/embedder.ts +0 -129
  264. package/src/core/soul/emergent-critic.ts +0 -96
  265. package/src/core/soul/forgetting.ts +0 -131
  266. package/src/core/soul/governance.ts +0 -93
  267. package/src/core/soul/hash.ts +0 -97
  268. package/src/core/soul/hdc.ts +0 -154
  269. package/src/core/soul/kernel.ts +0 -540
  270. package/src/core/soul/lattice.ts +0 -103
  271. package/src/core/soul/lens.ts +0 -110
  272. package/src/core/soul/projector.ts +0 -240
  273. package/src/core/soul/reflect.ts +0 -170
  274. package/src/core/soul/reflex.ts +0 -164
  275. package/src/core/soul/retrieve.ts +0 -146
  276. package/src/core/soul/salience.ts +0 -146
  277. package/src/core/soul/service.ts +0 -204
  278. package/src/core/soul/settings.ts +0 -47
  279. package/src/core/soul/signals.ts +0 -117
  280. package/src/core/soul/talon-embedder.ts +0 -80
  281. package/src/core/soul/taps.ts +0 -199
  282. package/src/core/soul/types.ts +0 -298
  283. package/src/core/soul/valence.ts +0 -83
  284. package/src/frontend/telegram/helpers/diagnostics.ts +0 -428
  285. package/src/frontend/telegram/helpers/format.ts +0 -42
  286. package/src/frontend/telegram/helpers/index.ts +0 -13
  287. package/src/util/cleanup-registry.ts +0 -36
  288. /package/src/backend/{shared → runtime}/frontends.ts +0 -0
  289. /package/src/backend/{shared → runtime}/metrics.ts +0 -0
  290. /package/src/backend/{shared → runtime}/sleep.ts +0 -0
  291. /package/src/backend/{shared → runtime/turn}/flow-violation.ts +0 -0
  292. /package/src/backend/{shared → runtime}/usage.ts +0 -0
  293. /package/src/{util/mcp-launcher.ts → core/mcp-hub/launcher.ts} +0 -0
  294. /package/src/{util → core/tools/content}/web-content.ts +0 -0
  295. /package/src/core/tools/{mcp-env.ts → ops/mcp-env.ts} +0 -0
  296. /package/src/{util → core/weaver}/session-name.ts +0 -0
  297. /package/src/frontend/native/{routes → bridge/routes}/index.ts +0 -0
  298. /package/src/frontend/native/{routes → bridge/routes}/memory.ts +0 -0
  299. /package/src/frontend/native/{routes → bridge/routes}/mesh.ts +0 -0
  300. /package/src/frontend/native/{routes → bridge/routes}/models.ts +0 -0
  301. /package/src/frontend/native/{routes → bridge/routes}/params.ts +0 -0
  302. /package/src/frontend/native/{routes → bridge/routes}/table.ts +0 -0
  303. /package/src/frontend/native/{tool-result.ts → turn/tool-result.ts} +0 -0
  304. /package/src/frontend/{shared → presentation}/access.ts +0 -0
  305. /package/src/frontend/{shared → presentation}/plan-usage-report.ts +0 -0
  306. /package/src/frontend/whatsapp/{auth-state.ts → connection/auth-state.ts} +0 -0
  307. /package/src/frontend/whatsapp/{identity.ts → connection/identity.ts} +0 -0
  308. /package/src/frontend/whatsapp/{pairing-lock.ts → connection/pairing-lock.ts} +0 -0
  309. /package/src/frontend/whatsapp/{pairing.ts → connection/pairing.ts} +0 -0
  310. /package/src/frontend/whatsapp/{pins.ts → messages/pins.ts} +0 -0
@@ -15,11 +15,11 @@
15
15
  * means the removal is broadcast, so open lists update in place.
16
16
  */
17
17
 
18
- import { log, logError } from "../../util/log.js";
19
- import { getRecentHistory } from "../../storage/history.js";
18
+ import { log, logError } from "../../../util/log.js";
19
+ import { getRecentHistory } from "../../../storage/history.js";
20
20
  import { deleteChat } from "./chat-lifecycle.js";
21
- import type { NativeRuntime } from "./runtime.js";
22
- import { isBusy } from "./turn.js";
21
+ import type { NativeRuntime } from "../runtime.js";
22
+ import { isBusy } from "../turn/turn.js";
23
23
 
24
24
  const EMPTY_CHAT_MIN_AGE_MS = 60 * 60_000;
25
25
  const EMPTY_CHAT_SWEEP_INTERVAL_MS = 30 * 60_000;
@@ -10,19 +10,19 @@ import {
10
10
  searchHistoryMessages,
11
11
  type HistoryMessage,
12
12
  type MessageAttachment,
13
- } from "../../storage/history.js";
14
- import { isDeliveryTool } from "../../core/tools/index.js";
13
+ } from "../../../storage/history.js";
14
+ import { isDeliveryTool } from "../../../core/tools/index.js";
15
15
  import type { ChatEntry } from "./chats.js";
16
- import { refreshContext } from "./context.js";
17
- import { contentTypeFor, rehydrateAttachment } from "./media.js";
16
+ import { refreshContext } from "../turn/context.js";
17
+ import { contentTypeFor, rehydrateAttachment } from "../media/media.js";
18
18
  import {
19
19
  historyToClientMessage,
20
20
  type ClientAttachment,
21
21
  type ClientMessage,
22
22
  type SearchResult,
23
- } from "./protocol.js";
24
- import type { NativeRuntime } from "./runtime.js";
25
- import { getTurnMeta } from "./turn-meta.js";
23
+ } from "../protocol.js";
24
+ import type { NativeRuntime } from "../runtime.js";
25
+ import { getTurnMeta } from "../turn/turn-meta.js";
26
26
 
27
27
  export type HistoryPageOptions = { before?: number; limit?: number };
28
28
 
@@ -3,14 +3,14 @@
3
3
  * cached readouts, pulse checkpoint) while keeping the chat itself.
4
4
  */
5
5
 
6
- import { resetSession } from "../../storage/sessions.js";
7
- import { clearHistory } from "../../storage/history.js";
8
- import { resetPulseCheckpoint } from "../../core/background/pulse.js";
9
- import { getBackendForChat } from "../../core/engine/backend-controller/index.js";
6
+ import { resetSession } from "../../../storage/sessions.js";
7
+ import { clearHistory } from "../../../storage/history.js";
8
+ import { resetPulseCheckpoint } from "../../../core/background/pulse/pulse.js";
9
+ import { getBackendForChat } from "../../../core/engine/backend-controller/index.js";
10
10
  import { broadcastChatUpdated } from "./chat-wire.js";
11
- import { emitSystem } from "./emit.js";
12
- import type { NativeRuntime } from "./runtime.js";
13
- import { clearTurnMeta } from "./turn-meta.js";
11
+ import { emitSystem } from "../turn/emit.js";
12
+ import type { NativeRuntime } from "../runtime.js";
13
+ import { clearTurnMeta } from "../turn/turn-meta.js";
14
14
 
15
15
  /**
16
16
  * Forget everything the conversation accumulated. Shared by the explicit
@@ -18,18 +18,21 @@ import type { TalonConfig } from "../../core/config/index.js";
18
18
  import type { ContextManager } from "../../core/types.js";
19
19
  import type { Gateway } from "../../core/engine/gateway.js";
20
20
  import { log, logError } from "../../util/log.js";
21
- import { createNativeActionHandler } from "./actions.js";
22
- import { loadOrCreateBridgeToken } from "./auth.js";
23
- import { warmContextCache } from "./context.js";
24
- import { removeBridgeDiscovery, writeBridgeDiscovery } from "./discovery.js";
25
- import { emitAssistant, emitPhoto } from "./emit.js";
26
- import { startEmptyChatSweep } from "./empty-chat-sweep.js";
27
- import { buildBridgeHandlers } from "./handlers.js";
21
+ import { createNativeActionHandler } from "./turn/actions.js";
22
+ import { loadOrCreateBridgeToken } from "./bridge/auth.js";
23
+ import { warmContextCache } from "./turn/context.js";
24
+ import {
25
+ removeBridgeDiscovery,
26
+ writeBridgeDiscovery,
27
+ } from "./bridge/discovery.js";
28
+ import { emitAssistant, emitPhoto } from "./turn/emit.js";
29
+ import { startEmptyChatSweep } from "./chats/empty-chat-sweep.js";
30
+ import { buildBridgeHandlers } from "./surface/handlers.js";
28
31
  import { createNativeRuntime, type NativeRuntime } from "./runtime.js";
29
- import { BridgeServer } from "./server.js";
30
- import { isLoopbackHost, loadOrCreateBridgeTlsIdentity } from "./tls.js";
32
+ import { BridgeServer } from "./bridge/server.js";
33
+ import { isLoopbackHost, loadOrCreateBridgeTlsIdentity } from "./bridge/tls.js";
31
34
 
32
- export { summarizeToolResult } from "./tool-result.js";
35
+ export { summarizeToolResult } from "./turn/tool-result.js";
33
36
 
34
37
  export type NativeFrontend = {
35
38
  name: "native";
@@ -9,9 +9,9 @@ import { mkdir, unlink } from "node:fs/promises";
9
9
  import { basename, extname, join } from "node:path";
10
10
  import { pipeline } from "node:stream/promises";
11
11
  import type { Readable } from "node:stream";
12
- import { dirs } from "../../util/paths.js";
13
- import type { ClientAttachment } from "./protocol.js";
14
- import type { NativeRuntime } from "./runtime.js";
12
+ import { dirs } from "../../../util/paths.js";
13
+ import type { ClientAttachment } from "../protocol.js";
14
+ import type { NativeRuntime } from "../runtime.js";
15
15
 
16
16
  /**
17
17
  * Upload ceiling. Bodies stream straight to disk, so this bounds what a
@@ -11,7 +11,7 @@
11
11
  import type { TalonConfig } from "../../core/config/index.js";
12
12
  import type { Gateway } from "../../core/engine/gateway.js";
13
13
  import { getMeshService, type MeshService } from "../../core/mesh/index.js";
14
- import { NativeChats } from "./chats.js";
14
+ import { NativeChats } from "./chats/chats.js";
15
15
  import type {
16
16
  BridgeEvent,
17
17
  ClientAttachment,
@@ -4,10 +4,10 @@
4
4
 
5
5
  import { dirname, resolve } from "node:path";
6
6
  import { spawn } from "node:child_process";
7
- import { isBunRuntime } from "../../util/runtime.js";
8
- import { logError } from "../../util/log.js";
9
- import { PKG_ROOT } from "../../cli/context.js";
10
- import { forceDream } from "../../core/background/dream.js";
7
+ import { isBunRuntime } from "../../../util/runtime.js";
8
+ import { logError } from "../../../util/log.js";
9
+ import { PKG_ROOT } from "../../../cli/context.js";
10
+ import { forceDream } from "../../../core/background/dream/index.js";
11
11
 
12
12
  /**
13
13
  * Restart the daemon by spawning a detached `talon restart` — the same
@@ -17,18 +17,21 @@
17
17
  * gating on top.
18
18
  */
19
19
 
20
- import type { Backend } from "../../core/agent-runtime/capabilities.js";
21
- import { performPluginReload } from "../../core/engine/gateway-actions/plugins.js";
22
- import { getPluginPromptAdditions } from "../../core/plugin/index.js";
23
- import { listPluginItems, setPluginEnabled } from "../../core/plugin/manage.js";
24
- import { notifyPromptInputsChanged } from "../../core/prompt/invalidation.js";
25
- import { listSkills, setSkillEnabled } from "../../storage/skills.js";
20
+ import type { Backend } from "../../../core/agent-runtime/capabilities.js";
21
+ import { performPluginReload } from "../../../core/engine/gateway-actions/plugins.js";
22
+ import { getPluginPromptAdditions } from "../../../core/plugin/index.js";
23
+ import {
24
+ listPluginItems,
25
+ setPluginEnabled,
26
+ } from "../../../core/plugin/manage.js";
27
+ import { notifyPromptInputsChanged } from "../../../core/prompt/invalidation.js";
28
+ import { listSkills, setSkillEnabled } from "../../../storage/skills.js";
26
29
  import {
27
30
  rebuildSystemPrompt,
28
31
  type TalonConfig,
29
- } from "../../core/config/index.js";
30
- import { log } from "../../util/log.js";
31
- import type { PluginItem, SkillItem, ToggleResult } from "./protocol.js";
32
+ } from "../../../core/config/index.js";
33
+ import { log } from "../../../util/log.js";
34
+ import type { PluginItem, SkillItem, ToggleResult } from "../protocol.js";
32
35
  import { persistConfigPatch } from "./settings.js";
33
36
 
34
37
  export function pluginItems(config: TalonConfig): PluginItem[] {
@@ -4,11 +4,11 @@
4
4
  * anything with logic of its own lives in the module named for it.
5
5
  */
6
6
 
7
- import { files } from "../../util/paths.js";
8
- import { setChatPulse } from "../../storage/chat-settings.js";
9
- import { getPooledBackend } from "../../core/engine/backend-controller/index.js";
10
- import { createChat, deleteChat, renameChat } from "./chat-lifecycle.js";
11
- import { broadcastChatUpdated, toClientChat } from "./chat-wire.js";
7
+ import { files } from "../../../util/paths.js";
8
+ import { setChatPulse } from "../../../storage/chat-settings.js";
9
+ import { getPooledBackend } from "../../../core/engine/backend-controller/index.js";
10
+ import { createChat, deleteChat, renameChat } from "../chats/chat-lifecycle.js";
11
+ import { broadcastChatUpdated, toClientChat } from "../chats/chat-wire.js";
12
12
  import { control } from "./control.js";
13
13
  import {
14
14
  pluginItems,
@@ -16,7 +16,7 @@ import {
16
16
  togglePlugin,
17
17
  toggleSkill,
18
18
  } from "./extensions.js";
19
- import { historyPage, searchHistory } from "./history.js";
19
+ import { historyPage, searchHistory } from "../chats/history.js";
20
20
  import { readLogEntries } from "./logs.js";
21
21
  import { listMemory, memoryWhy } from "./memory.js";
22
22
  import {
@@ -24,7 +24,7 @@ import {
24
24
  MAX_UPLOAD_BYTES,
25
25
  resolveUpload,
26
26
  saveUploadStream,
27
- } from "./media.js";
27
+ } from "../media/media.js";
28
28
  import {
29
29
  effortLevels,
30
30
  listBackends,
@@ -33,15 +33,20 @@ import {
33
33
  setEffort,
34
34
  setModel,
35
35
  } from "./models.js";
36
- import { setQueued } from "./queue.js";
37
- import { resetChat } from "./reset.js";
38
- import type { NativeRuntime } from "./runtime.js";
39
- import type { BridgeServerHandlers, SendOptions } from "./server.js";
40
- import type { ClientAttachment } from "./protocol.js";
36
+ import { setQueued } from "../turn/queue.js";
37
+ import { resetChat } from "../chats/reset.js";
38
+ import type { NativeRuntime } from "../runtime.js";
39
+ import type { BridgeServerHandlers, SendOptions } from "../bridge/server.js";
40
+ import type { ClientAttachment } from "../protocol.js";
41
41
  import { configSnapshot, applyConfigUpdate } from "./settings.js";
42
42
  import { bridgeStatus, broadcastStatus } from "./status.js";
43
- import { logWarn } from "../../util/log.js";
44
- import { interruptTurn, isBusy, liveTurnEvents, startTurn } from "./turn.js";
43
+ import { logWarn } from "../../../util/log.js";
44
+ import {
45
+ interruptTurn,
46
+ isBusy,
47
+ liveTurnEvents,
48
+ startTurn,
49
+ } from "../turn/turn.js";
45
50
 
46
51
  /**
47
52
  * Turn a `/send` body's attachment references into the records this daemon
@@ -7,8 +7,8 @@
7
7
  * Pure functions over a raw tail string; file I/O stays with the caller.
8
8
  */
9
9
 
10
- import { tailFile } from "../../util/tail-file.js";
11
- import type { LogEntry, LogLevel } from "./protocol.js";
10
+ import { tailFile } from "../../../util/tail-file.js";
11
+ import type { LogEntry, LogLevel } from "../protocol.js";
12
12
 
13
13
  /** pino numeric levels → wire level names. */
14
14
  const PINO_LEVELS: Record<number, LogLevel> = {
@@ -23,12 +23,12 @@ import {
23
23
  type MemoryHistoryRow,
24
24
  type MemoryKind,
25
25
  type MemoryRow,
26
- } from "../../storage/memory.js";
26
+ } from "../../../storage/memory.js";
27
27
  import type {
28
28
  MemoryHistoryWire,
29
29
  MemoryRowWire,
30
30
  MemoryWhyWire,
31
- } from "./protocol.js";
31
+ } from "../protocol.js";
32
32
 
33
33
  /** Hard ceiling on one listing, whatever the client asks for. */
34
34
  const MAX_LIMIT = 100;
@@ -12,7 +12,7 @@ import {
12
12
  setChatBackend,
13
13
  EFFORT_LEVELS,
14
14
  type EffortLevel,
15
- } from "../../storage/chat-settings.js";
15
+ } from "../../../storage/chat-settings.js";
16
16
  import {
17
17
  getBackendForChat,
18
18
  getBackendIdForChat,
@@ -20,13 +20,13 @@ import {
20
20
  acquireBackendInstance,
21
21
  listAvailableBackends,
22
22
  rebindChat,
23
- } from "../../core/engine/backend-controller/index.js";
24
- import { getActiveReasoningLevels } from "../shared/reasoning-levels.js";
25
- import { broadcastChatUpdated } from "./chat-wire.js";
26
- import { emitSystem } from "./emit.js";
27
- import type { BackendOption, ModelOption } from "./protocol.js";
28
- import { wipeChatConversation } from "./reset.js";
29
- import type { NativeRuntime } from "./runtime.js";
23
+ } from "../../../core/engine/backend-controller/index.js";
24
+ import { getActiveReasoningLevels } from "../../presentation/reasoning-levels.js";
25
+ import { broadcastChatUpdated } from "../chats/chat-wire.js";
26
+ import { emitSystem } from "../turn/emit.js";
27
+ import type { BackendOption, ModelOption } from "../protocol.js";
28
+ import { wipeChatConversation } from "../chats/reset.js";
29
+ import type { NativeRuntime } from "../runtime.js";
30
30
  import { broadcastStatus } from "./status.js";
31
31
 
32
32
  export async function listModels(
@@ -104,8 +104,15 @@ export function setModel(
104
104
  // Persisted setting first — see toClientChat. Writing the pick under the
105
105
  // live binding's key would attach it to the wrong backend whenever the
106
106
  // boot-time rebind to the persisted backend is still pending.
107
- const backendId =
108
- getChatSettings(chatId).backend ?? getBackendIdForChat(chatId);
107
+ let backendId: string;
108
+ try {
109
+ backendId = getChatSettings(chatId).backend ?? getBackendIdForChat(chatId);
110
+ } catch {
111
+ // Pool not ready — the same fallback listModels uses in this state, so
112
+ // the pick lands under the backend whose catalog the client was shown.
113
+ // Letting this throw would 400 the route and drop the pick entirely.
114
+ backendId = runtime.config.backend;
115
+ }
109
116
  setChatModelForBackend(chatId, backendId, model.trim() || undefined);
110
117
  broadcastChatUpdated(runtime, entry);
111
118
  }
@@ -14,21 +14,21 @@
14
14
  import { existsSync, readFileSync, mkdirSync } from "node:fs";
15
15
  import writeFileAtomic from "write-file-atomic";
16
16
  import { dirname } from "node:path";
17
- import type { TalonConfig } from "../../core/config/index.js";
18
- import { files as pathFiles } from "../../util/paths.js";
19
- import { setTimezone } from "../../util/time.js";
20
- import { resolveModel } from "../../core/models/catalog.js";
21
- import { getHealthStatus } from "../../util/watchdog.js";
22
- import { getActiveSessionCount } from "../../storage/sessions.js";
17
+ import type { TalonConfig } from "../../../core/config/index.js";
18
+ import { files as pathFiles } from "../../../util/paths.js";
19
+ import { setTimezone } from "../../../util/time.js";
20
+ import { resolveModel } from "../../../core/models/catalog.js";
21
+ import { getHealthStatus } from "../../../util/watchdog.js";
22
+ import { getActiveSessionCount } from "../../../storage/sessions.js";
23
23
  import {
24
24
  startPulseTimer,
25
25
  stopPulseTimer,
26
- } from "../../core/background/pulse.js";
26
+ } from "../../../core/background/pulse/pulse.js";
27
27
  import {
28
28
  startHeartbeatTimer,
29
29
  stopHeartbeatTimer,
30
- } from "../../core/background/heartbeat/index.js";
31
- import { log } from "../../util/log.js";
30
+ } from "../../../core/background/heartbeat/index.js";
31
+ import { log } from "../../../util/log.js";
32
32
 
33
33
  /** Config keys a client may change through the bridge. */
34
34
  export const EDITABLE = [
@@ -3,9 +3,9 @@
3
3
  * as a `status` event whenever something it reports changes.
4
4
  */
5
5
 
6
- import { resolveModel } from "../../core/models/catalog.js";
7
- import { BRIDGE_PROTOCOL_VERSION, type BridgeStatus } from "./protocol.js";
8
- import type { NativeRuntime } from "./runtime.js";
6
+ import { resolveModel } from "../../../core/models/catalog.js";
7
+ import { BRIDGE_PROTOCOL_VERSION, type BridgeStatus } from "../protocol.js";
8
+ import type { NativeRuntime } from "../runtime.js";
9
9
 
10
10
  export function bridgeStatus(runtime: NativeRuntime): BridgeStatus {
11
11
  const { config } = runtime;
@@ -8,10 +8,13 @@
8
8
  * fallback knows the turn already produced output).
9
9
  */
10
10
 
11
- import type { FrontendActionHandler, ActionResult } from "../../core/types.js";
12
- import type { Gateway } from "../../core/engine/gateway.js";
13
- import type { NativeChats, ChatEntry } from "./chats.js";
14
- import type { BridgeEvent, ClientButton } from "./protocol.js";
11
+ import type {
12
+ FrontendActionHandler,
13
+ ActionResult,
14
+ } from "../../../core/types.js";
15
+ import type { Gateway } from "../../../core/engine/gateway.js";
16
+ import type { NativeChats, ChatEntry } from "../chats/chats.js";
17
+ import type { BridgeEvent, ClientButton } from "../protocol.js";
15
18
 
16
19
  export type NativeActionDeps = {
17
20
  chats: NativeChats;
@@ -3,17 +3,17 @@
3
3
  * cache it on the runtime, and push changes to clients.
4
4
  */
5
5
 
6
- import { getSessionInfo } from "../../storage/sessions.js";
7
- import { buildContextDisplay } from "../shared/status-context.js";
8
- import { resolveActiveModelForChat } from "../../core/models/active-model.js";
6
+ import { getSessionInfo } from "../../../storage/sessions.js";
7
+ import { buildContextDisplay } from "../../presentation/status-context.js";
8
+ import { resolveActiveModelForChat } from "../../../core/models/active-model.js";
9
9
  import {
10
10
  getBackendForChat,
11
11
  getBackendIdForChat,
12
- } from "../../core/engine/backend-controller/index.js";
13
- import { broadcastChatUpdated } from "./chat-wire.js";
14
- import type { ChatEntry } from "./chats.js";
15
- import type { ContextInfo } from "./protocol.js";
16
- import type { NativeRuntime } from "./runtime.js";
12
+ } from "../../../core/engine/backend-controller/index.js";
13
+ import { broadcastChatUpdated } from "../chats/chat-wire.js";
14
+ import type { ChatEntry } from "../chats/chats.js";
15
+ import type { ContextInfo } from "../protocol.js";
16
+ import type { NativeRuntime } from "../runtime.js";
17
17
 
18
18
  type ContextOptions = { resolveModel?: boolean };
19
19
 
@@ -3,19 +3,19 @@
3
3
  * persist), touch the chat, and broadcast it to every client.
4
4
  */
5
5
 
6
- import { pushMessage } from "../../storage/history.js";
7
- import { extractSessionName } from "../../util/session-name.js";
8
- import { broadcastChatUpdated } from "./chat-wire.js";
9
- import { DEFAULT_CHAT_TITLE, type ChatEntry } from "./chats.js";
10
- import { mediaUrl, registerMedia } from "./media.js";
6
+ import { pushMessage } from "../../../storage/history.js";
7
+ import { extractSessionName } from "../../../core/weaver/session-name.js";
8
+ import { broadcastChatUpdated } from "../chats/chat-wire.js";
9
+ import { DEFAULT_CHAT_TITLE, type ChatEntry } from "../chats/chats.js";
10
+ import { mediaUrl, registerMedia } from "../media/media.js";
11
11
  import {
12
12
  BOT_SENDER_ID,
13
13
  USER_SENDER_ID,
14
14
  type ClientButton,
15
15
  type ClientAttachment,
16
16
  type ClientMessage,
17
- } from "./protocol.js";
18
- import type { NativeRuntime } from "./runtime.js";
17
+ } from "../protocol.js";
18
+ import type { NativeRuntime } from "../runtime.js";
19
19
 
20
20
  /**
21
21
  * Name a chat from its first user message — instantly and for free.
@@ -3,9 +3,9 @@
3
3
  * is running. Every mutation is synced to clients as a `chat_updated`.
4
4
  */
5
5
 
6
- import { broadcastChatUpdated } from "./chat-wire.js";
7
- import type { ChatEntry } from "./chats.js";
8
- import type { NativeRuntime, QueuedEntry } from "./runtime.js";
6
+ import { broadcastChatUpdated } from "../chats/chat-wire.js";
7
+ import type { ChatEntry } from "../chats/chats.js";
8
+ import type { NativeRuntime, QueuedEntry } from "../runtime.js";
9
9
 
10
10
  /**
11
11
  * Set (or replace) a chat's queued follow-up and sync it to every client via
@@ -13,8 +13,8 @@ import {
13
13
  recordTurnMeta as storeRecordTurnMeta,
14
14
  getTurnMeta as storeGetTurnMeta,
15
15
  clearTurnMeta as storeClearTurnMeta,
16
- } from "../../storage/turn-meta.js";
17
- import type { ClientToolCall } from "./protocol.js";
16
+ } from "../../../storage/turn-meta.js";
17
+ import type { ClientToolCall } from "../protocol.js";
18
18
 
19
19
  export type TurnMeta = {
20
20
  durationMs?: number;
@@ -6,19 +6,19 @@
6
6
  * backends) — mirroring the terminal renderer's delivery semantics.
7
7
  */
8
8
 
9
- import type { ExecuteResult } from "../../core/types.js";
10
- import type { AgentEvent } from "../../core/agent-runtime/events.js";
11
- import { execute } from "../../core/engine/dispatcher.js";
12
- import { toolInputToRecord } from "../../core/agent-runtime/events.js";
13
- import { getBackendForChat } from "../../core/engine/backend-controller/index.js";
14
- import { isDeliveryTool } from "../../core/tools/index.js";
9
+ import type { ExecuteResult } from "../../../core/types.js";
10
+ import type { AgentEvent } from "../../../core/agent-runtime/events.js";
11
+ import { execute } from "../../../core/engine/dispatcher.js";
12
+ import { toolInputToRecord } from "../../../core/agent-runtime/events.js";
13
+ import { getBackendForChat } from "../../../core/engine/backend-controller/index.js";
14
+ import { isDeliveryTool } from "../../../core/tools/index.js";
15
15
  import { recordTurnMeta } from "./turn-meta.js";
16
- import type { ChatEntry } from "./chats.js";
16
+ import type { ChatEntry } from "../chats/chats.js";
17
17
  import { refreshContext } from "./context.js";
18
18
  import { emitAssistant, emitUser } from "./emit.js";
19
- import type { BridgeEvent, ClientAttachment } from "./protocol.js";
19
+ import type { BridgeEvent, ClientAttachment } from "../protocol.js";
20
20
  import { takeQueued } from "./queue.js";
21
- import type { LiveToolEntry, NativeRuntime } from "./runtime.js";
21
+ import type { LiveToolEntry, NativeRuntime } from "../runtime.js";
22
22
  import { summarizeToolResult } from "./tool-result.js";
23
23
 
24
24
  /** The tool calls of one running turn, in call order. */
@@ -1,9 +1,10 @@
1
1
  /**
2
2
  * Frontend-agnostic display formatters shared by all chat frontends.
3
3
  *
4
- * These were previously duplicated per-frontend (telegram/helpers/format.ts,
5
- * discord/helpers.ts) and had started to drift — parseInterval accepted days
6
- * on Discord but not Telegram. One definition here keeps them in lockstep.
4
+ * These were previously duplicated per-frontend (the old
5
+ * telegram/helpers/format.ts, discord/helpers.ts) and had started to drift —
6
+ * parseInterval accepted days on Discord but not Telegram. One definition
7
+ * here keeps them in lockstep; frontends import this module directly.
7
8
  */
8
9
 
9
10
  import { resolveModel } from "../../core/models/catalog.js";
@@ -33,7 +33,7 @@ import {
33
33
  } from "../../core/engine/backend-controller/index.js";
34
34
  import { resetSession } from "../../storage/sessions.js";
35
35
  import { clearHistory } from "../../storage/history.js";
36
- import { resetPulseCheckpoint } from "../../core/background/pulse.js";
36
+ import { resetPulseCheckpoint } from "../../core/background/pulse/pulse.js";
37
37
  import { logWarn } from "../../util/log.js";
38
38
  import {
39
39
  displayReasoningEffort,
@@ -8,9 +8,21 @@ import type { TalonConfig } from "../../core/config/index.js";
8
8
  import {
9
9
  normalizeReasoningLevels,
10
10
  supportsReasoningLevel,
11
+ REASONING_LEVEL_DESCRIPTIONS,
11
12
  } from "../../core/models/reasoning-levels.js";
12
13
  export { supportsReasoningLevel };
13
14
 
15
+ /**
16
+ * Effort-level descriptions shown next to each option in a picker.
17
+ *
18
+ * One home for both frontends: Discord renders them as select-menu
19
+ * descriptions, and anything else offering the same choice reads the
20
+ * same table rather than copying it.
21
+ */
22
+ export const EFFORT_DESCRIPTIONS: Record<string, string> = {
23
+ ...REASONING_LEVEL_DESCRIPTIONS,
24
+ };
25
+
14
26
  export type ActiveReasoningLevels = {
15
27
  activeModel: string | null;
16
28
  modelInfo?: UnifiedModelInfo;