@dxos/plugin-assistant 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/PLUGIN.mdl +25 -0
  2. package/dist/lib/AssistantCapabilities.mjs +8 -1
  3. package/dist/lib/AssistantCapabilities.mjs.map +1 -1
  4. package/dist/lib/Settings.mjs +4 -0
  5. package/dist/lib/Settings.mjs.map +1 -1
  6. package/dist/lib/TurnReviewSkill.mjs +55 -0
  7. package/dist/lib/TurnReviewSkill.mjs.map +1 -0
  8. package/dist/lib/chunk-AgentArticle.mjs +1 -1
  9. package/dist/lib/chunk-AssistantSettings.mjs +1 -1
  10. package/dist/lib/chunk-AssistantSettings.mjs.map +1 -1
  11. package/dist/lib/chunk-Chat.mjs +322 -174
  12. package/dist/lib/chunk-Chat.mjs.map +1 -1
  13. package/dist/lib/chunk-ChatArticle.mjs +14 -7
  14. package/dist/lib/chunk-ChatArticle.mjs.map +1 -1
  15. package/dist/lib/chunk-ChatDialog.mjs +5 -4
  16. package/dist/lib/chunk-ChatDialog.mjs.map +1 -1
  17. package/dist/lib/chunk-IntegrationPrompt.mjs +1 -1
  18. package/dist/lib/chunk-PLUGIN.mjs +1 -1
  19. package/dist/lib/chunk-PluginUrlPrompt.mjs +1 -1
  20. package/dist/lib/chunk-QuestionSurface.mjs +1 -1
  21. package/dist/lib/chunk-SpaceHomePrompt.mjs +116 -60
  22. package/dist/lib/chunk-SpaceHomePrompt.mjs.map +1 -1
  23. package/dist/lib/chunk-TriggerStatus.mjs +1 -1
  24. package/dist/lib/chunk-agent-service.mjs +3 -1
  25. package/dist/lib/chunk-agent-service.mjs.map +1 -1
  26. package/dist/lib/chunk-analyze-turn.mjs +220 -0
  27. package/dist/lib/chunk-analyze-turn.mjs.map +1 -0
  28. package/dist/lib/{chunk-processor.mjs → chunk-chat-model.mjs} +95 -43
  29. package/dist/lib/chunk-chat-model.mjs.map +1 -0
  30. package/dist/lib/chunk-context.mjs.map +1 -1
  31. package/dist/lib/chunk-create-chat.mjs +5 -19
  32. package/dist/lib/chunk-create-chat.mjs.map +1 -1
  33. package/dist/lib/chunk-create-object.mjs +1 -1
  34. package/dist/lib/chunk-default-skills.mjs +28 -0
  35. package/dist/lib/chunk-default-skills.mjs.map +1 -0
  36. package/dist/lib/chunk-generate-home-suggestions.mjs +8 -6
  37. package/dist/lib/chunk-generate-home-suggestions.mjs.map +1 -1
  38. package/dist/lib/chunk-presets.mjs +1 -1
  39. package/dist/lib/chunk-presets.mjs.map +1 -1
  40. package/dist/lib/chunk-question-resumer.mjs +1 -1
  41. package/dist/lib/chunk-react-surface.mjs +1 -1
  42. package/dist/lib/chunk-run-prompt-in-chat.mjs +2 -1
  43. package/dist/lib/chunk-run-prompt-in-chat.mjs.map +1 -1
  44. package/dist/lib/chunk-run-prompt-in-new-chat.mjs +1 -1
  45. package/dist/lib/chunk-schema-defs.mjs +2 -2
  46. package/dist/lib/chunk-skill-definition.mjs +3 -2
  47. package/dist/lib/chunk-skill-definition.mjs.map +1 -1
  48. package/dist/lib/components.mjs +13 -13
  49. package/dist/lib/components.mjs.map +1 -1
  50. package/dist/lib/hooks.mjs +40 -31
  51. package/dist/lib/hooks.mjs.map +1 -1
  52. package/dist/lib/operations.mjs +3 -1
  53. package/dist/lib/operations.mjs.map +1 -1
  54. package/dist/lib/skills.mjs +2 -1
  55. package/dist/lib/translations.mjs +4 -2
  56. package/dist/lib/translations.mjs.map +1 -1
  57. package/dist/types/src/Chat.d.ts +1 -1
  58. package/dist/types/src/capabilities/agent-service.d.ts.map +1 -1
  59. package/dist/types/src/capabilities/skill-definition.d.ts.map +1 -1
  60. package/dist/types/src/{processor/processor.d.ts → chat-model/chat-model.d.ts} +24 -22
  61. package/dist/types/src/chat-model/chat-model.d.ts.map +1 -0
  62. package/dist/types/src/chat-model/chat-model.edge.test.d.ts +2 -0
  63. package/dist/types/src/chat-model/chat-model.edge.test.d.ts.map +1 -0
  64. package/dist/types/src/chat-model/chat-model.node.test.d.ts +2 -0
  65. package/dist/types/src/chat-model/chat-model.node.test.d.ts.map +1 -0
  66. package/dist/types/src/chat-model/chat-model.scripted.node.test.d.ts +2 -0
  67. package/dist/types/src/chat-model/chat-model.scripted.node.test.d.ts.map +1 -0
  68. package/dist/types/src/{processor → chat-model}/index.d.ts +1 -1
  69. package/dist/types/src/chat-model/index.d.ts.map +1 -0
  70. package/dist/types/src/chat-model/outbox.d.ts.map +1 -0
  71. package/dist/types/src/chat-model/outbox.test.d.ts.map +1 -0
  72. package/dist/types/src/chat-model/presets.d.ts.map +1 -0
  73. package/dist/types/src/chat-model/presets.test.d.ts.map +1 -0
  74. package/dist/types/src/{processor → chat-model}/prompt.d.ts +2 -2
  75. package/dist/types/src/chat-model/prompt.d.ts.map +1 -0
  76. package/dist/types/src/chat-model/prompt.test.d.ts.map +1 -0
  77. package/dist/types/src/chat-model/streaming.node.test.d.ts.map +1 -0
  78. package/dist/types/src/chat-model/testing/chat-model-recorder.d.ts +58 -0
  79. package/dist/types/src/chat-model/testing/chat-model-recorder.d.ts.map +1 -0
  80. package/dist/types/src/chat-model/testing/harness.d.ts +22 -0
  81. package/dist/types/src/chat-model/testing/harness.d.ts.map +1 -0
  82. package/dist/types/src/chat-model/thread.d.ts.map +1 -0
  83. package/dist/types/src/chat-model/thread.test.d.ts.map +1 -0
  84. package/dist/types/src/components/Chat/Chat.d.ts +6 -6
  85. package/dist/types/src/components/Chat/Chat.d.ts.map +1 -1
  86. package/dist/types/src/components/Chat/context.d.ts +5 -3
  87. package/dist/types/src/components/Chat/context.d.ts.map +1 -1
  88. package/dist/types/src/components/ChatPrompt/ChatActions.d.ts +1 -1
  89. package/dist/types/src/components/ChatPrompt/ChatActions.d.ts.map +1 -1
  90. package/dist/types/src/components/ChatPrompt/ChatMcpErrors.d.ts +3 -3
  91. package/dist/types/src/components/ChatPrompt/ChatMcpErrors.d.ts.map +1 -1
  92. package/dist/types/src/components/ChatPrompt/ChatOptions.d.ts +3 -1
  93. package/dist/types/src/components/ChatPrompt/ChatOptions.d.ts.map +1 -1
  94. package/dist/types/src/components/ChatPrompt/ChatOptions.stories.d.ts +4 -3
  95. package/dist/types/src/components/ChatPrompt/ChatOptions.stories.d.ts.map +1 -1
  96. package/dist/types/src/components/ChatPrompt/ChatPrompt.d.ts +15 -5
  97. package/dist/types/src/components/ChatPrompt/ChatPrompt.d.ts.map +1 -1
  98. package/dist/types/src/components/ChatPrompt/ChatPrompt.stories.d.ts +1 -1
  99. package/dist/types/src/components/ChatPrompt/ChatStatus.d.ts +1 -1
  100. package/dist/types/src/components/ChatPrompt/ChatStatus.d.ts.map +1 -1
  101. package/dist/types/src/components/ConnectorAuthMenu/ConnectorAuthMenu.stories.d.ts +9 -0
  102. package/dist/types/src/components/ConnectorAuthMenu/ConnectorAuthMenu.stories.d.ts.map +1 -1
  103. package/dist/types/src/components/Toolbox/Toolbox.d.ts +3 -3
  104. package/dist/types/src/components/Toolbox/Toolbox.d.ts.map +1 -1
  105. package/dist/types/src/containers/ChatArticle/ChatArticle.d.ts.map +1 -1
  106. package/dist/types/src/containers/ChatArticle/ChatArticle.stories.d.ts +1 -1
  107. package/dist/types/src/containers/SpaceHomePrompt/SpaceHomePrompt.d.ts.map +1 -1
  108. package/dist/types/src/hooks/index.d.ts +2 -2
  109. package/dist/types/src/hooks/index.d.ts.map +1 -1
  110. package/dist/types/src/hooks/{useChatProcessor.d.ts → useChatModel.d.ts} +6 -6
  111. package/dist/types/src/hooks/useChatModel.d.ts.map +1 -0
  112. package/dist/types/src/hooks/useDebug.d.ts +3 -3
  113. package/dist/types/src/hooks/useDebug.d.ts.map +1 -1
  114. package/dist/types/src/hooks/useHomeSuggestions.d.ts +3 -3
  115. package/dist/types/src/hooks/useHomeSuggestions.d.ts.map +1 -1
  116. package/dist/types/src/hooks/usePresets.d.ts +1 -1
  117. package/dist/types/src/hooks/usePresets.d.ts.map +1 -1
  118. package/dist/types/src/hooks/useSelectionContext.d.ts +3 -3
  119. package/dist/types/src/hooks/useSelectionContext.d.ts.map +1 -1
  120. package/dist/types/src/operations/analyze-turn.d.ts +5 -0
  121. package/dist/types/src/operations/analyze-turn.d.ts.map +1 -0
  122. package/dist/types/src/operations/analyze-turn.test.d.ts +2 -0
  123. package/dist/types/src/operations/analyze-turn.test.d.ts.map +1 -0
  124. package/dist/types/src/operations/create-chat.d.ts.map +1 -1
  125. package/dist/types/src/operations/generate-home-suggestions.d.ts.map +1 -1
  126. package/dist/types/src/operations/index.d.ts.map +1 -1
  127. package/dist/types/src/operations/run-prompt-in-chat.d.ts.map +1 -1
  128. package/dist/types/src/review/turn-review.d.ts +58 -0
  129. package/dist/types/src/review/turn-review.d.ts.map +1 -0
  130. package/dist/types/src/review/turn-review.test.d.ts +2 -0
  131. package/dist/types/src/review/turn-review.test.d.ts.map +1 -0
  132. package/dist/types/src/skills/index.d.ts +1 -0
  133. package/dist/types/src/skills/index.d.ts.map +1 -1
  134. package/dist/types/src/skills/turn-review/TurnReviewSkill.d.ts +21 -0
  135. package/dist/types/src/skills/turn-review/TurnReviewSkill.d.ts.map +1 -0
  136. package/dist/types/src/skills/turn-review/index.d.ts +2 -0
  137. package/dist/types/src/skills/turn-review/index.d.ts.map +1 -0
  138. package/dist/types/src/translations.d.ts.map +1 -1
  139. package/dist/types/src/types/Assistant.d.ts +1 -0
  140. package/dist/types/src/types/Assistant.d.ts.map +1 -1
  141. package/dist/types/src/types/AssistantCapabilities.d.ts +7 -1
  142. package/dist/types/src/types/AssistantCapabilities.d.ts.map +1 -1
  143. package/dist/types/src/types/Settings.d.ts +1 -0
  144. package/dist/types/src/types/Settings.d.ts.map +1 -1
  145. package/dist/types/src/util/agent-options.d.ts +27 -0
  146. package/dist/types/src/util/agent-options.d.ts.map +1 -0
  147. package/dist/types/src/util/agent-options.test.d.ts +2 -0
  148. package/dist/types/src/util/agent-options.test.d.ts.map +1 -0
  149. package/dist/types/src/util/default-skills.d.ts +10 -0
  150. package/dist/types/src/util/default-skills.d.ts.map +1 -0
  151. package/dist/types/tsconfig.tsbuildinfo +1 -1
  152. package/package.json +89 -80
  153. package/src/capabilities/agent-service.ts +2 -1
  154. package/src/capabilities/skill-definition.ts +2 -1
  155. package/src/chat-model/chat-model.edge.test.ts +301 -0
  156. package/src/{processor/processor.node.test.ts → chat-model/chat-model.node.test.ts} +19 -9
  157. package/src/chat-model/chat-model.scripted.node.test.ts +441 -0
  158. package/src/{processor/processor.ts → chat-model/chat-model.ts} +140 -45
  159. package/src/{processor → chat-model}/index.ts +1 -1
  160. package/src/{processor → chat-model}/prompt.ts +2 -2
  161. package/src/{processor → chat-model}/streaming.node.test.ts +108 -116
  162. package/src/chat-model/testing/chat-model-recorder.ts +249 -0
  163. package/src/chat-model/testing/harness.ts +81 -0
  164. package/src/{processor → chat-model}/thread.test.ts +1 -1
  165. package/src/components/Chat/Chat.tsx +44 -38
  166. package/src/components/Chat/Error.stories.tsx +1 -1
  167. package/src/components/Chat/context.ts +5 -3
  168. package/src/components/ChatPrompt/ChatActions.tsx +1 -1
  169. package/src/components/ChatPrompt/ChatMcpErrors.tsx +6 -6
  170. package/src/components/ChatPrompt/ChatOptions.stories.tsx +37 -3
  171. package/src/components/ChatPrompt/ChatOptions.tsx +118 -10
  172. package/src/components/ChatPrompt/ChatPrompt.stories.tsx +10 -10
  173. package/src/components/ChatPrompt/ChatPrompt.tsx +44 -27
  174. package/src/components/ChatPrompt/ChatStatus.tsx +8 -7
  175. package/src/components/Toolbox/Toolbox.tsx +12 -13
  176. package/src/containers/AssistantSettings/AssistantSettings.tsx +1 -1
  177. package/src/containers/ChatArticle/ChatArticle.stories.tsx +1 -1
  178. package/src/containers/ChatArticle/ChatArticle.tsx +16 -6
  179. package/src/containers/ChatDialog/ChatDialog.tsx +4 -4
  180. package/src/containers/SpaceHomePrompt/SpaceHomePrompt.tsx +110 -57
  181. package/src/hooks/index.ts +2 -2
  182. package/src/hooks/{useChatProcessor.ts → useChatModel.ts} +16 -14
  183. package/src/hooks/useDebug.ts +8 -8
  184. package/src/hooks/useHomeSuggestions.ts +14 -9
  185. package/src/hooks/usePresets.ts +2 -2
  186. package/src/hooks/useProcessEphemeralStatus.ts +1 -1
  187. package/src/hooks/useSelectionContext.ts +3 -5
  188. package/src/operations/analyze-turn.test.ts +194 -0
  189. package/src/operations/analyze-turn.ts +96 -0
  190. package/src/operations/create-chat.ts +4 -36
  191. package/src/operations/generate-home-suggestions.test.ts +1 -2
  192. package/src/operations/generate-home-suggestions.ts +17 -9
  193. package/src/operations/index.ts +2 -0
  194. package/src/operations/run-prompt-in-chat.ts +3 -2
  195. package/src/review/turn-review.test.ts +92 -0
  196. package/src/review/turn-review.ts +213 -0
  197. package/src/skills/index.ts +1 -0
  198. package/src/skills/turn-review/TurnReviewSkill.ts +46 -0
  199. package/src/skills/turn-review/index.ts +5 -0
  200. package/src/translations.ts +2 -0
  201. package/src/types/AssistantCapabilities.ts +8 -1
  202. package/src/types/Settings.ts +7 -0
  203. package/src/util/agent-options.test.ts +54 -0
  204. package/src/util/agent-options.ts +60 -0
  205. package/src/util/default-skills.ts +35 -0
  206. package/dist/lib/chunk-processor.mjs.map +0 -1
  207. package/dist/types/src/hooks/useChatProcessor.d.ts.map +0 -1
  208. package/dist/types/src/processor/index.d.ts.map +0 -1
  209. package/dist/types/src/processor/outbox.d.ts.map +0 -1
  210. package/dist/types/src/processor/outbox.test.d.ts.map +0 -1
  211. package/dist/types/src/processor/presets.d.ts.map +0 -1
  212. package/dist/types/src/processor/presets.test.d.ts.map +0 -1
  213. package/dist/types/src/processor/processor.d.ts.map +0 -1
  214. package/dist/types/src/processor/processor.node.test.d.ts +0 -2
  215. package/dist/types/src/processor/processor.node.test.d.ts.map +0 -1
  216. package/dist/types/src/processor/prompt.d.ts.map +0 -1
  217. package/dist/types/src/processor/prompt.test.d.ts.map +0 -1
  218. package/dist/types/src/processor/streaming.node.test.d.ts.map +0 -1
  219. package/dist/types/src/processor/thread.d.ts.map +0 -1
  220. package/dist/types/src/processor/thread.test.d.ts.map +0 -1
  221. /package/dist/types/src/{processor → chat-model}/outbox.d.ts +0 -0
  222. /package/dist/types/src/{processor → chat-model}/outbox.test.d.ts +0 -0
  223. /package/dist/types/src/{processor → chat-model}/presets.d.ts +0 -0
  224. /package/dist/types/src/{processor → chat-model}/presets.test.d.ts +0 -0
  225. /package/dist/types/src/{processor → chat-model}/prompt.test.d.ts +0 -0
  226. /package/dist/types/src/{processor → chat-model}/streaming.node.test.d.ts +0 -0
  227. /package/dist/types/src/{processor → chat-model}/thread.d.ts +0 -0
  228. /package/dist/types/src/{processor → chat-model}/thread.test.d.ts +0 -0
  229. /package/src/{processor → chat-model}/outbox.test.ts +0 -0
  230. /package/src/{processor → chat-model}/outbox.ts +0 -0
  231. /package/src/{processor → chat-model}/presets.test.ts +0 -0
  232. /package/src/{processor → chat-model}/presets.ts +0 -0
  233. /package/src/{processor → chat-model}/prompt.test.ts +0 -0
  234. /package/src/{processor → chat-model}/thread.ts +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.mjs","names":[],"sources":["../../src/hooks/useSkillRegistry.ts","../../src/hooks/useChatKeymap.ts","../../src/hooks/useChatProcessor.ts","../../src/hooks/useChatServices.ts","../../src/hooks/useChatToolbarActions.ts","../../src/hooks/useContextBinder.ts","../../src/hooks/useContextObjects.ts","../../src/hooks/useDebug.ts","../../src/hooks/useFilteredTypes.ts","../../src/hooks/useMcpServer.ts","../../src/hooks/usePlatform.ts","../../src/hooks/usePresets.ts","../../src/hooks/useReferencesProvider.ts","../../src/hooks/useSelectionContext.ts","../../src/hooks/useHomeSuggestions.ts","../../src/hooks/useProcessEphemeralStatus.ts","../../src/hooks/useSessionTimeline.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { type AiContext } from '@dxos/assistant';\nimport * as Skill from '@dxos/compute/Skill';\nimport { type Database, Filter, Obj, Ref, type Registry } from '@dxos/echo';\nimport { useQuery } from '@dxos/echo-react';\nimport { log } from '@dxos/log';\nimport { distinctBy } from '@dxos/util';\n\n/**\n * Stable identity for a skill in the picker.\n *\n * A registry skill is identified by its key, but a skill the user authored in a space has no\n * registry entry and so no key; falling back to its URI keeps such skills distinct from each other\n * (a shared `undefined` key collapses them into one row) and addressable by the toggle handler.\n */\nexport const getSkillId = (skill: Skill.Skill): string => Obj.getMeta(skill).key ?? Obj.getURI(skill) ?? skill.id;\n\nexport const useSkills = ({ registry, db }: { registry?: Registry.Registry; db?: Database.Database }) => {\n const [registrySkills, setRegistrySkills] = useState<Skill.Skill[]>(\n () => registry?.query(Filter.type(Skill.Skill)).runSync() ?? [],\n );\n\n useEffect(() => {\n if (!registry) {\n setRegistrySkills([]);\n return;\n }\n setRegistrySkills(registry.query(Filter.type(Skill.Skill)).runSync());\n return registry.changed.on(() => {\n setRegistrySkills(registry.query(Filter.type(Skill.Skill)).runSync());\n });\n }, [registry]);\n\n const spaceSkills = useQuery(db, Filter.type(Skill.Skill));\n return useMemo(() => {\n // Space copies first, so a fork shadows the registry entry it was cloned from rather than the\n // other way round — it carries the user's edits (same precedence as `Skill.resolveAnnotatedSkills`).\n const skills = distinctBy([...spaceSkills, ...registrySkills], getSkillId);\n skills.sort(({ name: a }, { name: b }) => a.localeCompare(b));\n return skills;\n }, [registrySkills, spaceSkills]);\n};\n\n/**\n * Create reactive map of active skills (by skill id).\n */\nexport const useActiveSkills = ({ context }: { context?: AiContext.Binder }) => {\n const [active, setActive] = useState<Map<string, Skill.Skill>>(new Map());\n\n useEffect(() => {\n if (!context) {\n setActive(new Map());\n return;\n }\n\n const updateActive = () => {\n setActive(new Map(context.getSkills().map((skill) => [getSkillId(skill), skill] as const)));\n };\n\n // Set initial value.\n updateActive();\n\n // Subscribe to changes.\n return context.subscribeSkills(updateActive);\n }, [context]);\n\n return active;\n};\n\n// TODO(burdon): Move logic into binder.\nexport const useSkillHandlers = ({ context }: { context?: AiContext.Binder }) => {\n const onUpdateSkill = useCallback(\n async (skill: Skill.Skill, checked: boolean) => {\n if (!context) {\n return;\n }\n\n // A registry skill binds by its key URI, which resolves through the hypergraph registry — no\n // DB clone needed. Anything else is a space object (including a fork of a registry skill) and\n // binds by its own ref, so the user's edits are what the conversation sees.\n const key = Obj.getMeta(skill).key;\n const registryRef = key !== undefined ? Ref.fromURI(Skill.registryURI(key)) : undefined;\n const ref = Obj.getDatabase(skill) === undefined && registryRef ? registryRef : Ref.make(skill);\n\n log('update skill', { skill: getSkillId(skill), uri: ref.uri, checked });\n if (checked) {\n await context.bind({ skills: [ref] });\n } else {\n // Both forms: a fork and the registry entry it shadows share one row, and the toggle has to\n // clear the conversation whichever of the two was bound (e.g. by the chat's own context).\n const refs = registryRef && registryRef.uri !== ref.uri ? [ref, registryRef] : [ref];\n await context.unbind({ skills: refs });\n }\n },\n [context],\n );\n\n return { onUpdateSkill };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Extension, Prec } from '@codemirror/state';\nimport { keymap } from '@codemirror/view';\nimport { useMemo } from 'react';\n\nimport { type Event } from '@dxos/async';\nimport { isTruthy } from '@dxos/util';\n\nimport { type ChatEvent } from '../components/Chat/events.ts';\n\n/**\n * CodeMirror keymap shared by the chat document (Thread) and the prompt editor — pressing\n * Mod-Arrow keys when either editor is focused emits the corresponding `ChatEvent` on the\n * shared event bus.\n */\nexport const useChatKeymapExtensions = ({ event }: { event: Event<ChatEvent> }): Extension[] => {\n return useMemo<Extension[]>(() => {\n return [\n Prec.highest(\n keymap.of([\n {\n key: 'Mod-ArrowUp',\n preventDefault: true,\n run: () => {\n event.emit({ type: 'nav-previous' });\n return true;\n },\n shift: () => {\n event.emit({ type: 'thread-open' });\n return true;\n },\n },\n {\n key: 'Mod-ArrowDown',\n preventDefault: true,\n run: () => {\n event.emit({ type: 'nav-next' });\n return true;\n },\n shift: () => {\n event.emit({ type: 'thread-close' });\n return true;\n },\n },\n ]),\n ),\n ].filter(isTruthy);\n }, [event]);\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { RegistryContext } from '@effect/atom-react/RegistryContext';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport { useContext, useEffect, useMemo, useState } from 'react';\n\nimport { AiService, OpaqueToolkit } from '@dxos/ai';\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport { AiSession } from '@dxos/assistant';\nimport type * as Chat from '@dxos/assistant/Chat';\nimport * as AgentService from '@dxos/compute/AgentService';\nimport * as Credential from '@dxos/compute/Credential';\nimport * as ServiceResolver from '@dxos/compute/ServiceResolver';\nimport { Database, Obj, Ref, Registry } from '@dxos/echo';\nimport { useObject } from '@dxos/echo-react';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { log } from '@dxos/log';\nimport * as UiHooks from '@dxos/react-ui/Hooks';\n\nimport { Assistant } from '#types';\n\nimport { AiChatProcessor, type AiServicePreset } from '../processor/index.ts';\n\nexport type UseChatProcessorProps = {\n db?: Database.Database;\n chat?: Chat.Chat;\n preset?: AiServicePreset;\n runtime?: Capabilities.ProcessManagerRuntime;\n registry?: Registry.Registry;\n settings?: Assistant.Settings;\n /** Attributes the prompts submitted through this processor to a person (see `AiChatProcessorOptions.sender`). */\n sender?: AgentService.PromptSender;\n};\n\n/**\n * Configure and create AiChatProcessor.\n */\nexport const useChatProcessor = ({\n db,\n chat,\n preset,\n runtime,\n registry,\n settings,\n sender,\n}: UseChatProcessorProps): AiChatProcessor | undefined => {\n const observableRegistry = useContext(RegistryContext);\n\n // Reactive subscription — re-renders when the feed ref resolves. Direct `.target` reads are not reactive.\n const [feedSnapshot] = useObject(chat?.feed);\n const feed = Obj.getReactiveOrUndefined(feedSnapshot);\n\n const [session, setSession] = useState<AiSession.Session>();\n UiHooks.useAsyncEffect(async () => {\n if (!db || !chat || !feed) {\n return;\n }\n\n const runtime = await EffectEx.runAndForwardErrors(\n Effect.context<Database.Service>().pipe(Effect.provide(Database.layer(db))),\n );\n const session = new AiSession.Session({\n feed,\n runtime,\n registry: observableRegistry,\n });\n const openedAt = performance.now();\n await session.open();\n log('session opened', { chat: chat.id, duration: Math.round(performance.now() - openedAt) });\n setSession(session);\n return () => {\n void session.close();\n setSession(undefined);\n };\n }, [db, chat, feed]);\n\n const serviceResolver = Hooks.useCapability(Capabilities.ServiceResolver);\n // Primitives rather than the object, so an inline `sender` literal does not rebuild the processor each render.\n const senderName = sender?.name;\n const senderDid = sender?.identityDid;\n\n const processor = useMemo(() => {\n if (!runtime || !session || !chat || !feed || !db) {\n return undefined;\n }\n\n const spaceLayer = ServiceResolver.provide(\n { space: db.spaceId },\n Database.Service,\n Credential.CredentialsService,\n AiService.AiService,\n AgentService.AgentService,\n Registry.Service,\n OpaqueToolkit.OpaqueToolkitProvider,\n ).pipe(Layer.provide(Layer.succeed(ServiceResolver.ServiceResolver, serviceResolver)));\n\n log('creating processor', { preset, model: preset?.model, settings });\n return new AiChatProcessor(session, runtime, feed, spaceLayer, {\n chat: chat ? Ref.make(chat) : undefined,\n observableRegistry,\n registry,\n model: preset?.model,\n provider: preset?.provider,\n // Absent keys rather than `undefined` values: the sender crosses the process input schema.\n sender:\n senderName || senderDid\n ? { ...(senderName ? { name: senderName } : {}), ...(senderDid ? { identityDid: senderDid } : {}) }\n : undefined,\n });\n }, [runtime, session, registry, preset, chat, feed, db?.spaceId, senderName, senderDid]);\n\n // A remount (e.g. the user navigated to another page mid-turn) gets a fresh processor whose\n // active/streaming state starts empty, while the agent process for the feed keeps running;\n // adopting it restores the running indicator and the streamed blocks.\n useEffect(() => processor?.adopt(), [processor]);\n\n return processor;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport * as AppSpace from '@dxos/app-toolkit/AppSpace';\nimport { type Key } from '@dxos/echo';\nimport { useClient } from '@dxos/react-client';\n\nimport { AssistantEvents } from '#types';\n\nexport type UseChatServicesProps = {\n id?: Key.SpaceId;\n};\n\n/**\n * Resolves the shared {@link Capabilities.ProcessManagerRuntime} for the given space.\n *\n * The runtime itself is space-agnostic; the returned value can be used to run\n * effects that pipe through {@link ServiceResolver.provide} (or the\n * `useSpaceCallback`/`useSpaceService` hooks) with the resolved {@link Key.SpaceId}.\n */\nexport const useChatServices = ({ id }: UseChatServicesProps) => {\n const client = useClient();\n id ??= AppSpace.getDefaultSpace(client)?.id;\n\n // Every chat entry point resolves its services here, so this is the assistant-in-use demand\n // signal: start-gated assistant modules (skills included) load now and register via the\n // reactive RegistrySync.\n Hooks.useActivationSignal(AssistantEvents.Start);\n const runtime = Hooks.useCapability(Capabilities.ProcessManagerRuntime);\n return id ? runtime : undefined;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport * as Chat from '@dxos/assistant/Chat';\nimport { Filter, Obj, Query, Type } from '@dxos/echo';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { invariant } from '@dxos/invariant';\nimport { MenuBuilder, useMenuBuilder } from '@dxos/react-ui-menu';\n\nimport { meta } from '#meta';\nimport { AssistantOperation } from '#types';\n\nimport { useChatContext } from '../components/Chat/context.ts';\n\n/**\n * Scopes the toolbar's chat switcher: which chats it lists, and what picking one does.\n *\n * Without it the switcher shows the companion chats of `companionTo` and switches the companion,\n * which is what the app wants nearly everywhere. A caller that owns its own chat selection (a\n * story showing every chat in a space, a panel scoped to a project) passes its own.\n */\nexport type ChatSwitcher = {\n chats: Chat.Chat[];\n onSelect: (chat: Chat.Chat) => void;\n};\n\nexport type ChatToolbarActionsProps = {\n chat?: Chat.Chat;\n companionTo?: Obj.Unknown;\n switcher?: ChatSwitcher;\n};\n\nexport const useChatToolbarActions = ({ chat, companionTo, switcher }: ChatToolbarActionsProps) => {\n const { invoke } = Hooks.useOperationInvoker();\n const { db } = useChatContext('useChatToolbarActions');\n\n // Stable references in deps avoid circular reference issues.\n return useMenuBuilder(\n (get) => {\n const chats =\n switcher?.chats ??\n (companionTo && db\n ? get(db.query(Query.select(Filter.id(companionTo.id)).children()).atom).filter(Obj.instanceOf(Chat.Chat))\n : []);\n\n const builder = MenuBuilder.make().root({\n label: ['chat-toolbar.title', { ns: meta.profile.key }],\n });\n\n if (companionTo) {\n builder.action(\n 'new',\n {\n label: ['new-thread.button', { ns: meta.profile.key }],\n icon: 'ph--plus--regular',\n type: 'new',\n },\n () => {\n invariant(companionTo);\n return invoke(AssistantOperation.SetCurrentChat, {\n companionTo,\n chat: undefined,\n }).pipe(EffectEx.runAndForwardErrors);\n },\n );\n }\n\n builder\n .action(\n 'branch',\n {\n label: ['branch-thread.menu', { ns: meta.profile.key }],\n icon: 'ph--git-branch--regular',\n type: 'branch',\n disabled: !chat || !db,\n },\n () =>\n Effect.gen(function* () {\n invariant(chat);\n yield* invoke(AssistantOperation.ForkChat, { chat, companionTo }, { spaceId: db?.spaceId });\n }).pipe(EffectEx.runAndForwardErrors),\n )\n .action(\n 'rename',\n {\n label: ['rename-thread.button', { ns: meta.profile.key }],\n icon: 'ph--magic-wand--regular',\n type: 'rename',\n disabled: !chat,\n },\n () =>\n Effect.gen(function* () {\n invariant(chat);\n yield* invoke(AssistantOperation.UpdateChatName, { chat }, { spaceId: db?.spaceId });\n }).pipe(EffectEx.runAndForwardErrors),\n );\n\n if (chats.length > 0) {\n builder.separator().group(\n 'chats',\n {\n label: ['chat-history.label', { ns: meta.profile.key }],\n icon: 'ph--clock-counter-clockwise--regular',\n selectCardinality: 'single',\n variant: 'dropdownMenu',\n },\n (builder) => {\n chats\n // TODO(wittjosiah): This should be the default sort order.\n .toSorted((a, b) => a.id.localeCompare(b.id))\n .forEach((chat) => {\n get(Obj.atomProperty(chat, 'name'));\n\n builder.action(\n chat.id,\n {\n label: Obj.getLabel(chat) ?? ['object-name.placeholder', { ns: Type.getTypename(Chat.Chat) }],\n },\n () => {\n if (switcher) {\n switcher.onSelect(chat);\n return;\n }\n return Effect.gen(function* () {\n invariant(companionTo);\n yield* invoke(AssistantOperation.SetCurrentChat, {\n companionTo,\n chat,\n });\n }).pipe(EffectEx.runAndForwardErrors);\n },\n );\n });\n },\n );\n }\n\n return builder.build();\n },\n [db?.spaceId, companionTo?.id, chat?.id, invoke, switcher?.chats.map(({ id }) => id).join(), switcher?.onSelect],\n );\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { RegistryContext } from '@effect/atom-react/RegistryContext';\nimport * as Effect from 'effect/Effect';\nimport type * as Registry from 'effect/reactivity/AtomRegistry';\nimport { useContext, useState } from 'react';\n\nimport { AiContext } from '@dxos/assistant';\nimport { Database, Feed } from '@dxos/echo';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { type Space } from '@dxos/react-client/echo';\nimport * as Hooks from '@dxos/react-ui/Hooks';\n\nexport const useContextBinder = (\n space: Space | undefined,\n feed: Feed.Feed | undefined,\n): AiContext.Binder | undefined => {\n const registry = useContext(RegistryContext) as Registry.AtomRegistry;\n const [binder, setBinder] = useState<AiContext.Binder>();\n\n Hooks.useAsyncEffect(async () => {\n setBinder(undefined);\n if (!space || !feed) {\n return;\n }\n\n const runtime = await EffectEx.runAndForwardErrors(\n Effect.context<Database.Service>().pipe(Effect.provide(Database.layer(space.db))),\n );\n const binder = new AiContext.Binder({ feed, runtime, registry });\n await binder.open();\n setBinder(binder);\n\n return () => {\n void binder.close();\n };\n }, [space, feed]);\n\n return binder;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { useAtomValue } from '@effect/atom-react/Hooks';\nimport * as Atom from 'effect/reactivity/Atom';\nimport { useCallback, useMemo } from 'react';\n\nimport { type AiContext } from '@dxos/assistant';\nimport * as Chat from '@dxos/assistant/Chat';\nimport { type Database, Obj } from '@dxos/echo';\nimport { type URI } from '@dxos/keys';\n\nexport type UseContextObjectsProps = {\n db?: Database.Database;\n context?: AiContext.Binder;\n};\n\nexport type UseContextObjects = {\n objects: Obj.Unknown[];\n onUpdateObject: (dxn: URI.URI, checked: boolean) => Promise<void>;\n};\n\nconst emptyObjectsAtom = Atom.make<Obj.Unknown[]>([]);\n\n/**\n * Create reactive map of active object references (by DXN string).\n */\nexport const useContextObjects = ({ db, context }: UseContextObjectsProps): UseContextObjects => {\n const boundObjects = useAtomValue(context?.objects ?? emptyObjectsAtom);\n // The session's own chat is bound into its context so the agent harness can resolve it\n // (`get-context` requires a bound chat to read the plan when no agent is present); it is not a\n // user-added reference, so exclude it from the UI. Mirrors the `!Obj.instanceOf(Chat.Chat, …)`\n // filter applied when copying context objects in `assistant-toolkit` `Agent`.\n const objects = useMemo(() => boundObjects.filter((object) => !Obj.instanceOf(Chat.Chat, object)), [boundObjects]);\n\n const handleUpdateObject = useCallback<UseContextObjects['onUpdateObject']>(\n async (dxn: URI.URI, checked: boolean) => {\n if (!db || !context) {\n return;\n }\n\n const ref = db.makeRef<Obj.Unknown>(dxn);\n await ref.load();\n if (checked) {\n await context.bind({ objects: [ref] });\n } else {\n await context.unbind({ objects: [ref] });\n }\n },\n [db, context],\n );\n\n return {\n objects,\n onUpdateObject: handleUpdateObject,\n };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { useCallback } from 'react';\n\nimport { trim } from '@dxos/util';\n\nimport { type AiChatProcessor } from '../processor/index.ts';\n\n/**\n * Returns an async callback that logs the chat's current context, system prompt,\n * and resolved tools to the browser console under a collapsible group.\n * Used by the chat's debug-toggle event handler.\n */\nexport const useDebug = ({ processor }: { processor?: AiChatProcessor }) => {\n return useCallback(async () => {\n if (!processor) {\n return;\n }\n\n const objects = processor.context.getObjects();\n const skills = processor.context.getSkills();\n const system = await processor.getSystemPrompt();\n const tools = (await processor.getTools()) ?? {};\n console.group('Chat', { objects, skills });\n try {\n console.log(trim`\n System Prompt:\n ${system}\n `);\n console.log(trim`\n Tools:\n ${Object.values(tools)\n .map((tool) => JSON.stringify(tool, null, 2))\n .join('\\n')}\n `);\n } finally {\n console.groupEnd();\n }\n }, [processor]);\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { useEffect, useState } from 'react';\n\nimport * as TypeOptions from '@dxos/app-toolkit/TypeOptions';\nimport { type Database, Type } from '@dxos/echo';\n\nconst getFilteredTypes = (db: Database.Database): Type.AnyEntity[] =>\n Array.from(\n new Set(\n db.graph.registry\n .list()\n .filter(Type.isType)\n .filter((schema) => TypeOptions.isUserType(schema)),\n ),\n );\n\n// TODO(burdon): Pass in filter.\n// TODO(wittjosiah): Factor out.\nexport const useFilteredTypes = (db?: Database.Database): Type.AnyEntity[] => {\n const [types, setTypes] = useState<Type.AnyEntity[]>([]);\n useEffect(() => {\n if (!db) {\n return;\n }\n\n setTypes(getFilteredTypes(db));\n return db.graph.registry.changed.on(() => {\n setTypes(getFilteredTypes(db));\n });\n }, [db]);\n\n return types;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Deferred from 'effect/Deferred';\nimport * as Duration from 'effect/Duration';\nimport * as Effect from 'effect/Effect';\nimport * as Schema from 'effect/Schema';\nimport { useCallback, useEffect, useState } from 'react';\n\nimport * as McpServer from '@dxos/compute/McpServer';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { log } from '@dxos/log';\nimport { McpOAuth, McpToolkit } from '@dxos/mcp-client';\n\nexport type McpServerStatus =\n | { state: 'disabled' }\n | { state: 'checking' }\n | { state: 'connected'; tools: string[] }\n | { state: 'unauthorized'; message: string }\n | { state: 'error'; message: string };\n\n/** Served by composer-app from `public/`; relays the authorization response on {@link OAUTH_CHANNEL}. */\nconst OAUTH_CALLBACK_PATH = '/mcp-oauth-callback.html';\nconst OAUTH_CHANNEL = 'dxos.mcp-oauth';\nconst SIGN_IN_TIMEOUT = Duration.minutes(5);\n\ntype CallbackResult = { code?: string; state?: string; error?: string };\n\n/** The interactive part of an MCP sign-in failed; `message` is shown on the server's row. */\nclass McpSignInError extends Schema.TaggedError<McpSignInError>('McpSignInError')('McpSignInError', {\n message: Schema.String,\n}) {}\n\n/**\n * The server's connection options as this browser can build them: the same credentials the agent\n * resolves each turn, minus EDGE-custodied tokens, which the UI cannot read.\n */\nconst toOptions = async (server: McpServer.McpServer): Promise<McpToolkit.Options> => {\n const options: McpToolkit.Options = { url: server.url, protocol: server.protocol, apiKey: server.apiKey };\n if (server.oauth?.tokens) {\n return { ...options, authProvider: McpOAuth.makeProvider({ store: McpServer.oauthStore(server) }) };\n }\n const accessToken = await server.accessToken?.tryLoad();\n return accessToken ? { ...options, apiKey: accessToken.token } : options;\n};\n\n/**\n * Checks that the server answers with the configured credentials. `revision` re-runs the check, e.g.\n * after signing in.\n */\nexport const useMcpServerStatus = (\n server: McpServer.McpServer,\n { enabled, revision }: { enabled: boolean; revision: number },\n): McpServerStatus => {\n const [status, setStatus] = useState<McpServerStatus>({ state: enabled ? 'checking' : 'disabled' });\n const url = server.url;\n const signedIn = server.oauth?.tokens !== undefined;\n\n useEffect(() => {\n if (!enabled) {\n setStatus({ state: 'disabled' });\n return;\n }\n\n let cancelled = false;\n setStatus({ state: 'checking' });\n void Effect.tryPromise({\n try: () => toOptions(server),\n catch: (cause) =>\n new McpToolkit.McpConnectionError({\n url: server.url,\n protocol: server.protocol,\n message: `Failed to load the server's credentials: ${McpToolkit.formatCause(cause)}`,\n }),\n })\n .pipe(\n Effect.flatMap(McpToolkit.probe),\n Effect.match({\n onSuccess: ({ tools }): McpServerStatus => ({ state: 'connected', tools }),\n onFailure: (error): McpServerStatus =>\n error.unauthorized\n ? { state: 'unauthorized', message: error.message }\n : { state: 'error', message: error.message },\n }),\n EffectEx.runAndForwardErrors,\n )\n .then((next) => {\n if (!cancelled) {\n setStatus(next);\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [server, url, enabled, signedIn, revision]);\n\n return status;\n};\n\n/**\n * Signs in to a server that uses MCP authorization (OAuth 2.1): discovers its authorization server,\n * registers Composer as a client, and runs the PKCE code flow in a popup. The tokens land on the\n * server object, where every agent in the space picks them up.\n */\nexport const useMcpServerSignIn = (server: McpServer.McpServer) => {\n const [pending, setPending] = useState(false);\n const [error, setError] = useState<string>();\n\n const signIn = useCallback(async () => {\n // Opened synchronously in the click handler: discovery and registration are awaited before the\n // authorization URL is known, and a popup opened after an await is blocked.\n const popup = window.open('about:blank', 'dxos-mcp-oauth', 'popup,width=520,height=720');\n setPending(true);\n setError(undefined);\n try {\n await EffectEx.runAndForwardErrors(authorize(server, popup));\n } catch (err) {\n log.warn('MCP sign-in failed', { url: server.url, error: err });\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n popup?.close();\n setPending(false);\n }\n }, [server]);\n\n return { signIn, pending, error };\n};\n\nconst authorize = (server: McpServer.McpServer, popup: Window | null) =>\n Effect.gen(function* () {\n if (!popup) {\n return yield* Effect.fail(new McpSignInError({ message: 'The sign-in window was blocked.' }));\n }\n\n const provider = McpOAuth.makeProvider({\n store: McpServer.oauthStore(server),\n redirectUrl: new URL(OAUTH_CALLBACK_PATH, window.location.origin).href,\n onAuthorize: (authorizationUrl) => {\n popup.location.href = authorizationUrl.href;\n },\n });\n\n // Every sign-in in this origin hears every callback; only the one whose `state` it echoes is ours.\n const callback = yield* Deferred.make<CallbackResult>();\n const channel = new BroadcastChannel(OAUTH_CHANNEL);\n channel.onmessage = (event: MessageEvent<CallbackResult>) => {\n if (event.data.state !== undefined && event.data.state === provider.pendingState) {\n Deferred.doneUnsafe(callback, Effect.succeed(event.data));\n }\n };\n yield* Effect.addFinalizer(() => Effect.sync(() => channel.close()));\n\n const result = yield* McpOAuth.authorize(provider, server.url);\n if (result === 'AUTHORIZED') {\n // Stored tokens were still good, or were refreshed without the user.\n return;\n }\n\n const { code, error } = yield* Deferred.await(callback).pipe(\n Effect.timeoutOrElse({\n duration: SIGN_IN_TIMEOUT,\n orElse: () => Effect.fail(new McpSignInError({ message: 'Timed out waiting for sign-in.' })),\n }),\n );\n if (error || !code) {\n return yield* Effect.fail(new McpSignInError({ message: error ?? 'The authorization server returned no code.' }));\n }\n\n yield* McpOAuth.completeAuthorization(provider, server.url, code);\n }).pipe(Effect.scoped);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport * as DeckCapabilities from '@dxos/plugin-deck/DeckCapabilities';\n\n/**\n * Which shell the chat surfaces are rendering into.\n *\n * Platform, not viewport: the affordances keyed to it (the online indicator, the thread's marker rail\n * and status pill) are dropped because the mobile app has no room and no pointer for them, not\n * because a window happens to be narrow — a narrowed desktop window keeps them all.\n *\n * The capability is optional so a harness that loads no deck plugin (storybook, tests) still renders,\n * taking the desktop treatment.\n *\n * Reads `DeckCapabilities.Platform` rather than `useLayout()` because `Layout.mode` is an open string\n * contract for whatever a layout plugin reports, while `Platform` is the typed, boot-fixed source this\n * hook actually needs.\n */\nexport const usePlatform = (): DeckCapabilities.Platform =>\n Hooks.useOptionalCapability(DeckCapabilities.Platform) ?? 'desktop';\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { useAtomValue } from '@effect/atom-react/Hooks';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { Model, Provider } from '@dxos/ai';\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport type * as Chat from '@dxos/assistant/Chat';\nimport { Obj } from '@dxos/echo';\nimport { useObject } from '@dxos/echo-react';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { DXN } from '@dxos/keys';\nimport * as UiHooks from '@dxos/react-ui/Hooks';\n\nimport { meta } from '#meta';\nimport { Assistant, AssistantCapabilities, AssistantPreset, Ollama } from '#types';\n\nimport {\n type AiServicePreset,\n defaultsKeyForProvider,\n pickPreset,\n presetsForProvider,\n providerForModel,\n resolveProvider,\n} from '../processor/index.ts';\n\nexport type UsePresets = {\n preset: AiServicePreset | undefined;\n} & Pick<AssistantPreset.ChatPresetProps, 'presets' | 'onPresetChange'>;\n\n/**\n * Resolves the chat model presets for the provider selected in settings ({@link Assistant.Settings.modelProvider}).\n * The selection is the chat's own (`Chat.session.model`), written back to it when the user picks; a chat that\n * has not selected one shows the configured per-provider model.\n */\nexport const usePresets = (settings: Assistant.Settings, chat?: Chat.Chat): UsePresets => {\n const { t } = UiHooks.useTranslation(meta.profile.key);\n // Subscribed rather than read: the picker has to follow a selection made on another mount of the\n // same chat, and the stamp the processor writes before the first request.\n const [session] = useObject(chat, 'session');\n const chatModel = session?.model;\n\n // The Ollama manager is the bundled sidecar (desktop only); its presence signals that the\n // `built-in` provider (rather than an external Ollama server) is available.\n const ollamaManager = Hooks.useOptionalCapability(AssistantCapabilities.OllamaManager);\n\n const provider = resolveProvider(settings.modelProvider, !!ollamaManager);\n const defaultModel = settings.modelDefaults?.[defaultsKeyForProvider(provider)];\n\n // Installed models reported by the bundled sidecar; used to offer only models actually present.\n const localModels = useAtomValue(ollamaManager?.state ?? Ollama.emptyState);\n\n // When the bundled sidecar is the active provider, list installed models in the background so the\n // chat selector is populated without first opening settings. Idempotent: kicks off only from the\n // idle state, so it spawns the sidecar once when local models are in use (not on every launch);\n // settings remains the explicit path for retrying after a failure.\n useEffect(() => {\n if (provider === Provider.builtIn.id && ollamaManager && localModels.kind === 'idle') {\n void EffectEx.runPromise(ollamaManager.refresh);\n }\n }, [provider, ollamaManager, localModels.kind]);\n\n // Probe the external LM Studio server only when that provider is selected on desktop.\n const lmStudioProbeUrl =\n provider === Provider.lmStudio.id && ollamaManager ? `${Provider.lmStudio.endpoint}/v1/models` : undefined;\n const lmStudioReachable = useEndpointReachable(lmStudioProbeUrl);\n\n const presets = useMemo(() => {\n const base = presetsForProvider(provider);\n // Desktop LM Studio: only offer presets when the external server responds.\n if (provider === Provider.lmStudio.id && ollamaManager) {\n return lmStudioReachable ? base : [];\n }\n // Bundled sidecar: only offer models that are actually installed (matched by back-end pull tag).\n if (provider === Provider.builtIn.id && ollamaManager) {\n const installed = new Set(localModels.models.map((model) => model.name));\n return base.filter((preset) => installed.has(preset.backend));\n }\n return base;\n }, [provider, ollamaManager, lmStudioReachable, localModels]);\n\n // The chat's selection when the active provider serves it, else the provider's configured model.\n // A selection the provider does not serve (the chat picked Claude, then the user went offline) is\n // still what the process will run, so it is shown as an unavailable entry rather than silently\n // displayed as the fallback — the picker and the request must agree.\n const unavailable = useMemo<AiServicePreset | undefined>(() => {\n if (!chatModel || presets.length === 0 || presets.some((preset) => preset.model === chatModel)) {\n return undefined;\n }\n // Carries the provider that actually serves the model rather than the active one, which by\n // definition does not — a resolver chain that still reaches it then can.\n const catalog = Model.byId(chatModel)[0];\n return {\n id: chatModel,\n provider: providerForModel(chatModel, provider) ?? provider,\n model: chatModel,\n backend: catalog?.backend ?? '',\n label: t('model-unavailable.label', { label: catalog?.label ?? DXN.getName(chatModel) }),\n };\n }, [chatModel, presets, provider, t]);\n\n const preset = useMemo(\n () => presets.find((preset) => preset.model === chatModel) ?? unavailable ?? pickPreset(presets, defaultModel),\n [presets, chatModel, unavailable, defaultModel],\n );\n\n const presetOptions = useMemo(\n () =>\n [...presets, ...(unavailable ? [unavailable] : [])].map(({ id, model, label }) => ({\n id,\n label: label ?? model,\n })),\n [presets, unavailable],\n );\n\n const handlePresetChange = useCallback<NonNullable<AssistantPreset.ChatPresetProps['onPresetChange']>>(\n (id) => {\n const preset = presets.find((preset) => preset.id === id);\n if (preset && chat) {\n Obj.update(chat, (chat) => {\n chat.session = { ...chat.session, model: preset.model };\n });\n }\n },\n [presets, chat],\n );\n\n return {\n preset,\n presets: presetOptions,\n onPresetChange: handlePresetChange,\n };\n};\n\n/** Reactively reports whether an HTTP endpoint responds; `undefined` url disables the probe. */\nconst useEndpointReachable = (url: string | undefined): boolean => {\n const [reachable, setReachable] = useState(false);\n useEffect(() => {\n if (!url) {\n setReachable(false);\n return;\n }\n let active = true;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 1500);\n fetch(url, { signal: controller.signal })\n .then((response) => active && setReachable(response.ok))\n .catch(() => active && setReachable(false))\n .finally(() => clearTimeout(timer));\n return () => {\n active = false;\n controller.abort();\n clearTimeout(timer);\n };\n }, [url]);\n return reachable;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { useMemo } from 'react';\n\nimport { type Space } from '@dxos/client/echo';\nimport { Filter, Obj } from '@dxos/echo';\nimport { type ReferencesProvider } from '@dxos/react-ui-chat';\n\n/**\n * Resolve references to objects in the space.\n */\nexport const useReferencesProvider = (space?: Space): ReferencesProvider | undefined => {\n return useMemo<ReferencesProvider | undefined>((): ReferencesProvider | undefined => {\n if (!space) {\n return undefined;\n }\n\n return {\n getReferences: async ({ query }) => {\n // TODO(burdon): Previously we filtered by types declared by the artifact definitions.\n // const schemas = skills.map((skill) => skill.schema).flat();\n // const objects = await space.db\n // .query(Filter.or(...schemas.map((schema) => Filter.type(schema as Type.Schema))))\n // .run();\n\n const objects = await space.db.query(Filter.everything()).run();\n\n return objects\n .filter(Obj.isObject)\n .filter((object) => stringMatch(query, Obj.getLabel(object) ?? ''))\n .map((object) => ({\n uri: Obj.getURI(object),\n label: Obj.getLabel(object) ?? '',\n }));\n },\n resolveReference: async ({ uri }) => {\n const object = await space.db.query(Filter.id(uri)).first();\n return { uri, label: Obj.getLabel(object) ?? '' };\n },\n } satisfies ReferencesProvider;\n }, [space]);\n};\n\nconst stringMatch = (query: string, label: string) => label.toLowerCase().startsWith(query.toLowerCase());\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { useCallback } from 'react';\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\nimport { Obj } from '@dxos/echo';\nimport * as AttentionCapabilities from '@dxos/plugin-attention/AttentionCapabilities';\nimport { Selection } from '@dxos/react-ui-attention/types';\n\nimport { type ProcessorRequestContext } from '../processor/index.ts';\n\n/** Resolve `object`'s selection to text via the AnchorResolver contributed for its typename. */\nexport const getSelectionContext = ({\n object,\n selection,\n resolvers,\n}: {\n object: Obj.Unknown;\n selection: Selection.Selection | undefined;\n resolvers: readonly AppCapabilities.AnchorResolver[];\n}): ProcessorRequestContext | undefined => {\n const typename = Obj.getTypename(object);\n const resolver = typename ? resolvers.find((candidate) => candidate.key === typename) : undefined;\n if (!resolver) {\n return undefined;\n }\n\n // A stale cursor throws in Automerge; a bad range must not abort the submit.\n const resolveAnchorText = (anchor: string): string | undefined => {\n try {\n return resolver.getText(object, anchor);\n } catch {\n return undefined;\n }\n };\n\n // Anchors and text stay pairwise-aligned: a range that fails to resolve is dropped from both.\n const resolved = Selection.toAnchors(selection).flatMap((anchor) => {\n const text = resolveAnchorText(anchor);\n return text != null && text.length > 0 ? [{ anchor, text }] : [];\n });\n if (resolved.length === 0) {\n return undefined;\n }\n\n return {\n selection: {\n anchors: resolved.map(({ anchor }) => anchor),\n text: resolved.map(({ text }) => text).join('\\n…\\n'),\n },\n };\n};\n\n/** Submit-time provider of the companion object's current selection as request context. */\nexport const useSelectionContext = (\n companionTo: Obj.Unknown | undefined,\n): (() => ProcessorRequestContext | undefined) => {\n // getAll-style lookup: absent capabilities yield empty arrays so non-companion chats stay inert.\n const [viewState] = Hooks.useCapabilities(AttentionCapabilities.ViewState);\n const resolvers = Hooks.useCapabilities(AppCapabilities.AnchorResolver);\n\n return useCallback(() => {\n if (!companionTo || !viewState) {\n return undefined;\n }\n const selection = viewState.get(Selection.aspect, Obj.getURI(companionTo));\n return getSelectionContext({ object: companionTo, selection, resolvers });\n }, [companionTo, viewState, resolvers]);\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { useMemo, useState } from 'react';\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport { type Space } from '@dxos/react-client/echo';\nimport * as UiHooks from '@dxos/react-ui/Hooks';\n\nimport { meta } from '#meta';\nimport { AssistantOperation } from '#types';\n\nconst FALLBACK_SUGGESTION_KEYS = [\n 'space-home.suggestion-magazine.label',\n 'space-home.suggestion-kanban.label',\n] as const;\n\n/**\n * Returns starter prompts for the space Home page. Returns undefined while the request is in flight\n * so the section stays hidden until settled. On success yields generated prompts; on empty result or\n * error falls back to the hardcoded defaults.\n */\nexport const useHomeSuggestions = (space?: Space): readonly string[] | undefined => {\n const { t } = UiHooks.useTranslation(meta.profile.key);\n const { invokePromise } = Hooks.useOperationInvoker();\n const fallbacks = useMemo(() => FALLBACK_SUGGESTION_KEYS.map((key) => t(key)), [t]);\n const [suggestions, setSuggestions] = useState<readonly string[] | undefined>(undefined);\n\n UiHooks.useAsyncEffect(\n async (controller) => {\n setSuggestions(undefined);\n if (!space) {\n return;\n }\n const result = await invokePromise(AssistantOperation.GenerateHomeSuggestions, {}, { spaceId: space.db.spaceId });\n if (controller.signal.aborted) {\n return;\n }\n const prompts = result.data?.prompts;\n setSuggestions(prompts && prompts.length > 0 ? prompts : fallbacks);\n },\n [space, invokePromise],\n );\n\n return suggestions;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { useAtomValue } from '@effect/atom-react/Hooks';\nimport * as Effect from 'effect/Effect';\nimport * as Fiber from 'effect/Fiber';\nimport * as Atom from 'effect/reactivity/Atom';\nimport * as Stream from 'effect/Stream';\nimport { useEffect, useMemo, useRef, useState } from 'react';\n\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport { ProcessManager } from '@dxos/compute-runtime';\nimport * as Process from '@dxos/compute/Process';\nimport * as ServiceResolver from '@dxos/compute/ServiceResolver';\nimport type * as Trace from '@dxos/compute/Trace';\nimport { type Space } from '@dxos/react-client/echo';\nimport { resolveEphemeralStatusUpdate } from '@dxos/react-ui-trace';\n\nconst atomEmpty = Atom.make(() => [] as const);\n\nconst ACTIVE_PROCESS_STATES = new Set<Process.State>([Process.State.RUNNING, Process.State.HYBERNATING]);\n\n/** Durable trace lines that represent finished work, not in-flight status. */\nexport const isTerminalActivityLine = (line: string): boolean =>\n line.endsWith(' - Success') || line.endsWith(' - Error') || line === 'Agent completed request';\n\nconst collectDescendantPids = (processes: readonly Process.Process[], rootPid: string): Set<string> => {\n const pids = new Set([rootPid]);\n let expanded = true;\n while (expanded) {\n expanded = false;\n for (const process of processes) {\n const pid = String(process.pid);\n const parentPid = process.parentPid ? String(process.parentPid) : undefined;\n if (parentPid && pids.has(parentPid) && !pids.has(pid)) {\n pids.add(pid);\n expanded = true;\n }\n }\n }\n return pids;\n};\n\nconst resolveSubscribePids = (agentPid: Process.ID, processes: readonly Process.Process[]): Process.ID[] => {\n const rootPid = String(agentPid);\n const descendants = collectDescendantPids(processes, rootPid);\n const activePids = processes\n .filter((process) => descendants.has(String(process.pid)) && ACTIVE_PROCESS_STATES.has(process.state))\n .map((process) => process.pid);\n\n if (activePids.length > 0) {\n return activePids;\n }\n\n return [agentPid];\n};\n\nconst attachActiveHandle = (\n processManager: ProcessManager.Manager,\n pid: Process.ID,\n): Effect.Effect<Process.Handle<any, any, never> | undefined> =>\n Effect.gen(function* () {\n const maxAttempts = 15;\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const handle = yield* processManager.attach(pid).pipe(Effect.catch(() => Effect.succeed(undefined)));\n if (handle && ACTIVE_PROCESS_STATES.has(handle.status.state)) {\n return handle;\n }\n if (handle) {\n return undefined;\n }\n yield* Effect.sleep(100);\n }\n return undefined;\n });\n\n/**\n * Subscribes to ephemeral trace events for a delegated sub-agent process subtree\n * and surfaces the latest pending text or tool-call block as a status line.\n */\nexport const useProcessEphemeralStatus = (\n agentPid: Process.ID | undefined,\n space: Space | undefined,\n): string | undefined => {\n // Optional capabilities: the live status is a progressive enhancement, so the component still\n // renders (e.g. in standalone stories) when there is no plugin manager / process runtime.\n const runtime = Hooks.useOptionalCapability(Capabilities.ProcessManagerRuntime);\n const monitor = Hooks.useOptionalCapability(Capabilities.ProcessManager);\n const processes = useAtomValue(monitor?.processTreeAtom ?? atomEmpty);\n const [status, setStatus] = useState<string | undefined>();\n const fibersRef = useRef<Fiber.Fiber<void, unknown>[]>([]);\n\n const subscribePidsKey = useMemo(() => {\n if (!agentPid) {\n return '';\n }\n return resolveSubscribePids(agentPid, processes)\n .map((pid) => String(pid))\n .sort()\n .join('|');\n }, [agentPid, processes]);\n\n useEffect(() => {\n if (!agentPid || !space?.id || !runtime || !subscribePidsKey) {\n setStatus(undefined);\n return;\n }\n\n const pids = subscribePidsKey.split('|').map((pid) => Process.ID.make(pid));\n let disposed = false;\n let replaying = true;\n let replayStatus: string | undefined;\n const endReplay = () => {\n replaying = false;\n if (!disposed) {\n setStatus(replayStatus);\n }\n };\n queueMicrotask(endReplay);\n fibersRef.current = [];\n\n const handleEphemeralMessage = (message: Trace.Message) => {\n const update = resolveEphemeralStatusUpdate(message);\n if (update === 'unchanged') {\n return;\n }\n\n if (replaying) {\n replayStatus = update.line;\n return;\n }\n setStatus(update.line);\n };\n\n const layer = ServiceResolver.provide({ space: space.id }, ProcessManager.ProcessManagerService);\n\n const subscribe = (pid: Process.ID) =>\n Effect.gen(function* () {\n // `attachActiveHandle` polls, so a teardown can land mid-resolve; bail before forking a\n // daemon that the cleanup pass below would never see (and thus never interrupt).\n if (disposed) {\n return;\n }\n const processManager = yield* ProcessManager.ProcessManagerService;\n const handle = yield* attachActiveHandle(processManager, pid);\n if (!handle || disposed) {\n return;\n }\n\n // `forkDaemon` keeps the stream fiber alive after `runPromise(forEach)` returns;\n // scoped `fork` is interrupted when the subscribe effect's parent scope closes.\n const fiber = yield* handle.subscribeEphemeral().pipe(\n Stream.runForEach((message) =>\n Effect.sync(() => {\n if (disposed) {\n return;\n }\n handleEphemeralMessage(message);\n }),\n ),\n Effect.forkDetach,\n );\n if (disposed) {\n yield* Fiber.interrupt(fiber);\n return;\n }\n fibersRef.current.push(fiber);\n });\n\n void runtime\n .runPromise(\n Effect.forEach(pids, subscribe, { concurrency: 'unbounded', discard: true }).pipe(Effect.provide(layer)),\n )\n .catch(() => {\n if (!disposed) {\n setStatus(undefined);\n }\n });\n\n return () => {\n disposed = true;\n const fibers = fibersRef.current;\n fibersRef.current = [];\n for (const fiber of fibers) {\n void runtime.runPromise(Fiber.interrupt(fiber).pipe(Effect.provide(layer)));\n }\n };\n }, [agentPid, runtime, space?.id, subscribePidsKey]);\n\n return status;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { useAtomValue } from '@effect/atom-react/Hooks';\nimport * as Duration from 'effect/Duration';\nimport * as Atom from 'effect/reactivity/Atom';\nimport { useMemo } from 'react';\n\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport * as Chat from '@dxos/assistant/Chat';\nimport type * as Process from '@dxos/compute/Process';\nimport { Obj } from '@dxos/echo';\nimport { type Space } from '@dxos/react-client/echo';\nimport {\n type Session,\n type SessionTimeline,\n useSessionTimeline as useNaturalSessionTimeline,\n} from '@dxos/react-ui-trace';\nimport { Task } from '@dxos/types';\n\nconst atomEmpty = Atom.make(() => [] as const as readonly Process.Process[]);\n\n/** A chat as the timeline's session: its uri is the agent process's target, its feed the trace meta's. */\nexport const sessionFromChat = (chat: Chat.Chat): Session => ({\n id: chat.id,\n label: chat.name,\n uri: Obj.getURI(chat),\n feedId: Chat.feedEntityId(chat),\n taskIds: chat.tasks.map((ref) => Task.refEntityId(ref)).filter((id): id is string => id !== undefined),\n});\n\n/** What a session is drawn from, as a comparable string. */\nconst sessionKey = (chat: Chat.Chat): string =>\n `${chat.id}:${chat.name ?? ''}:${chat.tasks.map((ref) => Task.refEntityId(ref)).join(',')}`;\n\nexport type UseSessionTimelineOptions = {\n /** The chats whose sessions are shown; each contributes a session lane and its checklist's task lanes. */\n chats: readonly Chat.Chat[];\n tasks?: readonly Task.Task[];\n};\n\n/**\n * The live session timeline of the given chats, with the app's process monitor joined in.\n */\nexport const useSessionTimeline = (\n space: Space | undefined,\n { chats, tasks }: UseSessionTimelineOptions,\n): SessionTimeline => {\n const monitor = Hooks.useOptionalCapability(Capabilities.ProcessManager);\n const processes = useAtomValue(\n useMemo(() => monitor?.processTreeAtom.pipe(Atom.debounce(Duration.millis(500))) ?? atomEmpty, [monitor]),\n );\n // Keyed on the checklists as well as the chats: an agent assigning itself a task edits a chat in\n // place, and a session missing that task would draw it as a lane of its own, outside its band.\n const checklists = chats.map(sessionKey).join('|');\n const sessions = useMemo(() => chats.map(sessionFromChat), [chats, checklists]);\n return useNaturalSessionTimeline(space, { sessions, tasks, processes });\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"hooks.mjs","names":[],"sources":["../../src/hooks/useSkillRegistry.ts","../../src/hooks/useChatKeymap.ts","../../src/hooks/useChatModel.ts","../../src/hooks/useChatServices.ts","../../src/hooks/useChatToolbarActions.ts","../../src/hooks/useContextBinder.ts","../../src/hooks/useContextObjects.ts","../../src/hooks/useDebug.ts","../../src/hooks/useFilteredTypes.ts","../../src/hooks/useMcpServer.ts","../../src/hooks/usePlatform.ts","../../src/hooks/usePresets.ts","../../src/hooks/useReferencesProvider.ts","../../src/hooks/useSelectionContext.ts","../../src/hooks/useHomeSuggestions.ts","../../src/hooks/useProcessEphemeralStatus.ts","../../src/hooks/useSessionTimeline.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { type AiContext } from '@dxos/assistant';\nimport * as Skill from '@dxos/compute/Skill';\nimport { type Database, Filter, Obj, Ref, type Registry } from '@dxos/echo';\nimport { useQuery } from '@dxos/echo-react';\nimport { log } from '@dxos/log';\nimport { distinctBy } from '@dxos/util';\n\n/**\n * Stable identity for a skill in the picker.\n *\n * A registry skill is identified by its key, but a skill the user authored in a space has no\n * registry entry and so no key; falling back to its URI keeps such skills distinct from each other\n * (a shared `undefined` key collapses them into one row) and addressable by the toggle handler.\n */\nexport const getSkillId = (skill: Skill.Skill): string => Obj.getMeta(skill).key ?? Obj.getURI(skill) ?? skill.id;\n\nexport const useSkills = ({ registry, db }: { registry?: Registry.Registry; db?: Database.Database }) => {\n const [registrySkills, setRegistrySkills] = useState<Skill.Skill[]>(\n () => registry?.query(Filter.type(Skill.Skill)).runSync() ?? [],\n );\n\n useEffect(() => {\n if (!registry) {\n setRegistrySkills([]);\n return;\n }\n setRegistrySkills(registry.query(Filter.type(Skill.Skill)).runSync());\n return registry.changed.on(() => {\n setRegistrySkills(registry.query(Filter.type(Skill.Skill)).runSync());\n });\n }, [registry]);\n\n const spaceSkills = useQuery(db, Filter.type(Skill.Skill));\n return useMemo(() => {\n // Space copies first, so a fork shadows the registry entry it was cloned from rather than the\n // other way round — it carries the user's edits (same precedence as `Skill.resolveAnnotatedSkills`).\n const skills = distinctBy([...spaceSkills, ...registrySkills], getSkillId);\n skills.sort(({ name: a }, { name: b }) => a.localeCompare(b));\n return skills;\n }, [registrySkills, spaceSkills]);\n};\n\n/**\n * Create reactive map of active skills (by skill id).\n */\nexport const useActiveSkills = ({ context }: { context?: AiContext.Binder }) => {\n const [active, setActive] = useState<Map<string, Skill.Skill>>(new Map());\n\n useEffect(() => {\n if (!context) {\n setActive(new Map());\n return;\n }\n\n const updateActive = () => {\n setActive(new Map(context.getSkills().map((skill) => [getSkillId(skill), skill] as const)));\n };\n\n // Set initial value.\n updateActive();\n\n // Subscribe to changes.\n return context.subscribeSkills(updateActive);\n }, [context]);\n\n return active;\n};\n\n// TODO(burdon): Move logic into binder.\nexport const useSkillHandlers = ({ context }: { context?: AiContext.Binder }) => {\n const onUpdateSkill = useCallback(\n async (skill: Skill.Skill, checked: boolean) => {\n if (!context) {\n return;\n }\n\n // A registry skill binds by its key URI, which resolves through the hypergraph registry — no\n // DB clone needed. Anything else is a space object (including a fork of a registry skill) and\n // binds by its own ref, so the user's edits are what the conversation sees.\n const key = Obj.getMeta(skill).key;\n const registryRef = key !== undefined ? Ref.fromURI(Skill.registryURI(key)) : undefined;\n const ref = Obj.getDatabase(skill) === undefined && registryRef ? registryRef : Ref.make(skill);\n\n log('update skill', { skill: getSkillId(skill), uri: ref.uri, checked });\n if (checked) {\n await context.bind({ skills: [ref] });\n } else {\n // Both forms: a fork and the registry entry it shadows share one row, and the toggle has to\n // clear the conversation whichever of the two was bound (e.g. by the chat's own context).\n const refs = registryRef && registryRef.uri !== ref.uri ? [ref, registryRef] : [ref];\n await context.unbind({ skills: refs });\n }\n },\n [context],\n );\n\n return { onUpdateSkill };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Extension, Prec } from '@codemirror/state';\nimport { keymap } from '@codemirror/view';\nimport { useMemo } from 'react';\n\nimport { type Event } from '@dxos/async';\nimport { isTruthy } from '@dxos/util';\n\nimport { type ChatEvent } from '../components/Chat/events.ts';\n\n/**\n * CodeMirror keymap shared by the chat document (Thread) and the prompt editor — pressing\n * Mod-Arrow keys when either editor is focused emits the corresponding `ChatEvent` on the\n * shared event bus.\n */\nexport const useChatKeymapExtensions = ({ event }: { event: Event<ChatEvent> }): Extension[] => {\n return useMemo<Extension[]>(() => {\n return [\n Prec.highest(\n keymap.of([\n {\n key: 'Mod-ArrowUp',\n preventDefault: true,\n run: () => {\n event.emit({ type: 'nav-previous' });\n return true;\n },\n shift: () => {\n event.emit({ type: 'thread-open' });\n return true;\n },\n },\n {\n key: 'Mod-ArrowDown',\n preventDefault: true,\n run: () => {\n event.emit({ type: 'nav-next' });\n return true;\n },\n shift: () => {\n event.emit({ type: 'thread-close' });\n return true;\n },\n },\n ]),\n ),\n ].filter(isTruthy);\n }, [event]);\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { RegistryContext } from '@effect/atom-react/RegistryContext';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport { useContext, useEffect, useMemo, useState } from 'react';\n\nimport { AiService, OpaqueToolkit } from '@dxos/ai';\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport { AiSession } from '@dxos/assistant';\nimport type * as Chat from '@dxos/assistant/Chat';\nimport * as AgentService from '@dxos/compute/AgentService';\nimport * as Credential from '@dxos/compute/Credential';\nimport * as ServiceResolver from '@dxos/compute/ServiceResolver';\nimport { Database, Obj, Ref, Registry } from '@dxos/echo';\nimport { useObject } from '@dxos/echo-react';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { log } from '@dxos/log';\nimport * as UiHooks from '@dxos/react-ui/Hooks';\n\nimport { Assistant } from '#types';\n\nimport { type AiServicePreset, ChatModel } from '../chat-model/index.ts';\n\nexport type UseChatModelProps = {\n db?: Database.Database;\n chat?: Chat.Chat;\n preset?: AiServicePreset;\n runtime?: Capabilities.ProcessManagerRuntime;\n registry?: Registry.Registry;\n settings?: Assistant.Settings;\n /** Attributes the prompts submitted through this chat model to a person (see `ChatModelOptions.sender`). */\n sender?: AgentService.PromptSender;\n};\n\n/**\n * Configure and create ChatModel.\n */\nexport const useChatModel = ({\n db,\n chat,\n preset,\n runtime,\n registry,\n settings,\n sender,\n}: UseChatModelProps): ChatModel | undefined => {\n const observableRegistry = useContext(RegistryContext);\n\n // Reactive subscription — re-renders when the feed ref resolves. Direct `.target` reads are not reactive.\n const [feedSnapshot] = useObject(chat?.feed);\n const feed = Obj.getReactiveOrUndefined(feedSnapshot);\n\n const [session, setSession] = useState<AiSession.Session>();\n UiHooks.useAsyncEffect(async () => {\n if (!db || !chat || !feed) {\n return;\n }\n\n const runtime = await EffectEx.runAndForwardErrors(\n Effect.context<Database.Service>().pipe(Effect.provide(Database.layer(db))),\n );\n const session = new AiSession.Session({\n feed,\n runtime,\n registry: observableRegistry,\n });\n const openedAt = performance.now();\n await session.open();\n log('session opened', { chat: chat.id, duration: Math.round(performance.now() - openedAt) });\n setSession(session);\n return () => {\n void session.close();\n setSession(undefined);\n };\n }, [db, chat, feed]);\n\n const serviceResolver = Hooks.useCapability(Capabilities.ServiceResolver);\n // Primitives rather than the object, so an inline `sender` literal does not rebuild the chat model each render.\n const senderName = sender?.name;\n const senderDid = sender?.identityDid;\n const reportStruggles = settings?.reportStruggles ?? false;\n\n const chatModel = useMemo(() => {\n if (!runtime || !session || !chat || !feed || !db) {\n return undefined;\n }\n\n const spaceLayer = ServiceResolver.provide(\n { space: db.spaceId },\n Database.Service,\n Credential.CredentialsService,\n AiService.AiService,\n AgentService.AgentService,\n Registry.Service,\n OpaqueToolkit.OpaqueToolkitProvider,\n ).pipe(Layer.provide(Layer.succeed(ServiceResolver.ServiceResolver, serviceResolver)));\n\n log('creating chat model', { preset, model: preset?.model, settings });\n return new ChatModel(session, runtime, feed, spaceLayer, {\n chat: chat ? Ref.make(chat) : undefined,\n observableRegistry,\n registry,\n model: preset?.model,\n provider: preset?.provider,\n // Absent keys rather than `undefined` values: the sender crosses the process input schema.\n sender:\n senderName || senderDid\n ? { ...(senderName ? { name: senderName } : {}), ...(senderDid ? { identityDid: senderDid } : {}) }\n : undefined,\n reportStruggles,\n });\n }, [runtime, session, registry, preset, chat, feed, db?.spaceId, senderName, senderDid, reportStruggles]);\n\n // A remount (e.g. the user navigated to another page mid-turn) gets a fresh chat model whose\n // active/streaming state starts empty, while the agent process for the feed keeps running;\n // adopting it restores the running indicator and the streamed blocks.\n useEffect(() => chatModel?.adopt(), [chatModel]);\n\n return chatModel;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport * as AppSpace from '@dxos/app-toolkit/AppSpace';\nimport { type Key } from '@dxos/echo';\nimport { useClient } from '@dxos/react-client';\n\nimport { AssistantEvents } from '#types';\n\nexport type UseChatServicesProps = {\n id?: Key.SpaceId;\n};\n\n/**\n * Resolves the shared {@link Capabilities.ProcessManagerRuntime} for the given space.\n *\n * The runtime itself is space-agnostic; the returned value can be used to run\n * effects that pipe through {@link ServiceResolver.provide} (or the\n * `useSpaceCallback`/`useSpaceService` hooks) with the resolved {@link Key.SpaceId}.\n */\nexport const useChatServices = ({ id }: UseChatServicesProps) => {\n const client = useClient();\n id ??= AppSpace.getDefaultSpace(client)?.id;\n\n // Every chat entry point resolves its services here, so this is the assistant-in-use demand\n // signal: start-gated assistant modules (skills included) load now and register via the\n // reactive RegistrySync.\n Hooks.useActivationSignal(AssistantEvents.Start);\n const runtime = Hooks.useCapability(Capabilities.ProcessManagerRuntime);\n return id ? runtime : undefined;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport * as Chat from '@dxos/assistant/Chat';\nimport { Filter, Obj, Query, Type } from '@dxos/echo';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { invariant } from '@dxos/invariant';\nimport { MenuBuilder, useMenuBuilder } from '@dxos/react-ui-menu';\n\nimport { meta } from '#meta';\nimport { AssistantOperation } from '#types';\n\nimport { useChatContext } from '../components/Chat/context.ts';\n\n/**\n * Scopes the toolbar's chat switcher: which chats it lists, and what picking one does.\n *\n * Without it the switcher shows the companion chats of `companionTo` and switches the companion,\n * which is what the app wants nearly everywhere. A caller that owns its own chat selection (a\n * story showing every chat in a space, a panel scoped to a project) passes its own.\n */\nexport type ChatSwitcher = {\n chats: Chat.Chat[];\n onSelect: (chat: Chat.Chat) => void;\n};\n\nexport type ChatToolbarActionsProps = {\n chat?: Chat.Chat;\n companionTo?: Obj.Unknown;\n switcher?: ChatSwitcher;\n};\n\nexport const useChatToolbarActions = ({ chat, companionTo, switcher }: ChatToolbarActionsProps) => {\n const { invoke } = Hooks.useOperationInvoker();\n const { db } = useChatContext('useChatToolbarActions');\n\n // Stable references in deps avoid circular reference issues.\n return useMenuBuilder(\n (get) => {\n const chats =\n switcher?.chats ??\n (companionTo && db\n ? get(db.query(Query.select(Filter.id(companionTo.id)).children()).atom).filter(Obj.instanceOf(Chat.Chat))\n : []);\n\n const builder = MenuBuilder.make().root({\n label: ['chat-toolbar.title', { ns: meta.profile.key }],\n });\n\n if (companionTo) {\n builder.action(\n 'new',\n {\n label: ['new-thread.button', { ns: meta.profile.key }],\n icon: 'ph--plus--regular',\n type: 'new',\n },\n () => {\n invariant(companionTo);\n return invoke(AssistantOperation.SetCurrentChat, {\n companionTo,\n chat: undefined,\n }).pipe(EffectEx.runAndForwardErrors);\n },\n );\n }\n\n builder\n .action(\n 'branch',\n {\n label: ['branch-thread.menu', { ns: meta.profile.key }],\n icon: 'ph--git-branch--regular',\n type: 'branch',\n disabled: !chat || !db,\n },\n () =>\n Effect.gen(function* () {\n invariant(chat);\n yield* invoke(AssistantOperation.ForkChat, { chat, companionTo }, { spaceId: db?.spaceId });\n }).pipe(EffectEx.runAndForwardErrors),\n )\n .action(\n 'rename',\n {\n label: ['rename-thread.button', { ns: meta.profile.key }],\n icon: 'ph--magic-wand--regular',\n type: 'rename',\n disabled: !chat,\n },\n () =>\n Effect.gen(function* () {\n invariant(chat);\n yield* invoke(AssistantOperation.UpdateChatName, { chat }, { spaceId: db?.spaceId });\n }).pipe(EffectEx.runAndForwardErrors),\n );\n\n if (chats.length > 0) {\n builder.separator().group(\n 'chats',\n {\n label: ['chat-history.label', { ns: meta.profile.key }],\n icon: 'ph--clock-counter-clockwise--regular',\n selectCardinality: 'single',\n variant: 'dropdownMenu',\n },\n (builder) => {\n chats\n // TODO(wittjosiah): This should be the default sort order.\n .toSorted((a, b) => a.id.localeCompare(b.id))\n .forEach((chat) => {\n get(Obj.atomProperty(chat, 'name'));\n\n builder.action(\n chat.id,\n {\n label: Obj.getLabel(chat) ?? ['object-name.placeholder', { ns: Type.getTypename(Chat.Chat) }],\n },\n () => {\n if (switcher) {\n switcher.onSelect(chat);\n return;\n }\n return Effect.gen(function* () {\n invariant(companionTo);\n yield* invoke(AssistantOperation.SetCurrentChat, {\n companionTo,\n chat,\n });\n }).pipe(EffectEx.runAndForwardErrors);\n },\n );\n });\n },\n );\n }\n\n return builder.build();\n },\n [db?.spaceId, companionTo?.id, chat?.id, invoke, switcher?.chats.map(({ id }) => id).join(), switcher?.onSelect],\n );\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { RegistryContext } from '@effect/atom-react/RegistryContext';\nimport * as Effect from 'effect/Effect';\nimport type * as Registry from 'effect/reactivity/AtomRegistry';\nimport { useContext, useState } from 'react';\n\nimport { AiContext } from '@dxos/assistant';\nimport { Database, Feed } from '@dxos/echo';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { type Space } from '@dxos/react-client/echo';\nimport * as Hooks from '@dxos/react-ui/Hooks';\n\nexport const useContextBinder = (\n space: Space | undefined,\n feed: Feed.Feed | undefined,\n): AiContext.Binder | undefined => {\n const registry = useContext(RegistryContext) as Registry.AtomRegistry;\n const [binder, setBinder] = useState<AiContext.Binder>();\n\n Hooks.useAsyncEffect(async () => {\n setBinder(undefined);\n if (!space || !feed) {\n return;\n }\n\n const runtime = await EffectEx.runAndForwardErrors(\n Effect.context<Database.Service>().pipe(Effect.provide(Database.layer(space.db))),\n );\n const binder = new AiContext.Binder({ feed, runtime, registry });\n await binder.open();\n setBinder(binder);\n\n return () => {\n void binder.close();\n };\n }, [space, feed]);\n\n return binder;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { useAtomValue } from '@effect/atom-react/Hooks';\nimport * as Atom from 'effect/reactivity/Atom';\nimport { useCallback, useMemo } from 'react';\n\nimport { type AiContext } from '@dxos/assistant';\nimport * as Chat from '@dxos/assistant/Chat';\nimport { type Database, Obj } from '@dxos/echo';\nimport { type URI } from '@dxos/keys';\n\nexport type UseContextObjectsProps = {\n db?: Database.Database;\n context?: AiContext.Binder;\n};\n\nexport type UseContextObjects = {\n objects: Obj.Unknown[];\n onUpdateObject: (dxn: URI.URI, checked: boolean) => Promise<void>;\n};\n\nconst emptyObjectsAtom = Atom.make<Obj.Unknown[]>([]);\n\n/**\n * Create reactive map of active object references (by DXN string).\n */\nexport const useContextObjects = ({ db, context }: UseContextObjectsProps): UseContextObjects => {\n const boundObjects = useAtomValue(context?.objects ?? emptyObjectsAtom);\n // The session's own chat is bound into its context so the agent harness can resolve it\n // (`get-context` requires a bound chat to read the plan when no agent is present); it is not a\n // user-added reference, so exclude it from the UI. Mirrors the `!Obj.instanceOf(Chat.Chat, …)`\n // filter applied when copying context objects in `assistant-toolkit` `Agent`.\n const objects = useMemo(() => boundObjects.filter((object) => !Obj.instanceOf(Chat.Chat, object)), [boundObjects]);\n\n const handleUpdateObject = useCallback<UseContextObjects['onUpdateObject']>(\n async (dxn: URI.URI, checked: boolean) => {\n if (!db || !context) {\n return;\n }\n\n const ref = db.makeRef<Obj.Unknown>(dxn);\n await ref.load();\n if (checked) {\n await context.bind({ objects: [ref] });\n } else {\n await context.unbind({ objects: [ref] });\n }\n },\n [db, context],\n );\n\n return {\n objects,\n onUpdateObject: handleUpdateObject,\n };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { useCallback } from 'react';\n\nimport { trim } from '@dxos/util';\n\nimport { type ChatModel } from '../chat-model/index.ts';\n\n/**\n * Returns an async callback that logs the chat's current context, system prompt,\n * and resolved tools to the browser console under a collapsible group.\n * Used by the chat's debug-toggle event handler.\n */\nexport const useDebug = ({ chatModel }: { chatModel?: ChatModel }) => {\n return useCallback(async () => {\n if (!chatModel) {\n return;\n }\n\n const objects = chatModel.context.getObjects();\n const skills = chatModel.context.getSkills();\n const system = await chatModel.getSystemPrompt();\n const tools = (await chatModel.getTools()) ?? {};\n console.group('Chat', { objects, skills });\n try {\n console.log(trim`\n System Prompt:\n ${system}\n `);\n console.log(trim`\n Tools:\n ${Object.values(tools)\n .map((tool) => JSON.stringify(tool, null, 2))\n .join('\\n')}\n `);\n } finally {\n console.groupEnd();\n }\n }, [chatModel]);\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { useEffect, useState } from 'react';\n\nimport * as TypeOptions from '@dxos/app-toolkit/TypeOptions';\nimport { type Database, Type } from '@dxos/echo';\n\nconst getFilteredTypes = (db: Database.Database): Type.AnyEntity[] =>\n Array.from(\n new Set(\n db.graph.registry\n .list()\n .filter(Type.isType)\n .filter((schema) => TypeOptions.isUserType(schema)),\n ),\n );\n\n// TODO(burdon): Pass in filter.\n// TODO(wittjosiah): Factor out.\nexport const useFilteredTypes = (db?: Database.Database): Type.AnyEntity[] => {\n const [types, setTypes] = useState<Type.AnyEntity[]>([]);\n useEffect(() => {\n if (!db) {\n return;\n }\n\n setTypes(getFilteredTypes(db));\n return db.graph.registry.changed.on(() => {\n setTypes(getFilteredTypes(db));\n });\n }, [db]);\n\n return types;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Deferred from 'effect/Deferred';\nimport * as Duration from 'effect/Duration';\nimport * as Effect from 'effect/Effect';\nimport * as Schema from 'effect/Schema';\nimport { useCallback, useEffect, useState } from 'react';\n\nimport * as McpServer from '@dxos/compute/McpServer';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { log } from '@dxos/log';\nimport { McpOAuth, McpToolkit } from '@dxos/mcp-client';\n\nexport type McpServerStatus =\n | { state: 'disabled' }\n | { state: 'checking' }\n | { state: 'connected'; tools: string[] }\n | { state: 'unauthorized'; message: string }\n | { state: 'error'; message: string };\n\n/** Served by composer-app from `public/`; relays the authorization response on {@link OAUTH_CHANNEL}. */\nconst OAUTH_CALLBACK_PATH = '/mcp-oauth-callback.html';\nconst OAUTH_CHANNEL = 'dxos.mcp-oauth';\nconst SIGN_IN_TIMEOUT = Duration.minutes(5);\n\ntype CallbackResult = { code?: string; state?: string; error?: string };\n\n/** The interactive part of an MCP sign-in failed; `message` is shown on the server's row. */\nclass McpSignInError extends Schema.TaggedError<McpSignInError>('McpSignInError')('McpSignInError', {\n message: Schema.String,\n}) {}\n\n/**\n * The server's connection options as this browser can build them: the same credentials the agent\n * resolves each turn, minus EDGE-custodied tokens, which the UI cannot read.\n */\nconst toOptions = async (server: McpServer.McpServer): Promise<McpToolkit.Options> => {\n const options: McpToolkit.Options = { url: server.url, protocol: server.protocol, apiKey: server.apiKey };\n if (server.oauth?.tokens) {\n return { ...options, authProvider: McpOAuth.makeProvider({ store: McpServer.oauthStore(server) }) };\n }\n const accessToken = await server.accessToken?.tryLoad();\n return accessToken ? { ...options, apiKey: accessToken.token } : options;\n};\n\n/**\n * Checks that the server answers with the configured credentials. `revision` re-runs the check, e.g.\n * after signing in.\n */\nexport const useMcpServerStatus = (\n server: McpServer.McpServer,\n { enabled, revision }: { enabled: boolean; revision: number },\n): McpServerStatus => {\n const [status, setStatus] = useState<McpServerStatus>({ state: enabled ? 'checking' : 'disabled' });\n const url = server.url;\n const signedIn = server.oauth?.tokens !== undefined;\n\n useEffect(() => {\n if (!enabled) {\n setStatus({ state: 'disabled' });\n return;\n }\n\n let cancelled = false;\n setStatus({ state: 'checking' });\n void Effect.tryPromise({\n try: () => toOptions(server),\n catch: (cause) =>\n new McpToolkit.McpConnectionError({\n url: server.url,\n protocol: server.protocol,\n message: `Failed to load the server's credentials: ${McpToolkit.formatCause(cause)}`,\n }),\n })\n .pipe(\n Effect.flatMap(McpToolkit.probe),\n Effect.match({\n onSuccess: ({ tools }): McpServerStatus => ({ state: 'connected', tools }),\n onFailure: (error): McpServerStatus =>\n error.unauthorized\n ? { state: 'unauthorized', message: error.message }\n : { state: 'error', message: error.message },\n }),\n EffectEx.runAndForwardErrors,\n )\n .then((next) => {\n if (!cancelled) {\n setStatus(next);\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [server, url, enabled, signedIn, revision]);\n\n return status;\n};\n\n/**\n * Signs in to a server that uses MCP authorization (OAuth 2.1): discovers its authorization server,\n * registers Composer as a client, and runs the PKCE code flow in a popup. The tokens land on the\n * server object, where every agent in the space picks them up.\n */\nexport const useMcpServerSignIn = (server: McpServer.McpServer) => {\n const [pending, setPending] = useState(false);\n const [error, setError] = useState<string>();\n\n const signIn = useCallback(async () => {\n // Opened synchronously in the click handler: discovery and registration are awaited before the\n // authorization URL is known, and a popup opened after an await is blocked.\n const popup = window.open('about:blank', 'dxos-mcp-oauth', 'popup,width=520,height=720');\n setPending(true);\n setError(undefined);\n try {\n await EffectEx.runAndForwardErrors(authorize(server, popup));\n } catch (err) {\n log.warn('MCP sign-in failed', { url: server.url, error: err });\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n popup?.close();\n setPending(false);\n }\n }, [server]);\n\n return { signIn, pending, error };\n};\n\nconst authorize = (server: McpServer.McpServer, popup: Window | null) =>\n Effect.gen(function* () {\n if (!popup) {\n return yield* Effect.fail(new McpSignInError({ message: 'The sign-in window was blocked.' }));\n }\n\n const provider = McpOAuth.makeProvider({\n store: McpServer.oauthStore(server),\n redirectUrl: new URL(OAUTH_CALLBACK_PATH, window.location.origin).href,\n onAuthorize: (authorizationUrl) => {\n popup.location.href = authorizationUrl.href;\n },\n });\n\n // Every sign-in in this origin hears every callback; only the one whose `state` it echoes is ours.\n const callback = yield* Deferred.make<CallbackResult>();\n const channel = new BroadcastChannel(OAUTH_CHANNEL);\n channel.onmessage = (event: MessageEvent<CallbackResult>) => {\n if (event.data.state !== undefined && event.data.state === provider.pendingState) {\n Deferred.doneUnsafe(callback, Effect.succeed(event.data));\n }\n };\n yield* Effect.addFinalizer(() => Effect.sync(() => channel.close()));\n\n const result = yield* McpOAuth.authorize(provider, server.url);\n if (result === 'AUTHORIZED') {\n // Stored tokens were still good, or were refreshed without the user.\n return;\n }\n\n const { code, error } = yield* Deferred.await(callback).pipe(\n Effect.timeoutOrElse({\n duration: SIGN_IN_TIMEOUT,\n orElse: () => Effect.fail(new McpSignInError({ message: 'Timed out waiting for sign-in.' })),\n }),\n );\n if (error || !code) {\n return yield* Effect.fail(new McpSignInError({ message: error ?? 'The authorization server returned no code.' }));\n }\n\n yield* McpOAuth.completeAuthorization(provider, server.url, code);\n }).pipe(Effect.scoped);\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport * as DeckCapabilities from '@dxos/plugin-deck/DeckCapabilities';\n\n/**\n * Which shell the chat surfaces are rendering into.\n *\n * Platform, not viewport: the affordances keyed to it (the online indicator, the thread's marker rail\n * and status pill) are dropped because the mobile app has no room and no pointer for them, not\n * because a window happens to be narrow — a narrowed desktop window keeps them all.\n *\n * The capability is optional so a harness that loads no deck plugin (storybook, tests) still renders,\n * taking the desktop treatment.\n *\n * Reads `DeckCapabilities.Platform` rather than `useLayout()` because `Layout.mode` is an open string\n * contract for whatever a layout plugin reports, while `Platform` is the typed, boot-fixed source this\n * hook actually needs.\n */\nexport const usePlatform = (): DeckCapabilities.Platform =>\n Hooks.useOptionalCapability(DeckCapabilities.Platform) ?? 'desktop';\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { useAtomValue } from '@effect/atom-react/Hooks';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { Model, Provider } from '@dxos/ai';\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport type * as Chat from '@dxos/assistant/Chat';\nimport { Obj } from '@dxos/echo';\nimport { useObject } from '@dxos/echo-react';\nimport * as EffectEx from '@dxos/effect/EffectEx';\nimport { DXN } from '@dxos/keys';\nimport * as UiHooks from '@dxos/react-ui/Hooks';\n\nimport { meta } from '#meta';\nimport { Assistant, AssistantCapabilities, AssistantPreset, Ollama } from '#types';\n\nimport {\n type AiServicePreset,\n defaultsKeyForProvider,\n pickPreset,\n presetsForProvider,\n providerForModel,\n resolveProvider,\n} from '../chat-model/index.ts';\n\nexport type UsePresets = {\n preset: AiServicePreset | undefined;\n} & Pick<AssistantPreset.ChatPresetProps, 'presets' | 'onPresetChange'>;\n\n/**\n * Resolves the chat model presets for the provider selected in settings ({@link Assistant.Settings.modelProvider}).\n * The selection is the chat's own (`Chat.session.model`), written back to it when the user picks; a chat that\n * has not selected one shows the configured per-provider model.\n */\nexport const usePresets = (settings: Assistant.Settings, chat?: Chat.Chat): UsePresets => {\n const { t } = UiHooks.useTranslation(meta.profile.key);\n // Subscribed rather than read: the picker has to follow a selection made on another mount of the\n // same chat, and the stamp the chat model writes before the first request.\n const [session] = useObject(chat, 'session');\n const chatModel = session?.model;\n\n // The Ollama manager is the bundled sidecar (desktop only); its presence signals that the\n // `built-in` provider (rather than an external Ollama server) is available.\n const ollamaManager = Hooks.useOptionalCapability(AssistantCapabilities.OllamaManager);\n\n const provider = resolveProvider(settings.modelProvider, !!ollamaManager);\n const defaultModel = settings.modelDefaults?.[defaultsKeyForProvider(provider)];\n\n // Installed models reported by the bundled sidecar; used to offer only models actually present.\n const localModels = useAtomValue(ollamaManager?.state ?? Ollama.emptyState);\n\n // When the bundled sidecar is the active provider, list installed models in the background so the\n // chat selector is populated without first opening settings. Idempotent: kicks off only from the\n // idle state, so it spawns the sidecar once when local models are in use (not on every launch);\n // settings remains the explicit path for retrying after a failure.\n useEffect(() => {\n if (provider === Provider.builtIn.id && ollamaManager && localModels.kind === 'idle') {\n void EffectEx.runPromise(ollamaManager.refresh);\n }\n }, [provider, ollamaManager, localModels.kind]);\n\n // Probe the external LM Studio server only when that provider is selected on desktop.\n const lmStudioProbeUrl =\n provider === Provider.lmStudio.id && ollamaManager ? `${Provider.lmStudio.endpoint}/v1/models` : undefined;\n const lmStudioReachable = useEndpointReachable(lmStudioProbeUrl);\n\n const presets = useMemo(() => {\n const base = presetsForProvider(provider);\n // Desktop LM Studio: only offer presets when the external server responds.\n if (provider === Provider.lmStudio.id && ollamaManager) {\n return lmStudioReachable ? base : [];\n }\n // Bundled sidecar: only offer models that are actually installed (matched by back-end pull tag).\n if (provider === Provider.builtIn.id && ollamaManager) {\n const installed = new Set(localModels.models.map((model) => model.name));\n return base.filter((preset) => installed.has(preset.backend));\n }\n return base;\n }, [provider, ollamaManager, lmStudioReachable, localModels]);\n\n // The chat's selection when the active provider serves it, else the provider's configured model.\n // A selection the provider does not serve (the chat picked Claude, then the user went offline) is\n // still what the process will run, so it is shown as an unavailable entry rather than silently\n // displayed as the fallback — the picker and the request must agree.\n const unavailable = useMemo<AiServicePreset | undefined>(() => {\n if (!chatModel || presets.length === 0 || presets.some((preset) => preset.model === chatModel)) {\n return undefined;\n }\n // Carries the provider that actually serves the model rather than the active one, which by\n // definition does not — a resolver chain that still reaches it then can.\n const catalog = Model.byId(chatModel)[0];\n return {\n id: chatModel,\n provider: providerForModel(chatModel, provider) ?? provider,\n model: chatModel,\n backend: catalog?.backend ?? '',\n label: t('model-unavailable.label', { label: catalog?.label ?? DXN.getName(chatModel) }),\n };\n }, [chatModel, presets, provider, t]);\n\n const preset = useMemo(\n () => presets.find((preset) => preset.model === chatModel) ?? unavailable ?? pickPreset(presets, defaultModel),\n [presets, chatModel, unavailable, defaultModel],\n );\n\n const presetOptions = useMemo(\n () =>\n [...presets, ...(unavailable ? [unavailable] : [])].map(({ id, model, label }) => ({\n id,\n label: label ?? model,\n })),\n [presets, unavailable],\n );\n\n const handlePresetChange = useCallback<NonNullable<AssistantPreset.ChatPresetProps['onPresetChange']>>(\n (id) => {\n const preset = presets.find((preset) => preset.id === id);\n if (preset && chat) {\n Obj.update(chat, (chat) => {\n chat.session = { ...chat.session, model: preset.model };\n });\n }\n },\n [presets, chat],\n );\n\n return {\n preset,\n presets: presetOptions,\n onPresetChange: handlePresetChange,\n };\n};\n\n/** Reactively reports whether an HTTP endpoint responds; `undefined` url disables the probe. */\nconst useEndpointReachable = (url: string | undefined): boolean => {\n const [reachable, setReachable] = useState(false);\n useEffect(() => {\n if (!url) {\n setReachable(false);\n return;\n }\n let active = true;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 1500);\n fetch(url, { signal: controller.signal })\n .then((response) => active && setReachable(response.ok))\n .catch(() => active && setReachable(false))\n .finally(() => clearTimeout(timer));\n return () => {\n active = false;\n controller.abort();\n clearTimeout(timer);\n };\n }, [url]);\n return reachable;\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { useMemo } from 'react';\n\nimport { type Space } from '@dxos/client/echo';\nimport { Filter, Obj } from '@dxos/echo';\nimport { type ReferencesProvider } from '@dxos/react-ui-chat';\n\n/**\n * Resolve references to objects in the space.\n */\nexport const useReferencesProvider = (space?: Space): ReferencesProvider | undefined => {\n return useMemo<ReferencesProvider | undefined>((): ReferencesProvider | undefined => {\n if (!space) {\n return undefined;\n }\n\n return {\n getReferences: async ({ query }) => {\n // TODO(burdon): Previously we filtered by types declared by the artifact definitions.\n // const schemas = skills.map((skill) => skill.schema).flat();\n // const objects = await space.db\n // .query(Filter.or(...schemas.map((schema) => Filter.type(schema as Type.Schema))))\n // .run();\n\n const objects = await space.db.query(Filter.everything()).run();\n\n return objects\n .filter(Obj.isObject)\n .filter((object) => stringMatch(query, Obj.getLabel(object) ?? ''))\n .map((object) => ({\n uri: Obj.getURI(object),\n label: Obj.getLabel(object) ?? '',\n }));\n },\n resolveReference: async ({ uri }) => {\n const object = await space.db.query(Filter.id(uri)).first();\n return { uri, label: Obj.getLabel(object) ?? '' };\n },\n } satisfies ReferencesProvider;\n }, [space]);\n};\n\nconst stringMatch = (query: string, label: string) => label.toLowerCase().startsWith(query.toLowerCase());\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { useCallback } from 'react';\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\nimport { Obj } from '@dxos/echo';\nimport * as AttentionCapabilities from '@dxos/plugin-attention/AttentionCapabilities';\nimport { Selection } from '@dxos/react-ui-attention/types';\n\nimport { type ChatRequestContext } from '../chat-model/index.ts';\n\n/** Resolve `object`'s selection to text via the AnchorResolver contributed for its typename. */\nexport const getSelectionContext = ({\n object,\n selection,\n resolvers,\n}: {\n object: Obj.Unknown;\n selection: Selection.Selection | undefined;\n resolvers: readonly AppCapabilities.AnchorResolver[];\n}): ChatRequestContext | undefined => {\n const typename = Obj.getTypename(object);\n const resolver = typename ? resolvers.find((candidate) => candidate.key === typename) : undefined;\n if (!resolver) {\n return undefined;\n }\n\n // A stale cursor throws in Automerge; a bad range must not abort the submit.\n const resolveAnchorText = (anchor: string): string | undefined => {\n try {\n return resolver.getText(object, anchor);\n } catch {\n return undefined;\n }\n };\n\n // Anchors and text stay pairwise-aligned: a range that fails to resolve is dropped from both.\n const resolved = Selection.toAnchors(selection).flatMap((anchor) => {\n const text = resolveAnchorText(anchor);\n return text != null && text.length > 0 ? [{ anchor, text }] : [];\n });\n if (resolved.length === 0) {\n return undefined;\n }\n\n return {\n selection: {\n anchors: resolved.map(({ anchor }) => anchor),\n text: resolved.map(({ text }) => text).join('\\n…\\n'),\n },\n };\n};\n\n/** Submit-time provider of the companion object's current selection as request context. */\nexport const useSelectionContext = (companionTo: Obj.Unknown | undefined): (() => ChatRequestContext | undefined) => {\n // getAll-style lookup: absent capabilities yield empty arrays so non-companion chats stay inert.\n const [viewState] = Hooks.useCapabilities(AttentionCapabilities.ViewState);\n const resolvers = Hooks.useCapabilities(AppCapabilities.AnchorResolver);\n\n return useCallback(() => {\n if (!companionTo || !viewState) {\n return undefined;\n }\n const selection = viewState.get(Selection.aspect, Obj.getURI(companionTo));\n return getSelectionContext({ object: companionTo, selection, resolvers });\n }, [companionTo, viewState, resolvers]);\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { useMemo, useState } from 'react';\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport { type Space } from '@dxos/react-client/echo';\nimport * as UiHooks from '@dxos/react-ui/Hooks';\n\nimport { meta } from '#meta';\nimport { AssistantCapabilities, AssistantOperation } from '#types';\n\nconst FALLBACK_SUGGESTION_KEYS = [\n 'space-home.suggestion-magazine.label',\n 'space-home.suggestion-kanban.label',\n] as const;\n\n/**\n * Returns starter prompts for the space Home page: the space's cached prompts at once, then the\n * operation's answer once it settles (generated prompts, or the hardcoded defaults on an empty result\n * or error). Undefined while nothing is cached and the request is in flight.\n */\nexport const useHomeSuggestions = (space?: Space): readonly string[] | undefined => {\n const { t } = UiHooks.useTranslation(meta.profile.key);\n const { invokePromise } = Hooks.useOperationInvoker();\n const cache = Hooks.useOptionalAtomCapability(AssistantCapabilities.HomeSuggestionsCache);\n const fallbacks = useMemo(() => FALLBACK_SUGGESTION_KEYS.map((key) => t(key)), [t]);\n const [settled, setSettled] = useState<{ spaceId: string; prompts: readonly string[] }>();\n\n UiHooks.useAsyncEffect(\n async (controller) => {\n if (!space) {\n return;\n }\n const spaceId = space.db.spaceId;\n const result = await invokePromise(AssistantOperation.GenerateHomeSuggestions, {}, { spaceId });\n if (controller.signal.aborted) {\n return;\n }\n const prompts = result.data?.prompts;\n setSettled({ spaceId, prompts: prompts && prompts.length > 0 ? prompts : fallbacks });\n },\n [space, invokePromise],\n );\n\n const spaceId = space?.db.spaceId;\n if (!spaceId) {\n return undefined;\n }\n return settled?.spaceId === spaceId ? settled.prompts : cache?.[spaceId]?.prompts;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { useAtomValue } from '@effect/atom-react/Hooks';\nimport * as Effect from 'effect/Effect';\nimport * as Fiber from 'effect/Fiber';\nimport * as Atom from 'effect/reactivity/Atom';\nimport * as Stream from 'effect/Stream';\nimport { useEffect, useMemo, useRef, useState } from 'react';\n\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport { ProcessManager } from '@dxos/compute-runtime';\nimport * as Process from '@dxos/compute/Process';\nimport * as ServiceResolver from '@dxos/compute/ServiceResolver';\nimport type * as Trace from '@dxos/compute/Trace';\nimport { type Space } from '@dxos/react-client/echo';\nimport { resolveEphemeralStatusUpdate } from '@dxos/react-ui-trace';\n\nconst atomEmpty = Atom.make(() => [] as const);\n\nconst ACTIVE_PROCESS_STATES = new Set<Process.State>([Process.State.RUNNING, Process.State.HYBERNATING]);\n\n/** Durable trace lines that represent finished work, not in-flight status. */\nexport const isTerminalActivityLine = (line: string): boolean =>\n line.endsWith(' - Success') || line.endsWith(' - Error') || line === 'Agent completed request';\n\nconst collectDescendantPids = (processes: readonly Process.Process[], rootPid: string): Set<string> => {\n const pids = new Set([rootPid]);\n let expanded = true;\n while (expanded) {\n expanded = false;\n for (const process of processes) {\n const pid = String(process.pid);\n const parentPid = process.parentPid ? String(process.parentPid) : undefined;\n if (parentPid && pids.has(parentPid) && !pids.has(pid)) {\n pids.add(pid);\n expanded = true;\n }\n }\n }\n return pids;\n};\n\nconst resolveSubscribePids = (agentPid: Process.ID, processes: readonly Process.Process[]): Process.ID[] => {\n const rootPid = String(agentPid);\n const descendants = collectDescendantPids(processes, rootPid);\n const activePids = processes\n .filter((process) => descendants.has(String(process.pid)) && ACTIVE_PROCESS_STATES.has(process.state))\n .map((process) => process.pid);\n\n if (activePids.length > 0) {\n return activePids;\n }\n\n return [agentPid];\n};\n\nconst attachActiveHandle = (\n processManager: ProcessManager.Manager,\n pid: Process.ID,\n): Effect.Effect<Process.Process<any, any, never> | undefined> =>\n Effect.gen(function* () {\n const maxAttempts = 15;\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const handle = yield* processManager.attach(pid).pipe(Effect.catch(() => Effect.succeed(undefined)));\n if (handle && ACTIVE_PROCESS_STATES.has(handle.status.state)) {\n return handle;\n }\n if (handle) {\n return undefined;\n }\n yield* Effect.sleep(100);\n }\n return undefined;\n });\n\n/**\n * Subscribes to ephemeral trace events for a delegated sub-agent process subtree\n * and surfaces the latest pending text or tool-call block as a status line.\n */\nexport const useProcessEphemeralStatus = (\n agentPid: Process.ID | undefined,\n space: Space | undefined,\n): string | undefined => {\n // Optional capabilities: the live status is a progressive enhancement, so the component still\n // renders (e.g. in standalone stories) when there is no plugin manager / process runtime.\n const runtime = Hooks.useOptionalCapability(Capabilities.ProcessManagerRuntime);\n const monitor = Hooks.useOptionalCapability(Capabilities.ProcessManager);\n const processes = useAtomValue(monitor?.processTreeAtom ?? atomEmpty);\n const [status, setStatus] = useState<string | undefined>();\n const fibersRef = useRef<Fiber.Fiber<void, unknown>[]>([]);\n\n const subscribePidsKey = useMemo(() => {\n if (!agentPid) {\n return '';\n }\n return resolveSubscribePids(agentPid, processes)\n .map((pid) => String(pid))\n .sort()\n .join('|');\n }, [agentPid, processes]);\n\n useEffect(() => {\n if (!agentPid || !space?.id || !runtime || !subscribePidsKey) {\n setStatus(undefined);\n return;\n }\n\n const pids = subscribePidsKey.split('|').map((pid) => Process.ID.make(pid));\n let disposed = false;\n let replaying = true;\n let replayStatus: string | undefined;\n const endReplay = () => {\n replaying = false;\n if (!disposed) {\n setStatus(replayStatus);\n }\n };\n queueMicrotask(endReplay);\n fibersRef.current = [];\n\n const handleEphemeralMessage = (message: Trace.Message) => {\n const update = resolveEphemeralStatusUpdate(message);\n if (update === 'unchanged') {\n return;\n }\n\n if (replaying) {\n replayStatus = update.line;\n return;\n }\n setStatus(update.line);\n };\n\n const layer = ServiceResolver.provide({ space: space.id }, ProcessManager.ProcessManagerService);\n\n const subscribe = (pid: Process.ID) =>\n Effect.gen(function* () {\n // `attachActiveHandle` polls, so a teardown can land mid-resolve; bail before forking a\n // daemon that the cleanup pass below would never see (and thus never interrupt).\n if (disposed) {\n return;\n }\n const processManager = yield* ProcessManager.ProcessManagerService;\n const handle = yield* attachActiveHandle(processManager, pid);\n if (!handle || disposed) {\n return;\n }\n\n // `forkDaemon` keeps the stream fiber alive after `runPromise(forEach)` returns;\n // scoped `fork` is interrupted when the subscribe effect's parent scope closes.\n const fiber = yield* handle.subscribeEphemeral().pipe(\n Stream.runForEach((message) =>\n Effect.sync(() => {\n if (disposed) {\n return;\n }\n handleEphemeralMessage(message);\n }),\n ),\n Effect.forkDetach,\n );\n if (disposed) {\n yield* Fiber.interrupt(fiber);\n return;\n }\n fibersRef.current.push(fiber);\n });\n\n void runtime\n .runPromise(\n Effect.forEach(pids, subscribe, { concurrency: 'unbounded', discard: true }).pipe(Effect.provide(layer)),\n )\n .catch(() => {\n if (!disposed) {\n setStatus(undefined);\n }\n });\n\n return () => {\n disposed = true;\n const fibers = fibersRef.current;\n fibersRef.current = [];\n for (const fiber of fibers) {\n void runtime.runPromise(Fiber.interrupt(fiber).pipe(Effect.provide(layer)));\n }\n };\n }, [agentPid, runtime, space?.id, subscribePidsKey]);\n\n return status;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport { useAtomValue } from '@effect/atom-react/Hooks';\nimport * as Duration from 'effect/Duration';\nimport * as Atom from 'effect/reactivity/Atom';\nimport { useMemo } from 'react';\n\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport * as Chat from '@dxos/assistant/Chat';\nimport type * as Process from '@dxos/compute/Process';\nimport { Obj } from '@dxos/echo';\nimport { type Space } from '@dxos/react-client/echo';\nimport {\n type Session,\n type SessionTimeline,\n useSessionTimeline as useNaturalSessionTimeline,\n} from '@dxos/react-ui-trace';\nimport { Task } from '@dxos/types';\n\nconst atomEmpty = Atom.make(() => [] as const as readonly Process.Process[]);\n\n/** A chat as the timeline's session: its uri is the agent process's target, its feed the trace meta's. */\nexport const sessionFromChat = (chat: Chat.Chat): Session => ({\n id: chat.id,\n label: chat.name,\n uri: Obj.getURI(chat),\n feedId: Chat.feedEntityId(chat),\n taskIds: chat.tasks.map((ref) => Task.refEntityId(ref)).filter((id): id is string => id !== undefined),\n});\n\n/** What a session is drawn from, as a comparable string. */\nconst sessionKey = (chat: Chat.Chat): string =>\n `${chat.id}:${chat.name ?? ''}:${chat.tasks.map((ref) => Task.refEntityId(ref)).join(',')}`;\n\nexport type UseSessionTimelineOptions = {\n /** The chats whose sessions are shown; each contributes a session lane and its checklist's task lanes. */\n chats: readonly Chat.Chat[];\n tasks?: readonly Task.Task[];\n};\n\n/**\n * The live session timeline of the given chats, with the app's process monitor joined in.\n */\nexport const useSessionTimeline = (\n space: Space | undefined,\n { chats, tasks }: UseSessionTimelineOptions,\n): SessionTimeline => {\n const monitor = Hooks.useOptionalCapability(Capabilities.ProcessManager);\n const processes = useAtomValue(\n useMemo(() => monitor?.processTreeAtom.pipe(Atom.debounce(Duration.millis(500))) ?? atomEmpty, [monitor]),\n );\n // Keyed on the checklists as well as the chats: an agent assigning itself a task edits a chat in\n // place, and a session missing that task would draw it as a lane of its own, outside its band.\n const checklists = chats.map(sessionKey).join('|');\n const sessions = useMemo(() => chats.map(sessionFromChat), [chats, checklists]);\n return useNaturalSessionTimeline(space, { sessions, tasks, processes });\n};\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { AssistantOperation } from "#types";
2
2
  import * as Operation from "@dxos/compute/Operation";
3
+ import { TurnReviewSkill } from "#skills";
3
4
  import * as OperationHandlerSet from "@dxos/compute/OperationHandlerSet";
4
5
  import * as RoutineOperation from "@dxos/plugin-routine/RoutineOperation";
5
6
  //#region src/operations/index.ts
@@ -15,7 +16,8 @@ var AssistantOperationHandlerSet = OperationHandlerSet.lazy([
15
16
  RoutineOperation.RunPromptInNewChat.pipe(Operation.lazyHandler(() => import("./chunk-run-prompt-in-new-chat.mjs"))),
16
17
  AssistantOperation.SetCurrentChat.pipe(Operation.lazyHandler(() => import("./chunk-set-current-chat.mjs"))),
17
18
  AssistantOperation.SetTracePanelDebug.pipe(Operation.lazyHandler(() => import("./chunk-set-trace-panel-debug.mjs"))),
18
- AssistantOperation.UpdateChatName.pipe(Operation.lazyHandler(() => import("./chunk-update-chat-name.mjs")))
19
+ AssistantOperation.UpdateChatName.pipe(Operation.lazyHandler(() => import("./chunk-update-chat-name.mjs"))),
20
+ TurnReviewSkill.AnalyzeTurn.pipe(Operation.lazyHandler(() => import("./chunk-analyze-turn.mjs")))
19
21
  ]);
20
22
  //#endregion
21
23
  export { AssistantOperationHandlerSet };
@@ -1 +1 @@
1
- {"version":3,"file":"operations.mjs","names":[],"sources":["../../src/operations/index.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Operation from '@dxos/compute/Operation';\nimport * as OperationHandlerSet from '@dxos/compute/OperationHandlerSet';\nimport * as RoutineOperation from '@dxos/plugin-routine/RoutineOperation';\n\nimport { AssistantOperation } from '#types';\n\nexport const AssistantOperationHandlerSet = OperationHandlerSet.lazy([\n AssistantOperation.AnswerQuestion.pipe(Operation.lazyHandler(() => import('./answer-question.ts'))),\n AssistantOperation.BindChatContext.pipe(Operation.lazyHandler(() => import('./bind-chat-context.ts'))),\n AssistantOperation.CreateChat.pipe(Operation.lazyHandler(() => import('./create-chat.ts'))),\n AssistantOperation.EnsureCompanionChat.pipe(Operation.lazyHandler(() => import('./ensure-companion-chat.ts'))),\n AssistantOperation.ForkChat.pipe(Operation.lazyHandler(() => import('./fork-chat.ts'))),\n AssistantOperation.GenerateHomeSuggestions.pipe(\n Operation.lazyHandler(() => import('./generate-home-suggestions.ts')),\n ),\n AssistantOperation.RespondToRequest.pipe(Operation.lazyHandler(() => import('./respond-to-request.ts'))),\n AssistantOperation.RunPromptInChat.pipe(Operation.lazyHandler(() => import('./run-prompt-in-chat.ts'))),\n RoutineOperation.RunPromptInNewChat.pipe(Operation.lazyHandler(() => import('./run-prompt-in-new-chat.ts'))),\n AssistantOperation.SetCurrentChat.pipe(Operation.lazyHandler(() => import('./set-current-chat.ts'))),\n AssistantOperation.SetTracePanelDebug.pipe(Operation.lazyHandler(() => import('./set-trace-panel-debug.ts'))),\n AssistantOperation.UpdateChatName.pipe(Operation.lazyHandler(() => import('./update-chat-name.ts'))),\n]);\n"],"mappings":";;;;;AAUA,IAAa,+BAA+B,oBAAoB,KAAK;CACnE,mBAAmB,eAAe,KAAK,UAAU,kBAAkB,OAAO,8BAAuB,CAAC;CAClG,mBAAmB,gBAAgB,KAAK,UAAU,kBAAkB,OAAO,gCAAyB,CAAC;CACrG,mBAAmB,WAAW,KAAK,UAAU,kBAAkB,OAAO,0BAAmB,CAAC;CAC1F,mBAAmB,oBAAoB,KAAK,UAAU,kBAAkB,OAAO,oCAA6B,CAAC;CAC7G,mBAAmB,SAAS,KAAK,UAAU,kBAAkB,OAAO,wBAAiB,CAAC;CACtF,mBAAmB,wBAAwB,KACzC,UAAU,kBAAkB,OAAO,wCAAiC,CACtE;CACA,mBAAmB,iBAAiB,KAAK,UAAU,kBAAkB,OAAO,iCAA0B,CAAC;CACvG,mBAAmB,gBAAgB,KAAK,UAAU,kBAAkB,OAAO,iCAA0B,CAAC;CACtG,iBAAiB,mBAAmB,KAAK,UAAU,kBAAkB,OAAO,qCAA8B,CAAC;CAC3G,mBAAmB,eAAe,KAAK,UAAU,kBAAkB,OAAO,+BAAwB,CAAC;CACnG,mBAAmB,mBAAmB,KAAK,UAAU,kBAAkB,OAAO,oCAA6B,CAAC;CAC5G,mBAAmB,eAAe,KAAK,UAAU,kBAAkB,OAAO,+BAAwB,CAAC;AACrG,CAAC"}
1
+ {"version":3,"file":"operations.mjs","names":[],"sources":["../../src/operations/index.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Operation from '@dxos/compute/Operation';\nimport * as OperationHandlerSet from '@dxos/compute/OperationHandlerSet';\nimport * as RoutineOperation from '@dxos/plugin-routine/RoutineOperation';\n\nimport { TurnReviewSkill } from '#skills';\nimport { AssistantOperation } from '#types';\n\nexport const AssistantOperationHandlerSet = OperationHandlerSet.lazy([\n AssistantOperation.AnswerQuestion.pipe(Operation.lazyHandler(() => import('./answer-question.ts'))),\n AssistantOperation.BindChatContext.pipe(Operation.lazyHandler(() => import('./bind-chat-context.ts'))),\n AssistantOperation.CreateChat.pipe(Operation.lazyHandler(() => import('./create-chat.ts'))),\n AssistantOperation.EnsureCompanionChat.pipe(Operation.lazyHandler(() => import('./ensure-companion-chat.ts'))),\n AssistantOperation.ForkChat.pipe(Operation.lazyHandler(() => import('./fork-chat.ts'))),\n AssistantOperation.GenerateHomeSuggestions.pipe(\n Operation.lazyHandler(() => import('./generate-home-suggestions.ts')),\n ),\n AssistantOperation.RespondToRequest.pipe(Operation.lazyHandler(() => import('./respond-to-request.ts'))),\n AssistantOperation.RunPromptInChat.pipe(Operation.lazyHandler(() => import('./run-prompt-in-chat.ts'))),\n RoutineOperation.RunPromptInNewChat.pipe(Operation.lazyHandler(() => import('./run-prompt-in-new-chat.ts'))),\n AssistantOperation.SetCurrentChat.pipe(Operation.lazyHandler(() => import('./set-current-chat.ts'))),\n AssistantOperation.SetTracePanelDebug.pipe(Operation.lazyHandler(() => import('./set-trace-panel-debug.ts'))),\n AssistantOperation.UpdateChatName.pipe(Operation.lazyHandler(() => import('./update-chat-name.ts'))),\n TurnReviewSkill.AnalyzeTurn.pipe(Operation.lazyHandler(() => import('./analyze-turn.ts'))),\n]);\n"],"mappings":";;;;;;AAWA,IAAa,+BAA+B,oBAAoB,KAAK;CACnE,mBAAmB,eAAe,KAAK,UAAU,kBAAkB,OAAO,8BAAuB,CAAC;CAClG,mBAAmB,gBAAgB,KAAK,UAAU,kBAAkB,OAAO,gCAAyB,CAAC;CACrG,mBAAmB,WAAW,KAAK,UAAU,kBAAkB,OAAO,0BAAmB,CAAC;CAC1F,mBAAmB,oBAAoB,KAAK,UAAU,kBAAkB,OAAO,oCAA6B,CAAC;CAC7G,mBAAmB,SAAS,KAAK,UAAU,kBAAkB,OAAO,wBAAiB,CAAC;CACtF,mBAAmB,wBAAwB,KACzC,UAAU,kBAAkB,OAAO,wCAAiC,CACtE;CACA,mBAAmB,iBAAiB,KAAK,UAAU,kBAAkB,OAAO,iCAA0B,CAAC;CACvG,mBAAmB,gBAAgB,KAAK,UAAU,kBAAkB,OAAO,iCAA0B,CAAC;CACtG,iBAAiB,mBAAmB,KAAK,UAAU,kBAAkB,OAAO,qCAA8B,CAAC;CAC3G,mBAAmB,eAAe,KAAK,UAAU,kBAAkB,OAAO,+BAAwB,CAAC;CACnG,mBAAmB,mBAAmB,KAAK,UAAU,kBAAkB,OAAO,oCAA6B,CAAC;CAC5G,mBAAmB,eAAe,KAAK,UAAU,kBAAkB,OAAO,+BAAwB,CAAC;CACnG,gBAAgB,YAAY,KAAK,UAAU,kBAAkB,OAAO,2BAAoB,CAAC;AAC3F,CAAC"}
@@ -1,3 +1,4 @@
1
1
  import { t as AssistantSkill_exports } from "./AssistantSkill.mjs";
2
2
  import { t as PluginManagerSkill_exports } from "./PluginManagerSkill.mjs";
3
- export { AssistantSkill_exports as AssistantSkill, PluginManagerSkill_exports as PluginManagerSkill };
3
+ import { t as TurnReviewSkill_exports } from "./TurnReviewSkill.mjs";
4
+ export { AssistantSkill_exports as AssistantSkill, PluginManagerSkill_exports as PluginManagerSkill, TurnReviewSkill_exports as TurnReviewSkill };
@@ -1,10 +1,10 @@
1
1
  import { meta } from "#meta";
2
2
  import * as Chat from "@dxos/assistant/Chat";
3
3
  import { Type } from "@dxos/echo";
4
- import * as McpServer from "@dxos/compute/McpServer";
4
+ import * as Agent from "@dxos/assistant/Agent";
5
5
  import * as Skill from "@dxos/compute/Skill";
6
+ import * as McpServer from "@dxos/compute/McpServer";
6
7
  import { Sequence } from "@dxos/conductor";
7
- import * as Agent from "@dxos/assistant/Agent";
8
8
  import * as Instructions from "@dxos/compute/Instructions";
9
9
  import { translations as translations$1 } from "@dxos/react-ui-assistant/translations";
10
10
  import { translations as translations$2 } from "@dxos/react-ui-components/translations";
@@ -172,6 +172,8 @@ var translations = [
172
172
  "options.mcp.title": "MCP",
173
173
  "options.chat-model.title": "Models",
174
174
  "options.environment.title": "Environment",
175
+ "options.agent.title": "Agent",
176
+ "agent-locked.message": "The agent is chosen before the first message. Start a new chat to use another.",
175
177
  "remove-object.label": "Remove object",
176
178
  "chat-view.title": "View",
177
179
  "chat-view.normal.label": "Normal",
@@ -1 +1 @@
1
- {"version":3,"file":"translations.mjs","names":[],"sources":["../../src/translations.ts"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport * as Agent from '@dxos/assistant/Agent';\nimport * as Chat from '@dxos/assistant/Chat';\nimport * as Instructions from '@dxos/compute/Instructions';\nimport * as McpServer from '@dxos/compute/McpServer';\nimport * as Skill from '@dxos/compute/Skill';\nimport { Sequence } from '@dxos/conductor';\nimport { Type } from '@dxos/echo';\nimport { translations as assistantTranslations } from '@dxos/react-ui-assistant/translations';\nimport { translations as componentsTranslations } from '@dxos/react-ui-components/translations';\nimport { translations as formTranslations } from '@dxos/react-ui-form/translations';\nimport { translations as taskTranslations } from '@dxos/react-ui-task/translations';\nimport { translations as traceTranslations } from '@dxos/react-ui-trace/translations';\nimport type * as Theme from '@dxos/react-ui/Theme';\n\nimport { meta } from '#meta';\n\nexport const translations: Theme.Resource[] = [\n ...assistantTranslations,\n ...componentsTranslations,\n ...formTranslations,\n ...taskTranslations,\n ...traceTranslations,\n {\n 'en-US': {\n [Type.getTypename(Skill.Skill)]: {\n 'typename.label': 'Skill',\n 'typename.label_zero': 'Skills',\n 'typename.label_one': 'Skill',\n 'typename.label_other': 'Skills',\n 'object-name.placeholder': 'New skill',\n 'add-object.label': 'Add skill',\n 'rename-object.label': 'Rename skill',\n 'delete-object.label': 'Delete skill',\n 'object-deleted.label': 'Skill deleted',\n },\n [Type.getTypename(Instructions.Instructions)]: {\n 'typename.label': 'Instructions',\n 'typename.label_zero': 'Instructions',\n 'typename.label_one': 'Instructions',\n 'typename.label_other': 'Instructions',\n 'object-name.placeholder': 'New instructions',\n 'add-object.label': 'Add instructions',\n 'rename-object.label': 'Rename instructions',\n 'delete-object.label': 'Delete instructions',\n 'object-deleted.label': 'Instructions deleted',\n },\n [Type.getTypename(Sequence.Sequence)]: {\n 'typename.label': 'Sequence',\n 'typename.label_zero': 'Sequences',\n 'typename.label_one': 'Sequence',\n 'typename.label_other': 'Sequences',\n 'object-name.placeholder': 'New sequence',\n 'add-object.label': 'Add sequence',\n 'rename-object.label': 'Rename sequence',\n 'delete-object.label': 'Delete sequence',\n 'object-deleted.label': 'Sequence deleted',\n },\n [Type.getTypename(Chat.Chat)]: {\n 'typename.label': 'Session',\n 'typename.label_zero': 'Sessions',\n 'typename.label_one': 'Session',\n 'typename.label_other': 'Sessions',\n 'object-name.placeholder': 'New session',\n 'add-object.label': 'Add Session',\n 'rename-object.label': 'Rename session',\n 'delete-object.label': 'Delete session',\n 'object-deleted.label': 'Session deleted',\n },\n [Type.getTypename(McpServer.McpServer)]: {\n 'typename.label': 'MCP Server',\n 'typename.label_zero': 'MCP Servers',\n 'typename.label_one': 'MCP Server',\n 'typename.label_other': 'MCP Servers',\n },\n [Type.getTypename(Agent.Agent)]: {\n 'typename.label': 'Agent',\n 'typename.label_zero': 'Agents',\n 'typename.label_one': 'Agent',\n 'typename.label_other': 'Agents',\n 'object-name.placeholder': 'New agent',\n 'add-object.label': 'Add agent',\n 'rename-object.label': 'Rename agent',\n 'delete-object.label': 'Delete agent',\n 'object-deleted.label': 'Agent deleted',\n },\n // TODO(burdon): Reconcile with react-ui-chat.\n [meta.profile.key]: {\n 'delete-task.label': 'Delete task',\n 'execute-task.label': 'Execute task',\n 'execute-task.prompt': 'Implement task #{{ordinal}}',\n 'templates.label': 'Templates',\n 'open-ambient-chat.label': 'Open Assistant',\n 'assistant-chat.label': 'Assistant',\n 'plugin.name': 'Assistant',\n 'object.placeholder': 'New prompt',\n 'create-object.label': 'Create prompt',\n 'create-trigger.label': 'Create trigger',\n 'create-stack-section.label': 'Create prompt',\n 'value.placeholder': 'Enter value...',\n 'prompt-rules.label': 'Prompt Rules',\n 'typename.placeholder': 'Enter typename of objects which this template is for',\n 'description.placeholder': 'Enter description of when this template should be used',\n 'select-preset-template.placeholder': 'Select preset',\n 'service-registry.label': 'Service Registry',\n 'type-filter.placeholder': 'Type',\n 'any-type-filter.label': 'Any',\n 'no-skill.message': 'No active skills',\n 'tool-call.label': 'Calling',\n 'tool-result.label': 'Success',\n 'tool-error.label': 'Tool call failed',\n\n 'invocations.label': 'Invocations',\n 'trace.label': 'Trace',\n\n 'activity.starting.label': 'Starting agent',\n 'activity.preparing.label': 'Preparing request',\n 'activity.loading-history.label': 'Loading conversation',\n 'activity.summarizing.label': 'Summarizing conversation',\n 'activity.connecting-mcp.label': 'Connecting to MCP servers',\n 'activity.building-toolkit.label': 'Assembling tools',\n 'activity.encoding-prompt.label': 'Encoding prompt',\n 'activity.contacting-provider.label': 'Contacting inference provider',\n 'activity.generating.label': 'Generating',\n 'activity.calling-tool.label': 'Calling tool {{detail}}',\n 'activity.waking.seconds.label_one': 'Waking up in {{count}} second',\n 'activity.waking.seconds.label_other': 'Waking up in {{count}} seconds',\n 'activity.waking.minutes.label_one': 'Waking up in {{count}} minute',\n 'activity.waking.minutes.label_other': 'Waking up in {{count}} minutes',\n 'activity.waking.hours.label_one': 'Waking up in {{count}} hour',\n 'activity.waking.hours.label_other': 'Waking up in {{count}} hours',\n 'activity.sleeping.label': 'Waiting to wake',\n 'activity.attempt': 'attempt {{attempt}}',\n\n 'assistant-dialog.title': 'Assistant',\n 'open-assistant.label': 'Open assistant',\n 'import-compute-operations.label': 'Import compute operations',\n 'set-trace-panel-debug.label': 'Toggle trace panel debug view',\n\n 'no-results.message': 'No results',\n\n 'cancel-queued.button': 'Remove from queue',\n 'new-thread.button': 'New Chat',\n 'rename-thread.button': 'Rename Chat',\n 'chat-history.label': 'Chat History',\n 'chat-update-name.label': 'Update AI Chat name',\n 'create-chat.label': 'New AI Chat',\n\n 'toolkit.label': 'Toolkit',\n 'stats.label': 'Stats',\n 'summary.label': 'Summary',\n 'rewind.label': 'Rewind to here',\n 'thinking.label': 'Thinking',\n\n 'connect.label': 'Connect',\n 'integration-prompt.title': 'Connect {{service}}',\n 'integration-prompt.description': 'This action needs access to {{service}}. Connect it to continue.',\n 'integration-prompt.unavailable': 'No connector is available for {{service}}.',\n 'integration-prompt.scopes': 'Permissions needed:',\n\n 'question-actions.label': 'Question actions',\n 'question-failed.message': 'That answer could not be saved. Try again.',\n 'question-stranded.message': 'Answer saved, but the assistant could not be resumed.',\n\n 'plugin-prompt.title': 'Enable {{plugin}}',\n 'plugin-prompt.description': 'This action needs the {{plugin}} plugin. Enable it to continue.',\n 'plugin-prompt.enabled': '{{plugin}} is enabled.',\n 'plugin-prompt.unavailable': '{{plugin}} is not installed on this device.',\n 'plugin-prompt.failed': 'Could not enable {{plugin}}. Try again from the plugin registry.',\n 'plugin-prompt.button': 'Enable',\n 'plugin-url-prompt.title': 'Load {{plugin}}',\n 'plugin-url-prompt.default.name': 'plugin',\n 'plugin-url-prompt.description':\n 'Load {{plugin}} from this URL, then enable it in Plugins. It runs inside the app, so load only code you trust.',\n 'plugin-url-prompt.loaded': '{{plugin}} is loaded. Enable it in Plugins.',\n 'plugin-url-prompt.failed': 'Could not load the plugin: {{error}}',\n 'plugin-url-prompt.button': 'Load plugin',\n\n 'search.placeholder': 'Search...',\n 'prompt.placeholder': 'Enter question or command...',\n 'context-objects.button': 'Add to context',\n 'context-settings.button': 'Chat settings',\n 'send.label': 'Send',\n 'cancel-processing.button': 'Stop processing',\n 'show-tasks.button': 'Show tasks',\n 'hide-tasks.button': 'Hide tasks',\n\n 'options.skills.title': 'Skills',\n 'options.mcp.title': 'MCP',\n 'options.chat-model.title': 'Models',\n 'options.environment.title': 'Environment',\n 'remove-object.label': 'Remove object',\n\n 'chat-view.title': 'View',\n 'chat-view.normal.label': 'Normal',\n 'chat-view.summary.label': 'Summary',\n 'chat-view.thinking.label': 'Thinking',\n 'chat-view.debug.label': 'Debug',\n 'chat-environment.local.label': 'Local',\n 'chat-environment.remote.label': 'EDGE',\n 'mcp-server-add.label': 'Add MCP server',\n 'mcp-server-remove.label': 'Remove MCP server',\n 'mcp-server-name.label': 'Server name',\n 'mcp-server-name.placeholder': 'Name',\n 'mcp-server-url.label': 'Server URL',\n 'mcp-server-url.placeholder': 'https://...',\n 'mcp-server-protocol.label': 'Protocol',\n 'mcp-server-api-key.label': 'API key',\n 'mcp-server-api-key.placeholder': 'API key (optional)',\n 'mcp-server-status.checking': 'Connecting…',\n 'mcp-server-status.connected_one': '{{count}} tool',\n 'mcp-server-status.connected_other': '{{count}} tools',\n 'mcp-server-status.unauthorized': 'Sign-in required',\n 'mcp-server-status.disabled': 'Disabled',\n 'mcp-server-sign-in.label': 'Sign in',\n 'mcp-server-retry.label': 'Retry connection',\n 'mcp-server-error.label': 'MCP server unavailable',\n 'mcp-server-error.unauthorized': 'Sign-in required — sign in from the MCP tab of the chat options.',\n 'ai-service-error.label': 'AI service error',\n 'view-usage.label': 'View usage',\n\n // LLM provider labels.\n 'settings.provider.edge.label': 'Edge',\n 'settings.provider.built-in.label': 'Built-in',\n 'settings.provider.ollama.label': 'Ollama',\n 'settings.provider.lmstudio.label': 'LM Studio',\n\n // Ollama local model management (desktop only).\n 'settings.ollama.title': 'Local models',\n 'settings.ollama.installed.label': 'Downloaded models',\n 'settings.ollama.empty.message': 'No models downloaded. Pull one below to get started.',\n 'settings.ollama.pull.label': 'Pull model',\n 'settings.ollama.pull.placeholder': 'Search or enter a model name (e.g. llama3.2:1b)',\n 'settings.ollama.pull-custom.label': 'Pull “{{name}}”',\n 'settings.ollama.pulling.label': 'Pulling…',\n 'settings.ollama.pulling.message': 'Downloading… {{percent}}%',\n 'settings.ollama.cancel.label': 'Cancel download',\n 'settings.ollama.loaded.label': 'Loaded',\n 'settings.ollama.loaded.vram': 'Loaded · {{size}}',\n 'settings.ollama.load.label': 'Load into memory',\n 'settings.ollama.unload.label': 'Unload from memory',\n 'settings.ollama.remove.label': 'Delete model',\n 'settings.ollama.failed.message': 'Could not reach the local model service: {{error}}',\n\n 'debug.button': 'Debug',\n 'online-switch.label': 'Online',\n 'model-unavailable.label': '{{label}} (unavailable)',\n 'typename.label': 'Typename',\n 'branch-thread.menu': 'Branch chat',\n 'chat-toolbar.title': 'Chat toolbar',\n\n // Trigger status\n 'trigger-status-disabled.label': 'Triggers disabled',\n 'trigger-status-idle.label': 'Triggers idle',\n 'trigger-status-running.label': 'Trigger running',\n 'trigger-status-error.label': 'Trigger error',\n 'trigger-runtime.label': 'Auto trigger execution',\n 'trigger-last-invocation.label': 'Last run',\n 'trigger-duration.label': 'Duration',\n\n // AgentArticle.\n 'project-empty-spec.message': 'Open the Properties companion to configure the agent.',\n 'project-empty-spec.description': 'Open the Assistant companion to interact with the agent.',\n 'artifacts.label': 'Artifacts',\n 'inputs.label': 'Inputs',\n\n // AgentProperties.\n 'instructions.label': 'Instructions',\n 'instructions.placeholder': 'Enter instructions, goals, and constraints for the assistant.',\n 'reset-history.button': 'Reset',\n 'subscriptions.label': 'Subscriptions',\n\n // Per-space Home article: starter-prompt cards + the pinned assistant prompt.\n 'space-home.suggestions.heading': 'Get started',\n 'space-home.suggestion-magazine.label': 'Create feeds for tracking the latest AI news and build a magazine',\n 'space-home.suggestion-kanban.label': 'Create a kanban view for tracking tasks',\n 'space-home.prompt.placeholder': 'Ask the assistant anything…',\n\n 'nav-tree-group-ai.label': 'Assistant',\n },\n },\n },\n];\n"],"mappings":"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"}
1
+ {"version":3,"file":"translations.mjs","names":[],"sources":["../../src/translations.ts"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport * as Agent from '@dxos/assistant/Agent';\nimport * as Chat from '@dxos/assistant/Chat';\nimport * as Instructions from '@dxos/compute/Instructions';\nimport * as McpServer from '@dxos/compute/McpServer';\nimport * as Skill from '@dxos/compute/Skill';\nimport { Sequence } from '@dxos/conductor';\nimport { Type } from '@dxos/echo';\nimport { translations as assistantTranslations } from '@dxos/react-ui-assistant/translations';\nimport { translations as componentsTranslations } from '@dxos/react-ui-components/translations';\nimport { translations as formTranslations } from '@dxos/react-ui-form/translations';\nimport { translations as taskTranslations } from '@dxos/react-ui-task/translations';\nimport { translations as traceTranslations } from '@dxos/react-ui-trace/translations';\nimport type * as Theme from '@dxos/react-ui/Theme';\n\nimport { meta } from '#meta';\n\nexport const translations: Theme.Resource[] = [\n ...assistantTranslations,\n ...componentsTranslations,\n ...formTranslations,\n ...taskTranslations,\n ...traceTranslations,\n {\n 'en-US': {\n [Type.getTypename(Skill.Skill)]: {\n 'typename.label': 'Skill',\n 'typename.label_zero': 'Skills',\n 'typename.label_one': 'Skill',\n 'typename.label_other': 'Skills',\n 'object-name.placeholder': 'New skill',\n 'add-object.label': 'Add skill',\n 'rename-object.label': 'Rename skill',\n 'delete-object.label': 'Delete skill',\n 'object-deleted.label': 'Skill deleted',\n },\n [Type.getTypename(Instructions.Instructions)]: {\n 'typename.label': 'Instructions',\n 'typename.label_zero': 'Instructions',\n 'typename.label_one': 'Instructions',\n 'typename.label_other': 'Instructions',\n 'object-name.placeholder': 'New instructions',\n 'add-object.label': 'Add instructions',\n 'rename-object.label': 'Rename instructions',\n 'delete-object.label': 'Delete instructions',\n 'object-deleted.label': 'Instructions deleted',\n },\n [Type.getTypename(Sequence.Sequence)]: {\n 'typename.label': 'Sequence',\n 'typename.label_zero': 'Sequences',\n 'typename.label_one': 'Sequence',\n 'typename.label_other': 'Sequences',\n 'object-name.placeholder': 'New sequence',\n 'add-object.label': 'Add sequence',\n 'rename-object.label': 'Rename sequence',\n 'delete-object.label': 'Delete sequence',\n 'object-deleted.label': 'Sequence deleted',\n },\n [Type.getTypename(Chat.Chat)]: {\n 'typename.label': 'Session',\n 'typename.label_zero': 'Sessions',\n 'typename.label_one': 'Session',\n 'typename.label_other': 'Sessions',\n 'object-name.placeholder': 'New session',\n 'add-object.label': 'Add Session',\n 'rename-object.label': 'Rename session',\n 'delete-object.label': 'Delete session',\n 'object-deleted.label': 'Session deleted',\n },\n [Type.getTypename(McpServer.McpServer)]: {\n 'typename.label': 'MCP Server',\n 'typename.label_zero': 'MCP Servers',\n 'typename.label_one': 'MCP Server',\n 'typename.label_other': 'MCP Servers',\n },\n [Type.getTypename(Agent.Agent)]: {\n 'typename.label': 'Agent',\n 'typename.label_zero': 'Agents',\n 'typename.label_one': 'Agent',\n 'typename.label_other': 'Agents',\n 'object-name.placeholder': 'New agent',\n 'add-object.label': 'Add agent',\n 'rename-object.label': 'Rename agent',\n 'delete-object.label': 'Delete agent',\n 'object-deleted.label': 'Agent deleted',\n },\n // TODO(burdon): Reconcile with react-ui-chat.\n [meta.profile.key]: {\n 'delete-task.label': 'Delete task',\n 'execute-task.label': 'Execute task',\n 'execute-task.prompt': 'Implement task #{{ordinal}}',\n 'templates.label': 'Templates',\n 'open-ambient-chat.label': 'Open Assistant',\n 'assistant-chat.label': 'Assistant',\n 'plugin.name': 'Assistant',\n 'object.placeholder': 'New prompt',\n 'create-object.label': 'Create prompt',\n 'create-trigger.label': 'Create trigger',\n 'create-stack-section.label': 'Create prompt',\n 'value.placeholder': 'Enter value...',\n 'prompt-rules.label': 'Prompt Rules',\n 'typename.placeholder': 'Enter typename of objects which this template is for',\n 'description.placeholder': 'Enter description of when this template should be used',\n 'select-preset-template.placeholder': 'Select preset',\n 'service-registry.label': 'Service Registry',\n 'type-filter.placeholder': 'Type',\n 'any-type-filter.label': 'Any',\n 'no-skill.message': 'No active skills',\n 'tool-call.label': 'Calling',\n 'tool-result.label': 'Success',\n 'tool-error.label': 'Tool call failed',\n\n 'invocations.label': 'Invocations',\n 'trace.label': 'Trace',\n\n 'activity.starting.label': 'Starting agent',\n 'activity.preparing.label': 'Preparing request',\n 'activity.loading-history.label': 'Loading conversation',\n 'activity.summarizing.label': 'Summarizing conversation',\n 'activity.connecting-mcp.label': 'Connecting to MCP servers',\n 'activity.building-toolkit.label': 'Assembling tools',\n 'activity.encoding-prompt.label': 'Encoding prompt',\n 'activity.contacting-provider.label': 'Contacting inference provider',\n 'activity.generating.label': 'Generating',\n 'activity.calling-tool.label': 'Calling tool {{detail}}',\n 'activity.waking.seconds.label_one': 'Waking up in {{count}} second',\n 'activity.waking.seconds.label_other': 'Waking up in {{count}} seconds',\n 'activity.waking.minutes.label_one': 'Waking up in {{count}} minute',\n 'activity.waking.minutes.label_other': 'Waking up in {{count}} minutes',\n 'activity.waking.hours.label_one': 'Waking up in {{count}} hour',\n 'activity.waking.hours.label_other': 'Waking up in {{count}} hours',\n 'activity.sleeping.label': 'Waiting to wake',\n 'activity.attempt': 'attempt {{attempt}}',\n\n 'assistant-dialog.title': 'Assistant',\n 'open-assistant.label': 'Open assistant',\n 'import-compute-operations.label': 'Import compute operations',\n 'set-trace-panel-debug.label': 'Toggle trace panel debug view',\n\n 'no-results.message': 'No results',\n\n 'cancel-queued.button': 'Remove from queue',\n 'new-thread.button': 'New Chat',\n 'rename-thread.button': 'Rename Chat',\n 'chat-history.label': 'Chat History',\n 'chat-update-name.label': 'Update AI Chat name',\n 'create-chat.label': 'New AI Chat',\n\n 'toolkit.label': 'Toolkit',\n 'stats.label': 'Stats',\n 'summary.label': 'Summary',\n 'rewind.label': 'Rewind to here',\n 'thinking.label': 'Thinking',\n\n 'connect.label': 'Connect',\n 'integration-prompt.title': 'Connect {{service}}',\n 'integration-prompt.description': 'This action needs access to {{service}}. Connect it to continue.',\n 'integration-prompt.unavailable': 'No connector is available for {{service}}.',\n 'integration-prompt.scopes': 'Permissions needed:',\n\n 'question-actions.label': 'Question actions',\n 'question-failed.message': 'That answer could not be saved. Try again.',\n 'question-stranded.message': 'Answer saved, but the assistant could not be resumed.',\n\n 'plugin-prompt.title': 'Enable {{plugin}}',\n 'plugin-prompt.description': 'This action needs the {{plugin}} plugin. Enable it to continue.',\n 'plugin-prompt.enabled': '{{plugin}} is enabled.',\n 'plugin-prompt.unavailable': '{{plugin}} is not installed on this device.',\n 'plugin-prompt.failed': 'Could not enable {{plugin}}. Try again from the plugin registry.',\n 'plugin-prompt.button': 'Enable',\n 'plugin-url-prompt.title': 'Load {{plugin}}',\n 'plugin-url-prompt.default.name': 'plugin',\n 'plugin-url-prompt.description':\n 'Load {{plugin}} from this URL, then enable it in Plugins. It runs inside the app, so load only code you trust.',\n 'plugin-url-prompt.loaded': '{{plugin}} is loaded. Enable it in Plugins.',\n 'plugin-url-prompt.failed': 'Could not load the plugin: {{error}}',\n 'plugin-url-prompt.button': 'Load plugin',\n\n 'search.placeholder': 'Search...',\n 'prompt.placeholder': 'Enter question or command...',\n 'context-objects.button': 'Add to context',\n 'context-settings.button': 'Chat settings',\n 'send.label': 'Send',\n 'cancel-processing.button': 'Stop processing',\n 'show-tasks.button': 'Show tasks',\n 'hide-tasks.button': 'Hide tasks',\n\n 'options.skills.title': 'Skills',\n 'options.mcp.title': 'MCP',\n 'options.chat-model.title': 'Models',\n 'options.environment.title': 'Environment',\n 'options.agent.title': 'Agent',\n 'agent-locked.message': 'The agent is chosen before the first message. Start a new chat to use another.',\n 'remove-object.label': 'Remove object',\n\n 'chat-view.title': 'View',\n 'chat-view.normal.label': 'Normal',\n 'chat-view.summary.label': 'Summary',\n 'chat-view.thinking.label': 'Thinking',\n 'chat-view.debug.label': 'Debug',\n 'chat-environment.local.label': 'Local',\n 'chat-environment.remote.label': 'EDGE',\n 'mcp-server-add.label': 'Add MCP server',\n 'mcp-server-remove.label': 'Remove MCP server',\n 'mcp-server-name.label': 'Server name',\n 'mcp-server-name.placeholder': 'Name',\n 'mcp-server-url.label': 'Server URL',\n 'mcp-server-url.placeholder': 'https://...',\n 'mcp-server-protocol.label': 'Protocol',\n 'mcp-server-api-key.label': 'API key',\n 'mcp-server-api-key.placeholder': 'API key (optional)',\n 'mcp-server-status.checking': 'Connecting…',\n 'mcp-server-status.connected_one': '{{count}} tool',\n 'mcp-server-status.connected_other': '{{count}} tools',\n 'mcp-server-status.unauthorized': 'Sign-in required',\n 'mcp-server-status.disabled': 'Disabled',\n 'mcp-server-sign-in.label': 'Sign in',\n 'mcp-server-retry.label': 'Retry connection',\n 'mcp-server-error.label': 'MCP server unavailable',\n 'mcp-server-error.unauthorized': 'Sign-in required — sign in from the MCP tab of the chat options.',\n 'ai-service-error.label': 'AI service error',\n 'view-usage.label': 'View usage',\n\n // LLM provider labels.\n 'settings.provider.edge.label': 'Edge',\n 'settings.provider.built-in.label': 'Built-in',\n 'settings.provider.ollama.label': 'Ollama',\n 'settings.provider.lmstudio.label': 'LM Studio',\n\n // Ollama local model management (desktop only).\n 'settings.ollama.title': 'Local models',\n 'settings.ollama.installed.label': 'Downloaded models',\n 'settings.ollama.empty.message': 'No models downloaded. Pull one below to get started.',\n 'settings.ollama.pull.label': 'Pull model',\n 'settings.ollama.pull.placeholder': 'Search or enter a model name (e.g. llama3.2:1b)',\n 'settings.ollama.pull-custom.label': 'Pull “{{name}}”',\n 'settings.ollama.pulling.label': 'Pulling…',\n 'settings.ollama.pulling.message': 'Downloading… {{percent}}%',\n 'settings.ollama.cancel.label': 'Cancel download',\n 'settings.ollama.loaded.label': 'Loaded',\n 'settings.ollama.loaded.vram': 'Loaded · {{size}}',\n 'settings.ollama.load.label': 'Load into memory',\n 'settings.ollama.unload.label': 'Unload from memory',\n 'settings.ollama.remove.label': 'Delete model',\n 'settings.ollama.failed.message': 'Could not reach the local model service: {{error}}',\n\n 'debug.button': 'Debug',\n 'online-switch.label': 'Online',\n 'model-unavailable.label': '{{label}} (unavailable)',\n 'typename.label': 'Typename',\n 'branch-thread.menu': 'Branch chat',\n 'chat-toolbar.title': 'Chat toolbar',\n\n // Trigger status\n 'trigger-status-disabled.label': 'Triggers disabled',\n 'trigger-status-idle.label': 'Triggers idle',\n 'trigger-status-running.label': 'Trigger running',\n 'trigger-status-error.label': 'Trigger error',\n 'trigger-runtime.label': 'Auto trigger execution',\n 'trigger-last-invocation.label': 'Last run',\n 'trigger-duration.label': 'Duration',\n\n // AgentArticle.\n 'project-empty-spec.message': 'Open the Properties companion to configure the agent.',\n 'project-empty-spec.description': 'Open the Assistant companion to interact with the agent.',\n 'artifacts.label': 'Artifacts',\n 'inputs.label': 'Inputs',\n\n // AgentProperties.\n 'instructions.label': 'Instructions',\n 'instructions.placeholder': 'Enter instructions, goals, and constraints for the assistant.',\n 'reset-history.button': 'Reset',\n 'subscriptions.label': 'Subscriptions',\n\n // Per-space Home article: starter-prompt cards + the pinned assistant prompt.\n 'space-home.suggestions.heading': 'Get started',\n 'space-home.suggestion-magazine.label': 'Create feeds for tracking the latest AI news and build a magazine',\n 'space-home.suggestion-kanban.label': 'Create a kanban view for tracking tasks',\n 'space-home.prompt.placeholder': 'Ask the assistant anything…',\n\n 'nav-tree-group-ai.label': 'Assistant',\n },\n },\n },\n];\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  export declare const Root: {
2
- ({ children, chat, processor, db: dbFallback, debug: debugProp, onEvent, onSubmit, getContext, ...props }: import("./Chat.ts").RootProps): import("react").JSX.Element;
2
+ ({ children, chat, chatModel, db: dbFallback, debug: debugProp, onEvent, onSubmit, getContext, ...props }: import("./Chat.ts").RootProps): import("react").JSX.Element;
3
3
  displayName: string;
4
4
  }, Toolbar: import("react").ForwardRefExoticComponent<Omit<import("./Chat.ts").ToolbarProps, "className"> & {
5
5
  classNames?: import("@dxos/ui-types").ClassNameValue;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-service.d.ts","sourceRoot":"","sources":["../../../../src/capabilities/agent-service.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAKxC,OAAO,KAAK,UAAU,MAAM,gCAAgC,CAAC;AAM7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC"}
1
+ {"version":3,"file":"agent-service.d.ts","sourceRoot":"","sources":["../../../../src/capabilities/agent-service.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAKxC,OAAO,KAAK,UAAU,MAAM,gCAAgC,CAAC;AAM7D,OAAO,EAAyB,gBAAgB,EAAE,MAAM,QAAQ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"skill-definition.d.ts","sourceRoot":"","sources":["../../../../src/capabilities/skill-definition.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,UAAU,MAAM,gCAAgC,CAAC;AAC7D,OAAO,KAAK,MAAM,MAAM,4BAA4B,CAAC;AAmBrD,QAAA,MAAM,eAAe,0SA8BnB,CAAC;eAEY,eAAe"}
1
+ {"version":3,"file":"skill-definition.d.ts","sourceRoot":"","sources":["../../../../src/capabilities/skill-definition.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,UAAU,MAAM,gCAAgC,CAAC;AAC7D,OAAO,KAAK,MAAM,MAAM,4BAA4B,CAAC;AAmBrD,QAAA,MAAM,eAAe,0SA+BnB,CAAC;eAEY,eAAe"}