@dxos/plugin-assistant 0.10.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PLUGIN.mdl +3 -28
- package/dist/lib/AssistantPlugin.mjs +2 -0
- package/dist/lib/AssistantPlugin.node.mjs +55 -0
- package/dist/lib/AssistantPlugin.node.mjs.map +1 -0
- package/dist/lib/AssistantPlugin.workerd.mjs +43 -0
- package/dist/lib/AssistantPlugin.workerd.mjs.map +1 -0
- package/dist/lib/capabilities.mjs +24 -0
- package/dist/lib/capabilities.mjs.map +1 -0
- package/dist/lib/chunk-AgentArticle.mjs +52 -0
- package/dist/lib/chunk-AgentArticle.mjs.map +1 -0
- package/dist/lib/chunk-AgentProperties.mjs +35 -0
- package/dist/lib/chunk-AgentProperties.mjs.map +1 -0
- package/dist/lib/chunk-AssistantPlugin.mjs +88 -0
- package/dist/lib/chunk-AssistantPlugin.mjs.map +1 -0
- package/dist/lib/chunk-AssistantSettings.mjs +285 -0
- package/dist/lib/chunk-AssistantSettings.mjs.map +1 -0
- package/dist/lib/chunk-ChatArticle.mjs +121 -0
- package/dist/lib/chunk-ChatArticle.mjs.map +1 -0
- package/dist/lib/chunk-ChatCompanion.mjs +116 -0
- package/dist/lib/chunk-ChatCompanion.mjs.map +1 -0
- package/dist/lib/chunk-ChatDialog.mjs +73 -0
- package/dist/lib/chunk-ChatDialog.mjs.map +1 -0
- package/dist/lib/chunk-IntegrationPrompt.mjs +73 -0
- package/dist/lib/chunk-IntegrationPrompt.mjs.map +1 -0
- package/dist/lib/chunk-SpaceHomePrompt.mjs +104 -0
- package/dist/lib/chunk-SpaceHomePrompt.mjs.map +1 -0
- package/dist/lib/chunk-SpaceHomeSuggestions.mjs +60 -0
- package/dist/lib/chunk-SpaceHomeSuggestions.mjs.map +1 -0
- package/dist/lib/chunk-TracePanel.mjs +127 -0
- package/dist/lib/chunk-TracePanel.mjs.map +1 -0
- package/dist/lib/chunk-TracePanel2.mjs +7 -0
- package/dist/lib/chunk-TracePanel2.mjs.map +1 -0
- package/dist/lib/chunk-TriggerStatus.mjs +72 -0
- package/dist/lib/chunk-TriggerStatus.mjs.map +1 -0
- package/dist/lib/chunk-agent-hydrator.mjs +22 -0
- package/dist/lib/chunk-agent-hydrator.mjs.map +1 -0
- package/dist/lib/chunk-agent-service.mjs +21 -0
- package/dist/lib/chunk-agent-service.mjs.map +1 -0
- package/dist/lib/{neutral/ai-context-LIKJYMIN.mjs → chunk-ai-context.mjs} +8 -12
- package/dist/lib/chunk-ai-context.mjs.map +1 -0
- package/dist/lib/chunk-ai-service.mjs +27 -0
- package/dist/lib/chunk-ai-service.mjs.map +1 -0
- package/dist/lib/chunk-app-graph-builder.mjs +179 -0
- package/dist/lib/chunk-app-graph-builder.mjs.map +1 -0
- package/dist/lib/chunk-automation-templates.mjs +99 -0
- package/dist/lib/chunk-automation-templates.mjs.map +1 -0
- package/dist/lib/chunk-companion-chat-provisioner.mjs +123 -0
- package/dist/lib/chunk-companion-chat-provisioner.mjs.map +1 -0
- package/dist/lib/chunk-connector.mjs +60 -0
- package/dist/lib/chunk-connector.mjs.map +1 -0
- package/dist/lib/chunk-constants.mjs +9 -0
- package/dist/lib/chunk-constants.mjs.map +1 -0
- package/dist/lib/chunk-context.mjs +7 -0
- package/dist/lib/chunk-context.mjs.map +1 -0
- package/dist/lib/chunk-create-chat.mjs +53 -0
- package/dist/lib/chunk-create-chat.mjs.map +1 -0
- package/dist/lib/chunk-create-object.mjs +70 -0
- package/dist/lib/chunk-create-object.mjs.map +1 -0
- package/dist/lib/chunk-edge-model-resolver.mjs +64 -0
- package/dist/lib/chunk-edge-model-resolver.mjs.map +1 -0
- package/dist/lib/chunk-ensure-companion-chat.mjs +49 -0
- package/dist/lib/chunk-ensure-companion-chat.mjs.map +1 -0
- package/dist/lib/chunk-extensions.mjs +78 -0
- package/dist/lib/chunk-extensions.mjs.map +1 -0
- package/dist/lib/chunk-fork-chat.mjs +83 -0
- package/dist/lib/chunk-fork-chat.mjs.map +1 -0
- package/dist/lib/chunk-generate-home-suggestions.mjs +71 -0
- package/dist/lib/chunk-generate-home-suggestions.mjs.map +1 -0
- package/dist/lib/chunk-local-model-resolver.mjs +25 -0
- package/dist/lib/chunk-local-model-resolver.mjs.map +1 -0
- package/dist/lib/chunk-markdown-extension.mjs +27 -0
- package/dist/lib/chunk-markdown-extension.mjs.map +1 -0
- package/dist/lib/{neutral/chunk-L7AR4VTA.mjs → chunk-meta.mjs} +20 -25
- package/dist/lib/chunk-meta.mjs.map +1 -0
- package/dist/lib/chunk-operation-handler.mjs +13 -0
- package/dist/lib/chunk-operation-handler.mjs.map +1 -0
- package/dist/lib/chunk-paths.mjs +8 -0
- package/dist/lib/chunk-paths.mjs.map +1 -0
- package/dist/lib/chunk-processor.mjs +432 -0
- package/dist/lib/chunk-processor.mjs.map +1 -0
- package/dist/lib/chunk-react-surface.mjs +177 -0
- package/dist/lib/chunk-react-surface.mjs.map +1 -0
- package/dist/lib/chunk-run-prompt-in-new-chat.mjs +96 -0
- package/dist/lib/chunk-run-prompt-in-new-chat.mjs.map +1 -0
- package/dist/lib/chunk-set-current-chat.mjs +43 -0
- package/dist/lib/chunk-set-current-chat.mjs.map +1 -0
- package/dist/lib/chunk-settings.mjs +23 -0
- package/dist/lib/chunk-settings.mjs.map +1 -0
- package/dist/lib/chunk-skill-definition.mjs +42 -0
- package/dist/lib/chunk-skill-definition.mjs.map +1 -0
- package/dist/lib/chunk-skills.mjs +19 -0
- package/dist/lib/chunk-skills.mjs.map +1 -0
- package/dist/lib/chunk-state.mjs +32 -0
- package/dist/lib/chunk-state.mjs.map +1 -0
- package/dist/lib/chunk-toggle-trace-panel-debug.mjs +18 -0
- package/dist/lib/chunk-toggle-trace-panel-debug.mjs.map +1 -0
- package/dist/lib/chunk-toolkit.mjs +12 -0
- package/dist/lib/chunk-toolkit.mjs.map +1 -0
- package/dist/lib/chunk-types.mjs +332 -0
- package/dist/lib/chunk-types.mjs.map +1 -0
- package/dist/lib/chunk-update-chat-name.mjs +63 -0
- package/dist/lib/chunk-update-chat-name.mjs.map +1 -0
- package/dist/lib/components.mjs +2616 -0
- package/dist/lib/components.mjs.map +1 -0
- package/dist/lib/containers.mjs +17 -0
- package/dist/lib/containers.mjs.map +1 -0
- package/dist/lib/execution-graph.mjs +961 -0
- package/dist/lib/execution-graph.mjs.map +1 -0
- package/dist/lib/extensions.mjs +2 -0
- package/dist/lib/hooks.mjs +674 -0
- package/dist/lib/hooks.mjs.map +1 -0
- package/dist/lib/index.mjs +5 -0
- package/dist/lib/meta.mjs +2 -0
- package/dist/lib/operations.mjs +7 -0
- package/dist/lib/operations.mjs.map +1 -0
- package/dist/lib/plugin.mjs +9 -0
- package/dist/lib/plugin.mjs.map +1 -0
- package/dist/lib/plugin.workerd.mjs +2 -0
- package/dist/lib/skills.mjs +2 -0
- package/dist/lib/testing.mjs +2 -0
- package/dist/lib/translations.mjs +207 -0
- package/dist/lib/translations.mjs.map +1 -0
- package/dist/lib/types.mjs +2 -0
- package/dist/types/src/AssistantPlugin.d.ts.map +1 -1
- package/dist/types/src/AssistantPlugin.node.d.ts.map +1 -1
- package/dist/types/src/AssistantPlugin.workerd.d.ts.map +1 -1
- package/dist/types/src/capabilities/AssistantSurfaces.d.ts +22 -0
- package/dist/types/src/capabilities/AssistantSurfaces.d.ts.map +1 -0
- package/dist/types/src/capabilities/agent-hydrator.d.ts +1 -1
- package/dist/types/src/capabilities/agent-service.d.ts +1 -1
- package/dist/types/src/capabilities/agent-service.d.ts.map +1 -1
- package/dist/types/src/capabilities/ai-context.d.ts +1 -1
- package/dist/types/src/capabilities/ai-service.d.ts +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +12 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/automation-templates.d.ts +1 -1
- package/dist/types/src/capabilities/companion-chat-provisioner.d.ts +1 -1
- package/dist/types/src/capabilities/connector.d.ts +1 -1
- package/dist/types/src/capabilities/create-object.d.ts +1 -1
- package/dist/types/src/capabilities/edge-model-resolver.d.ts +1 -1
- package/dist/types/src/capabilities/edge-model-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +0 -2
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/local-model-resolver.d.ts +1 -1
- package/dist/types/src/capabilities/local-model-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/markdown-extension.d.ts +1 -1
- package/dist/types/src/capabilities/operation-handler.d.ts +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/capabilities/settings.d.ts +1 -1
- package/dist/types/src/capabilities/skill-definition.d.ts.map +1 -1
- package/dist/types/src/capabilities/standalone-chats-query.test.d.ts +2 -0
- package/dist/types/src/capabilities/standalone-chats-query.test.d.ts.map +1 -0
- package/dist/types/src/capabilities/state.d.ts +1 -1
- package/dist/types/src/capabilities/toolkit.d.ts +1 -1
- package/dist/types/src/components/AgentProperties/AgentProperties.d.ts +4 -1
- package/dist/types/src/components/AgentProperties/AgentProperties.d.ts.map +1 -1
- package/dist/types/src/components/AgentProperties/AgentProperties.stories.d.ts.map +1 -1
- package/dist/types/src/components/Chat/Chat.d.ts +21 -8
- package/dist/types/src/components/Chat/Chat.d.ts.map +1 -1
- package/dist/types/src/components/Chat/{Chat.stories.d.ts → Error.stories.d.ts} +1 -1
- package/dist/types/src/components/Chat/Error.stories.d.ts.map +1 -0
- package/dist/types/src/components/Chat/context.d.ts +8 -0
- package/dist/types/src/components/Chat/context.d.ts.map +1 -1
- package/dist/types/src/components/Chat/events.d.ts +5 -0
- package/dist/types/src/components/Chat/events.d.ts.map +1 -1
- package/dist/types/src/components/Chat/thread.d.ts +42 -0
- package/dist/types/src/components/Chat/thread.d.ts.map +1 -0
- package/dist/types/src/components/Chat/thread.test.d.ts +2 -0
- package/dist/types/src/components/Chat/thread.test.d.ts.map +1 -0
- package/dist/types/src/components/ChatPrompt/ChatActions.d.ts.map +1 -1
- package/dist/types/src/components/ChatPrompt/ChatOptions.stories.d.ts.map +1 -1
- package/dist/types/src/components/ChatPrompt/ChatPrompt.d.ts +5 -3
- package/dist/types/src/components/ChatPrompt/ChatPrompt.d.ts.map +1 -1
- package/dist/types/src/components/ChatPrompt/index.d.ts +0 -1
- package/dist/types/src/components/ChatPrompt/index.d.ts.map +1 -1
- package/dist/types/src/components/ChatThread/Anchor.stories.d.ts.map +1 -1
- package/dist/types/src/components/ChatThread/ChatThread.d.ts +8 -3
- package/dist/types/src/components/ChatThread/ChatThread.d.ts.map +1 -1
- package/dist/types/src/components/ChatThread/ChatThread.stories.d.ts +30 -2
- package/dist/types/src/components/ChatThread/ChatThread.stories.d.ts.map +1 -1
- package/dist/types/src/components/ChatThread/Link.d.ts.map +1 -1
- package/dist/types/src/components/ChatThread/index.d.ts +1 -0
- package/dist/types/src/components/ChatThread/index.d.ts.map +1 -1
- package/dist/types/src/components/ChatThread/registry.d.ts.map +1 -1
- package/dist/types/src/components/ChatThread/sync/index.d.ts +3 -0
- package/dist/types/src/components/ChatThread/sync/index.d.ts.map +1 -0
- package/dist/types/src/components/ChatThread/{sync.d.ts → sync/sync.d.ts} +46 -2
- package/dist/types/src/components/ChatThread/sync/sync.d.ts.map +1 -0
- package/dist/types/src/components/ChatThread/sync/sync.test.d.ts.map +1 -0
- package/dist/types/src/components/ChatThread/sync/tool-widget-state.d.ts.map +1 -0
- package/dist/types/src/components/ChatThread/sync/tool-widget-state.test.d.ts.map +1 -0
- package/dist/types/src/components/ChatThread/widgets/BranchWidget.d.ts +15 -0
- package/dist/types/src/components/ChatThread/widgets/BranchWidget.d.ts.map +1 -0
- package/dist/types/src/components/ChatThread/widgets/BranchWidget.stories.d.ts +21 -0
- package/dist/types/src/components/ChatThread/widgets/BranchWidget.stories.d.ts.map +1 -0
- package/dist/types/src/components/ChatThread/widgets/BranchWidget.test.d.ts +2 -0
- package/dist/types/src/components/ChatThread/widgets/BranchWidget.test.d.ts.map +1 -0
- package/dist/types/src/components/ChatThread/widgets/ReferenceWidget.d.ts.map +1 -1
- package/dist/types/src/components/ChatThread/widgets/SuggestionWidget.d.ts.map +1 -1
- package/dist/types/src/components/ChatThread/widgets/ToolWidget.d.ts +1 -2
- package/dist/types/src/components/ChatThread/widgets/ToolWidget.d.ts.map +1 -1
- package/dist/types/src/components/ChatThread/widgets/defaults.d.ts +6 -0
- package/dist/types/src/components/ChatThread/widgets/defaults.d.ts.map +1 -1
- package/dist/types/src/components/ChatThread/widgets/format-time.d.ts +2 -0
- package/dist/types/src/components/ChatThread/widgets/format-time.d.ts.map +1 -0
- package/dist/types/src/components/ChatThread/widgets/index.d.ts +4 -1
- package/dist/types/src/components/ChatThread/widgets/index.d.ts.map +1 -1
- package/dist/types/src/components/ChatThread/widgets/is-tool-message.d.ts +3 -0
- package/dist/types/src/components/ChatThread/widgets/is-tool-message.d.ts.map +1 -0
- package/dist/types/src/components/ConnectorAuthMenu/ConnectorAuthMenu.d.ts +16 -0
- package/dist/types/src/components/ConnectorAuthMenu/ConnectorAuthMenu.d.ts.map +1 -0
- package/dist/types/src/components/ConnectorAuthMenu/ConnectorAuthMenu.stories.d.ts +210 -0
- package/dist/types/src/components/ConnectorAuthMenu/ConnectorAuthMenu.stories.d.ts.map +1 -0
- package/dist/types/src/components/ConnectorAuthMenu/index.d.ts +2 -0
- package/dist/types/src/components/ConnectorAuthMenu/index.d.ts.map +1 -0
- package/dist/types/src/components/ProcessTree/ProcessTree.d.ts +1 -1
- package/dist/types/src/components/ProcessTree/ProcessTree.d.ts.map +1 -1
- package/dist/types/src/components/TaskList/TaskList.d.ts +9 -11
- package/dist/types/src/components/TaskList/TaskList.d.ts.map +1 -1
- package/dist/types/src/components/TaskList/TaskList.stories.d.ts +3 -4
- package/dist/types/src/components/TaskList/TaskList.stories.d.ts.map +1 -1
- package/dist/types/src/components/ToolBlock/ToolBlock.d.ts +1 -2
- package/dist/types/src/components/ToolBlock/ToolBlock.d.ts.map +1 -1
- package/dist/types/src/components/ToolBlock/index.d.ts +1 -0
- package/dist/types/src/components/ToolBlock/index.d.ts.map +1 -1
- package/dist/types/src/components/ToolBlock/is-tool-message.d.ts +3 -0
- package/dist/types/src/components/ToolBlock/is-tool-message.d.ts.map +1 -0
- package/dist/types/src/components/Toolbox/Toolbox.d.ts +1 -1
- package/dist/types/src/components/Toolbox/Toolbox.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/containers/AgentArticle/AgentArticle.d.ts +5 -2
- package/dist/types/src/containers/AgentArticle/AgentArticle.d.ts.map +1 -1
- package/dist/types/src/containers/AgentArticle/AgentArticle.stories.d.ts.map +1 -1
- package/dist/types/src/containers/AgentProperties/AgentProperties.d.ts +4 -1
- package/dist/types/src/containers/AgentProperties/AgentProperties.d.ts.map +1 -1
- package/dist/types/src/containers/AssistantSettings/AssistantSettings.d.ts +4 -1
- package/dist/types/src/containers/AssistantSettings/AssistantSettings.d.ts.map +1 -1
- package/dist/types/src/containers/AssistantSettings/AssistantSettings.stories.d.ts +4 -1
- package/dist/types/src/containers/AssistantSettings/AssistantSettings.stories.d.ts.map +1 -1
- package/dist/types/src/containers/AssistantSettings/OllamaModels.d.ts +4 -6
- package/dist/types/src/containers/AssistantSettings/OllamaModels.d.ts.map +1 -1
- package/dist/types/src/containers/ChatArticle/ChatArticle.d.ts.map +1 -1
- package/dist/types/src/containers/ChatArticle/ChatArticle.stories.d.ts +22 -1
- package/dist/types/src/containers/ChatArticle/ChatArticle.stories.d.ts.map +1 -1
- package/dist/types/src/containers/ChatCompanion/ChatCompanion.d.ts.map +1 -1
- package/dist/types/src/containers/ChatDialog/ChatDialog.d.ts +4 -1
- package/dist/types/src/containers/ChatDialog/ChatDialog.d.ts.map +1 -1
- package/dist/types/src/containers/IntegrationPrompt/IntegrationPrompt.d.ts +4 -7
- package/dist/types/src/containers/IntegrationPrompt/IntegrationPrompt.d.ts.map +1 -1
- package/dist/types/src/containers/SpaceHomePrompt/SpaceHomePrompt.d.ts +4 -9
- package/dist/types/src/containers/SpaceHomePrompt/SpaceHomePrompt.d.ts.map +1 -1
- package/dist/types/src/containers/SpaceHomeSuggestions/SpaceHomeSuggestions.d.ts +5 -7
- package/dist/types/src/containers/SpaceHomeSuggestions/SpaceHomeSuggestions.d.ts.map +1 -1
- package/dist/types/src/containers/TracePanel/TracePanel.d.ts +1 -1
- package/dist/types/src/containers/TracePanel/TracePanel.d.ts.map +1 -1
- package/dist/types/src/containers/TracePanel/TracePanel.stories.d.ts.map +1 -1
- package/dist/types/src/containers/TriggerStatus/TriggerStatus.d.ts +15 -1
- package/dist/types/src/containers/TriggerStatus/TriggerStatus.d.ts.map +1 -1
- package/dist/types/src/containers/index.d.ts +0 -1
- package/dist/types/src/containers/index.d.ts.map +1 -1
- package/dist/types/src/execution-graph/execution-graph.d.ts +12 -1
- package/dist/types/src/execution-graph/execution-graph.d.ts.map +1 -1
- package/dist/types/src/execution-graph/index.d.ts +1 -1
- package/dist/types/src/execution-graph/index.d.ts.map +1 -1
- package/dist/types/src/execution-graph/pending-block-status.d.ts.map +1 -1
- package/dist/types/src/execution-graph/span-tree.d.ts +17 -0
- package/dist/types/src/execution-graph/span-tree.d.ts.map +1 -1
- package/dist/types/src/feed-logger.d.ts +1 -1
- package/dist/types/src/feed-logger.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +1 -1
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useChatProcessor.d.ts.map +1 -1
- package/dist/types/src/hooks/useChatToolbarActions.d.ts.map +1 -1
- package/dist/types/src/hooks/useContextObjects.d.ts +1 -1
- package/dist/types/src/hooks/useContextObjects.d.ts.map +1 -1
- package/dist/types/src/hooks/useSelectionContext.d.ts +13 -0
- package/dist/types/src/hooks/useSelectionContext.d.ts.map +1 -0
- package/dist/types/src/hooks/useSelectionContext.test.d.ts +2 -0
- package/dist/types/src/hooks/useSelectionContext.test.d.ts.map +1 -0
- package/dist/types/src/hooks/useTraceMessages.d.ts.map +1 -1
- package/dist/types/src/operations/index.d.ts.map +1 -1
- package/dist/types/src/processor/index.d.ts +1 -0
- package/dist/types/src/processor/index.d.ts.map +1 -1
- package/dist/types/src/processor/processor.d.ts +5 -2
- package/dist/types/src/processor/processor.d.ts.map +1 -1
- package/dist/types/src/processor/prompt.d.ts +18 -0
- package/dist/types/src/processor/prompt.d.ts.map +1 -0
- package/dist/types/src/processor/prompt.test.d.ts +2 -0
- package/dist/types/src/processor/prompt.test.d.ts.map +1 -0
- package/dist/types/src/processor/streaming.node.test.d.ts +2 -0
- package/dist/types/src/processor/streaming.node.test.d.ts.map +1 -0
- package/dist/types/src/skills/assistant/skill.d.ts.map +1 -1
- package/dist/types/src/templates/scaffold.d.ts +1 -1
- package/dist/types/src/templates/scaffold.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/AssistantCapabilities.d.ts +1 -1
- package/dist/types/src/types/AssistantCapabilities.d.ts.map +1 -1
- package/dist/types/src/types/AssistantOperation.d.ts +2 -13
- package/dist/types/src/types/AssistantOperation.d.ts.map +1 -1
- package/dist/types/src/types/ChatSurface.d.ts +2 -2
- package/dist/types/src/types/ChatSurface.d.ts.map +1 -1
- package/dist/types/src/types/Ollama.d.ts +1 -1
- package/dist/types/src/types/Ollama.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/dx.config.ts +1 -0
- package/package.json +106 -105
- package/src/AssistantPlugin.node.ts +1 -2
- package/src/AssistantPlugin.test.ts +60 -62
- package/src/AssistantPlugin.ts +1 -10
- package/src/AssistantPlugin.workerd.ts +1 -2
- package/src/capabilities/AssistantSurfaces.tsx +86 -0
- package/src/capabilities/agent-service.ts +1 -1
- package/src/capabilities/app-graph-builder.ts +31 -17
- package/src/capabilities/companion-chat-provisioner.ts +12 -11
- package/src/capabilities/connector.ts +3 -3
- package/src/capabilities/edge-model-resolver.ts +5 -2
- package/src/capabilities/index.ts +0 -2
- package/src/capabilities/react-surface.ts +135 -0
- package/src/capabilities/skill-definition.ts +4 -0
- package/src/capabilities/standalone-chats-query.test.ts +51 -0
- package/src/capabilities/state.ts +1 -1
- package/src/components/AgentProperties/AgentProperties.stories.tsx +6 -7
- package/src/components/AgentProperties/AgentProperties.tsx +37 -30
- package/src/components/Chat/Chat.tsx +275 -59
- package/src/components/Chat/{Chat.stories.tsx → Error.stories.tsx} +1 -1
- package/src/components/Chat/context.ts +8 -0
- package/src/components/Chat/events.ts +5 -0
- package/src/components/Chat/thread.test.ts +127 -0
- package/src/components/Chat/thread.ts +87 -0
- package/src/components/ChatPrompt/ChatActions.tsx +8 -8
- package/src/components/ChatPrompt/ChatMcpErrors.tsx +2 -2
- package/src/components/ChatPrompt/ChatOptions.stories.tsx +2 -1
- package/src/components/ChatPrompt/ChatOptions.tsx +5 -5
- package/src/components/ChatPrompt/ChatPrompt.tsx +33 -6
- package/src/components/ChatPrompt/index.ts +0 -1
- package/src/components/ChatThread/Anchor.stories.tsx +2 -1
- package/src/components/ChatThread/ChatThread.stories.tsx +99 -4
- package/src/components/ChatThread/ChatThread.tsx +34 -6
- package/src/components/ChatThread/Link.tsx +1 -0
- package/src/components/ChatThread/index.ts +2 -0
- package/src/components/ChatThread/registry.tsx +28 -4
- package/src/components/ChatThread/sync/index.ts +6 -0
- package/src/components/ChatThread/{sync.test.ts → sync/sync.test.ts} +167 -7
- package/src/components/ChatThread/{sync.ts → sync/sync.ts} +97 -3
- package/src/components/ChatThread/{tool-widget-state.ts → sync/tool-widget-state.ts} +1 -3
- package/src/components/ChatThread/widgets/BranchWidget.stories.tsx +83 -0
- package/src/components/ChatThread/widgets/BranchWidget.test.ts +55 -0
- package/src/components/ChatThread/widgets/BranchWidget.tsx +61 -0
- package/src/components/ChatThread/widgets/FallbackWidget.tsx +2 -2
- package/src/components/ChatThread/widgets/ReasoningWidget.ts +1 -1
- package/src/components/ChatThread/widgets/ReferenceWidget.ts +1 -6
- package/src/components/ChatThread/widgets/SuggestionWidget.ts +12 -3
- package/src/components/ChatThread/widgets/SummaryWidget.tsx +1 -1
- package/src/components/ChatThread/widgets/ToolWidget.tsx +15 -9
- package/src/components/ChatThread/widgets/defaults.ts +7 -1
- package/src/components/ChatThread/widgets/format-time.ts +45 -0
- package/src/components/ChatThread/widgets/index.ts +4 -1
- package/src/components/ChatThread/widgets/is-tool-message.ts +13 -0
- package/src/components/ConnectorAuthMenu/ConnectorAuthMenu.stories.tsx +177 -0
- package/src/components/ConnectorAuthMenu/ConnectorAuthMenu.tsx +82 -0
- package/src/components/ConnectorAuthMenu/index.ts +5 -0
- package/src/components/ProcessTree/ProcessTree.stories.tsx +1 -1
- package/src/components/TaskList/TaskList.stories.tsx +19 -26
- package/src/components/TaskList/TaskList.tsx +32 -104
- package/src/components/ToolBlock/ToolBlock.tsx +1 -5
- package/src/components/ToolBlock/index.ts +1 -0
- package/src/components/ToolBlock/is-tool-message.ts +13 -0
- package/src/components/Toolbox/Toolbox.tsx +1 -1
- package/src/components/index.ts +1 -0
- package/src/containers/AgentArticle/AgentArticle.stories.tsx +18 -11
- package/src/containers/AgentArticle/AgentArticle.tsx +27 -151
- package/src/containers/AgentProperties/AgentProperties.tsx +21 -17
- package/src/containers/AssistantSettings/AssistantSettings.tsx +2 -0
- package/src/containers/AssistantSettings/OllamaModels.tsx +6 -4
- package/src/containers/ChatArticle/ChatArticle.stories.tsx +200 -27
- package/src/containers/ChatArticle/ChatArticle.tsx +25 -5
- package/src/containers/ChatCompanion/ChatCompanion.tsx +45 -10
- package/src/containers/ChatDialog/ChatDialog.tsx +4 -1
- package/src/containers/IntegrationPrompt/IntegrationPrompt.tsx +9 -6
- package/src/containers/SpaceHomePrompt/SpaceHomePrompt.tsx +2 -0
- package/src/containers/SpaceHomeSuggestions/SpaceHomeSuggestions.tsx +40 -39
- package/src/containers/TracePanel/TracePanel.stories.tsx +9 -4
- package/src/containers/TracePanel/TracePanel.tsx +22 -6
- package/src/containers/TriggerStatus/TriggerStatus.tsx +9 -16
- package/src/containers/index.ts +0 -1
- package/src/execution-graph/SPEC.md +60 -2
- package/src/execution-graph/execution-graph.ts +15 -2
- package/src/execution-graph/index.ts +1 -0
- package/src/execution-graph/pending-block-status.ts +3 -2
- package/src/execution-graph/span-tree.test.ts +87 -1
- package/src/execution-graph/span-tree.ts +95 -0
- package/src/feed-logger.ts +6 -6
- package/src/hooks/index.ts +1 -1
- package/src/hooks/useChatProcessor.ts +2 -1
- package/src/hooks/useChatToolbarActions.ts +22 -19
- package/src/hooks/useContextObjects.ts +9 -3
- package/src/hooks/useSelectionContext.test.ts +93 -0
- package/src/hooks/useSelectionContext.ts +72 -0
- package/src/hooks/useSkillRegistry.ts +1 -1
- package/src/hooks/useTraceMessages.ts +5 -3
- package/src/operations/create-chat.ts +2 -2
- package/src/operations/fork-chat.ts +2 -2
- package/src/operations/generate-home-suggestions.test.ts +2 -2
- package/src/operations/index.ts +0 -1
- package/src/operations/prompt.node.test.ts +1 -1
- package/src/paths.ts +3 -3
- package/src/processor/index.ts +1 -0
- package/src/processor/processor.node.test.ts +1 -1
- package/src/processor/processor.ts +33 -5
- package/src/processor/prompt.test.ts +37 -0
- package/src/processor/prompt.ts +42 -0
- package/src/processor/streaming.node.test.ts +196 -0
- package/src/skills/assistant/skill.node.test.ts +2 -2
- package/src/skills/assistant/skill.ts +3 -5
- package/src/templates/routine-templates.test.ts +1 -2
- package/src/templates/scaffold.ts +3 -3
- package/src/testing/data/trace-timeline-multiple.dx.json +1 -1
- package/src/testing/data/trace-timeline-remote.dx.json +1 -1
- package/src/testing/data/trace-timeline.dx.json +1 -2
- package/src/testing/trace-timeline.node.test.ts +3 -3
- package/src/translations.ts +11 -10
- package/src/types/AssistantCapabilities.ts +1 -1
- package/src/types/AssistantOperation.ts +8 -31
- package/src/types/ChatSurface.ts +3 -3
- package/src/types/Ollama.ts +1 -1
- package/dist/lib/neutral/AgentArticle-GV6EEW3I.mjs +0 -161
- package/dist/lib/neutral/AgentArticle-GV6EEW3I.mjs.map +0 -7
- package/dist/lib/neutral/AgentProperties-LFTEYJ54.mjs +0 -40
- package/dist/lib/neutral/AgentProperties-LFTEYJ54.mjs.map +0 -7
- package/dist/lib/neutral/AssistantPlugin.mjs +0 -10
- package/dist/lib/neutral/AssistantPlugin.mjs.map +0 -7
- package/dist/lib/neutral/AssistantPlugin.node.mjs +0 -72
- package/dist/lib/neutral/AssistantPlugin.node.mjs.map +0 -7
- package/dist/lib/neutral/AssistantPlugin.workerd.mjs +0 -13
- package/dist/lib/neutral/AssistantPlugin.workerd.mjs.map +0 -7
- package/dist/lib/neutral/AssistantSettings-3N5M5VCN.mjs +0 -302
- package/dist/lib/neutral/AssistantSettings-3N5M5VCN.mjs.map +0 -7
- package/dist/lib/neutral/ChatArticle-OO7GGEFW.mjs +0 -8
- package/dist/lib/neutral/ChatArticle-OO7GGEFW.mjs.map +0 -7
- package/dist/lib/neutral/ChatCompanion-GIFJRY6I.mjs +0 -128
- package/dist/lib/neutral/ChatCompanion-GIFJRY6I.mjs.map +0 -7
- package/dist/lib/neutral/ChatDialog-5MXN4MXS.mjs +0 -74
- package/dist/lib/neutral/ChatDialog-5MXN4MXS.mjs.map +0 -7
- package/dist/lib/neutral/IntegrationPrompt-2HJQFYJE.mjs +0 -72
- package/dist/lib/neutral/IntegrationPrompt-2HJQFYJE.mjs.map +0 -7
- package/dist/lib/neutral/PlanArticle-VPK2IYWU.mjs +0 -34
- package/dist/lib/neutral/PlanArticle-VPK2IYWU.mjs.map +0 -7
- package/dist/lib/neutral/SpaceHomePrompt-ISAB76LD.mjs +0 -114
- package/dist/lib/neutral/SpaceHomePrompt-ISAB76LD.mjs.map +0 -7
- package/dist/lib/neutral/SpaceHomeSuggestions-IDH77QQR.mjs +0 -63
- package/dist/lib/neutral/SpaceHomeSuggestions-IDH77QQR.mjs.map +0 -7
- package/dist/lib/neutral/TracePanel-JKNWADJ4.mjs +0 -12
- package/dist/lib/neutral/TracePanel-JKNWADJ4.mjs.map +0 -7
- package/dist/lib/neutral/TriggerStatus-FURRBHYA.mjs +0 -95
- package/dist/lib/neutral/TriggerStatus-FURRBHYA.mjs.map +0 -7
- package/dist/lib/neutral/agent-hydrator-OBO3RHLO.mjs +0 -23
- package/dist/lib/neutral/agent-hydrator-OBO3RHLO.mjs.map +0 -7
- package/dist/lib/neutral/agent-service-XFJ4VQMT.mjs +0 -32
- package/dist/lib/neutral/agent-service-XFJ4VQMT.mjs.map +0 -7
- package/dist/lib/neutral/ai-context-LIKJYMIN.mjs.map +0 -7
- package/dist/lib/neutral/ai-service-DM6YXWUC.mjs +0 -44
- package/dist/lib/neutral/ai-service-DM6YXWUC.mjs.map +0 -7
- package/dist/lib/neutral/app-graph-builder-OPVOEQY7.mjs +0 -249
- package/dist/lib/neutral/app-graph-builder-OPVOEQY7.mjs.map +0 -7
- package/dist/lib/neutral/automation-templates-MADJLXGJ.mjs +0 -97
- package/dist/lib/neutral/automation-templates-MADJLXGJ.mjs.map +0 -7
- package/dist/lib/neutral/capabilities/index.mjs +0 -47
- package/dist/lib/neutral/capabilities/index.mjs.map +0 -7
- package/dist/lib/neutral/chunk-5IHQ52KJ.mjs +0 -9
- package/dist/lib/neutral/chunk-5IHQ52KJ.mjs.map +0 -7
- package/dist/lib/neutral/chunk-6Q4OBGIK.mjs +0 -420
- package/dist/lib/neutral/chunk-6Q4OBGIK.mjs.map +0 -7
- package/dist/lib/neutral/chunk-BXI2R4OO.mjs +0 -410
- package/dist/lib/neutral/chunk-BXI2R4OO.mjs.map +0 -7
- package/dist/lib/neutral/chunk-CMPLPDYE.mjs +0 -30
- package/dist/lib/neutral/chunk-CMPLPDYE.mjs.map +0 -7
- package/dist/lib/neutral/chunk-GPHT3HYS.mjs +0 -8
- package/dist/lib/neutral/chunk-GPHT3HYS.mjs.map +0 -7
- package/dist/lib/neutral/chunk-HKLSFB5I.mjs +0 -90
- package/dist/lib/neutral/chunk-HKLSFB5I.mjs.map +0 -7
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs +0 -10
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +0 -7
- package/dist/lib/neutral/chunk-L7AR4VTA.mjs.map +0 -7
- package/dist/lib/neutral/chunk-LS72HWMM.mjs +0 -42
- package/dist/lib/neutral/chunk-LS72HWMM.mjs.map +0 -7
- package/dist/lib/neutral/chunk-OZWZGIV2.mjs +0 -12
- package/dist/lib/neutral/chunk-OZWZGIV2.mjs.map +0 -7
- package/dist/lib/neutral/chunk-QOKLFHUS.mjs +0 -13
- package/dist/lib/neutral/chunk-QOKLFHUS.mjs.map +0 -7
- package/dist/lib/neutral/chunk-SCTHQVIJ.mjs +0 -155
- package/dist/lib/neutral/chunk-SCTHQVIJ.mjs.map +0 -7
- package/dist/lib/neutral/chunk-U4LTLBAX.mjs +0 -56
- package/dist/lib/neutral/chunk-U4LTLBAX.mjs.map +0 -7
- package/dist/lib/neutral/chunk-UPKFUZ6V.mjs +0 -115
- package/dist/lib/neutral/chunk-UPKFUZ6V.mjs.map +0 -7
- package/dist/lib/neutral/chunk-V2Y4XE3O.mjs +0 -12
- package/dist/lib/neutral/chunk-V2Y4XE3O.mjs.map +0 -7
- package/dist/lib/neutral/chunk-VTK5R4H3.mjs +0 -9
- package/dist/lib/neutral/chunk-VTK5R4H3.mjs.map +0 -7
- package/dist/lib/neutral/chunk-XVGEJWJX.mjs +0 -133
- package/dist/lib/neutral/chunk-XVGEJWJX.mjs.map +0 -7
- package/dist/lib/neutral/companion-chat-provisioner-IQV5VIVE.mjs +0 -126
- package/dist/lib/neutral/companion-chat-provisioner-IQV5VIVE.mjs.map +0 -7
- package/dist/lib/neutral/components/index.mjs +0 -2527
- package/dist/lib/neutral/components/index.mjs.map +0 -7
- package/dist/lib/neutral/connector-ITLLTBPZ.mjs +0 -70
- package/dist/lib/neutral/connector-ITLLTBPZ.mjs.map +0 -7
- package/dist/lib/neutral/containers/index.mjs +0 -31
- package/dist/lib/neutral/containers/index.mjs.map +0 -7
- package/dist/lib/neutral/create-chat-YGVZZYGP.mjs +0 -56
- package/dist/lib/neutral/create-chat-YGVZZYGP.mjs.map +0 -7
- package/dist/lib/neutral/create-object-5PAEJ6KM.mjs +0 -76
- package/dist/lib/neutral/create-object-5PAEJ6KM.mjs.map +0 -7
- package/dist/lib/neutral/edge-model-resolver-WDJWDZTT.mjs +0 -55
- package/dist/lib/neutral/edge-model-resolver-WDJWDZTT.mjs.map +0 -7
- package/dist/lib/neutral/ensure-companion-chat-AMOF3C66.mjs +0 -58
- package/dist/lib/neutral/ensure-companion-chat-AMOF3C66.mjs.map +0 -7
- package/dist/lib/neutral/execution-graph/index.mjs +0 -977
- package/dist/lib/neutral/execution-graph/index.mjs.map +0 -7
- package/dist/lib/neutral/extensions/index.mjs +0 -8
- package/dist/lib/neutral/extensions/index.mjs.map +0 -7
- package/dist/lib/neutral/fork-chat-RMAAYYQF.mjs +0 -92
- package/dist/lib/neutral/fork-chat-RMAAYYQF.mjs.map +0 -7
- package/dist/lib/neutral/generate-home-suggestions-6MM2XWPV.mjs +0 -93
- package/dist/lib/neutral/generate-home-suggestions-6MM2XWPV.mjs.map +0 -7
- package/dist/lib/neutral/hooks/index.mjs +0 -877
- package/dist/lib/neutral/hooks/index.mjs.map +0 -7
- package/dist/lib/neutral/index.mjs +0 -42
- package/dist/lib/neutral/index.mjs.map +0 -7
- package/dist/lib/neutral/local-model-resolver-I2BENFFS.mjs +0 -24
- package/dist/lib/neutral/local-model-resolver-I2BENFFS.mjs.map +0 -7
- package/dist/lib/neutral/markdown-extension-R4TKDTIF.mjs +0 -41
- package/dist/lib/neutral/markdown-extension-R4TKDTIF.mjs.map +0 -7
- package/dist/lib/neutral/meta.json +0 -1
- package/dist/lib/neutral/meta.mjs +0 -12
- package/dist/lib/neutral/meta.mjs.map +0 -7
- package/dist/lib/neutral/migrations-7DEMVBOG.mjs +0 -28
- package/dist/lib/neutral/migrations-7DEMVBOG.mjs.map +0 -7
- package/dist/lib/neutral/navigation-resolver-PYGP2DAW.mjs +0 -18
- package/dist/lib/neutral/navigation-resolver-PYGP2DAW.mjs.map +0 -7
- package/dist/lib/neutral/operation-handler-2LEN45GP.mjs +0 -8
- package/dist/lib/neutral/operation-handler-2LEN45GP.mjs.map +0 -7
- package/dist/lib/neutral/operations/index.mjs +0 -8
- package/dist/lib/neutral/operations/index.mjs.map +0 -7
- package/dist/lib/neutral/plugin.mjs +0 -16
- package/dist/lib/neutral/plugin.mjs.map +0 -7
- package/dist/lib/neutral/plugin.workerd.mjs +0 -13
- package/dist/lib/neutral/plugin.workerd.mjs.map +0 -7
- package/dist/lib/neutral/react-surface-HEJEK44F.mjs +0 -171
- package/dist/lib/neutral/react-surface-HEJEK44F.mjs.map +0 -7
- package/dist/lib/neutral/resolve-navigation-targets-PBQ3OLUE.mjs +0 -28
- package/dist/lib/neutral/resolve-navigation-targets-PBQ3OLUE.mjs.map +0 -7
- package/dist/lib/neutral/run-prompt-in-new-chat-RNUJE2FM.mjs +0 -102
- package/dist/lib/neutral/run-prompt-in-new-chat-RNUJE2FM.mjs.map +0 -7
- package/dist/lib/neutral/set-current-chat-VWBPSIMZ.mjs +0 -48
- package/dist/lib/neutral/set-current-chat-VWBPSIMZ.mjs.map +0 -7
- package/dist/lib/neutral/settings-7Q3RITIT.mjs +0 -28
- package/dist/lib/neutral/settings-7Q3RITIT.mjs.map +0 -7
- package/dist/lib/neutral/skill-definition-553MQRTR.mjs +0 -8
- package/dist/lib/neutral/skill-definition-553MQRTR.mjs.map +0 -7
- package/dist/lib/neutral/skills/index.mjs +0 -8
- package/dist/lib/neutral/skills/index.mjs.map +0 -7
- package/dist/lib/neutral/state-4LGAKSSD.mjs +0 -34
- package/dist/lib/neutral/state-4LGAKSSD.mjs.map +0 -7
- package/dist/lib/neutral/testing.mjs +0 -8
- package/dist/lib/neutral/testing.mjs.map +0 -7
- package/dist/lib/neutral/toggle-trace-panel-debug-JGTB6KVJ.mjs +0 -21
- package/dist/lib/neutral/toggle-trace-panel-debug-JGTB6KVJ.mjs.map +0 -7
- package/dist/lib/neutral/toolkit-ETWLG5NT.mjs +0 -8
- package/dist/lib/neutral/toolkit-ETWLG5NT.mjs.map +0 -7
- package/dist/lib/neutral/translations.mjs +0 -217
- package/dist/lib/neutral/translations.mjs.map +0 -7
- package/dist/lib/neutral/types/index.mjs +0 -24
- package/dist/lib/neutral/types/index.mjs.map +0 -7
- package/dist/lib/neutral/update-chat-name-IJJELRR6.mjs +0 -61
- package/dist/lib/neutral/update-chat-name-IJJELRR6.mjs.map +0 -7
- package/dist/types/src/capabilities/migrations.d.ts +0 -5
- package/dist/types/src/capabilities/migrations.d.ts.map +0 -1
- package/dist/types/src/capabilities/navigation-resolver.d.ts +0 -5
- package/dist/types/src/capabilities/navigation-resolver.d.ts.map +0 -1
- package/dist/types/src/components/Chat/Chat.stories.d.ts.map +0 -1
- package/dist/types/src/components/ChatPrompt/ChatStatusIndicator.d.ts +0 -10
- package/dist/types/src/components/ChatPrompt/ChatStatusIndicator.d.ts.map +0 -1
- package/dist/types/src/components/ChatThread/sync.d.ts.map +0 -1
- package/dist/types/src/components/ChatThread/sync.test.d.ts.map +0 -1
- package/dist/types/src/components/ChatThread/tool-widget-state.d.ts.map +0 -1
- package/dist/types/src/components/ChatThread/tool-widget-state.test.d.ts.map +0 -1
- package/dist/types/src/containers/PlanArticle/PlanArticle.d.ts +0 -6
- package/dist/types/src/containers/PlanArticle/PlanArticle.d.ts.map +0 -1
- package/dist/types/src/containers/PlanArticle/index.d.ts +0 -2
- package/dist/types/src/containers/PlanArticle/index.d.ts.map +0 -1
- package/dist/types/src/hooks/useFlush.d.ts +0 -6
- package/dist/types/src/hooks/useFlush.d.ts.map +0 -1
- package/dist/types/src/operations/resolve-navigation-targets.d.ts +0 -5
- package/dist/types/src/operations/resolve-navigation-targets.d.ts.map +0 -1
- package/src/AssistantPlugin.conversations.json +0 -1
- package/src/capabilities/migrations.ts +0 -28
- package/src/capabilities/navigation-resolver.ts +0 -20
- package/src/capabilities/react-surface.tsx +0 -177
- package/src/components/ChatPrompt/ChatStatusIndicator.tsx +0 -42
- package/src/components/ChatThread/DEBUG.md +0 -64
- package/src/containers/PlanArticle/PlanArticle.tsx +0 -37
- package/src/containers/PlanArticle/index.ts +0 -5
- package/src/hooks/useFlush.ts +0 -35
- package/src/operations/resolve-navigation-targets.ts +0 -44
- /package/dist/types/src/components/ChatThread/{sync.test.d.ts → sync/sync.test.d.ts} +0 -0
- /package/dist/types/src/components/ChatThread/{tool-widget-state.d.ts → sync/tool-widget-state.d.ts} +0 -0
- /package/dist/types/src/components/ChatThread/{tool-widget-state.test.d.ts → sync/tool-widget-state.test.d.ts} +0 -0
- /package/src/components/ChatThread/{tool-widget-state.test.ts → sync/tool-widget-state.test.ts} +0 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
|
+
import { expect, fn, userEvent, within } from 'storybook/test';
|
|
7
|
+
|
|
8
|
+
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
9
|
+
|
|
10
|
+
import { translations } from '#translations';
|
|
11
|
+
|
|
12
|
+
import { MessageThreadContext } from '../sync';
|
|
13
|
+
import { BranchWidget, type BranchWidgetProps } from './BranchWidget';
|
|
14
|
+
|
|
15
|
+
const MESSAGE_ID = '01JQ0000000000000000000001';
|
|
16
|
+
|
|
17
|
+
const onRewind = fn();
|
|
18
|
+
|
|
19
|
+
const baseWidgetProps = {
|
|
20
|
+
_tag: 'branch',
|
|
21
|
+
range: { from: 0, to: 1 },
|
|
22
|
+
} satisfies Pick<BranchWidgetProps, '_tag' | 'range'>;
|
|
23
|
+
|
|
24
|
+
const meta = {
|
|
25
|
+
title: 'plugins/plugin-assistant/components/ChatWidgets/BranchWidget',
|
|
26
|
+
component: BranchWidget,
|
|
27
|
+
decorators: [withTheme(), withLayout({ layout: 'column' })],
|
|
28
|
+
parameters: {
|
|
29
|
+
layout: 'fullscreen',
|
|
30
|
+
translations,
|
|
31
|
+
},
|
|
32
|
+
} satisfies Meta<typeof BranchWidget>;
|
|
33
|
+
|
|
34
|
+
export default meta;
|
|
35
|
+
|
|
36
|
+
type Story = StoryObj<typeof meta>;
|
|
37
|
+
|
|
38
|
+
export const Default: Story = {
|
|
39
|
+
args: {
|
|
40
|
+
...baseWidgetProps,
|
|
41
|
+
messageId: MESSAGE_ID,
|
|
42
|
+
created: '2026-07-29T14:32:00.000Z',
|
|
43
|
+
context: new MessageThreadContext(),
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/** No timestamp: the toolbar still offers the rewind action. */
|
|
48
|
+
export const NoTimestamp: Story = {
|
|
49
|
+
args: {
|
|
50
|
+
...baseWidgetProps,
|
|
51
|
+
messageId: MESSAGE_ID,
|
|
52
|
+
context: new MessageThreadContext(),
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/** Without a message id there is nothing to rewind to, so the widget renders nothing. */
|
|
57
|
+
export const NoMessage: Story = {
|
|
58
|
+
args: {
|
|
59
|
+
...baseWidgetProps,
|
|
60
|
+
created: '2026-07-29T14:32:00.000Z',
|
|
61
|
+
context: new MessageThreadContext(),
|
|
62
|
+
},
|
|
63
|
+
play: async ({ canvasElement }) => {
|
|
64
|
+
const canvas = within(canvasElement);
|
|
65
|
+
await expect(canvas.queryByTestId('chat.rewind')).toBeNull();
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/** Clicking rewind reports the prompt's message id, which is what the thread soft-forks from. */
|
|
70
|
+
export const Clicked: Story = {
|
|
71
|
+
args: {
|
|
72
|
+
...baseWidgetProps,
|
|
73
|
+
messageId: MESSAGE_ID,
|
|
74
|
+
created: '2026-07-29T14:32:00.000Z',
|
|
75
|
+
context: new MessageThreadContext(undefined, { onRewind }),
|
|
76
|
+
},
|
|
77
|
+
play: async ({ canvasElement }) => {
|
|
78
|
+
onRewind.mockClear();
|
|
79
|
+
const canvas = within(canvasElement);
|
|
80
|
+
await userEvent.click(await canvas.findByTestId('chat.rewind'));
|
|
81
|
+
await expect(onRewind).toHaveBeenCalledWith(MESSAGE_ID);
|
|
82
|
+
},
|
|
83
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { describe, test } from 'vitest';
|
|
6
|
+
|
|
7
|
+
import { formatTime } from './format-time';
|
|
8
|
+
|
|
9
|
+
const NOW = new Date('2026-07-29T12:00:00Z').getTime();
|
|
10
|
+
|
|
11
|
+
describe('formatTime', () => {
|
|
12
|
+
test('renders an empty string for an unparseable timestamp', ({ expect }) => {
|
|
13
|
+
expect(formatTime('not a date', NOW)).toBe('');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('renders sub-minute ages in seconds', ({ expect }) => {
|
|
17
|
+
expect(formatTime(ago(20 * SECOND), NOW)).toMatch(/20 (seconds?|sec)/i);
|
|
18
|
+
// Never "0 seconds ago".
|
|
19
|
+
expect(formatTime(ago(200), NOW)).toMatch(/1 (second|sec)/i);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('renders minutes and hours relatively', ({ expect }) => {
|
|
23
|
+
expect(formatTime(ago(5 * MINUTE), NOW)).toMatch(/5 min/i);
|
|
24
|
+
expect(formatTime(ago(3 * HOUR), NOW)).toMatch(/3 (hours?|hr)/i);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('renders the previous day as yesterday', ({ expect }) => {
|
|
28
|
+
expect(formatTime(ago(26 * HOUR), NOW)).toMatch(/yesterday/i);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Two days is the cut-over: beyond it a date reads better than a growing "N days ago".
|
|
32
|
+
test('renders anything two days or older as a date', ({ expect }) => {
|
|
33
|
+
const older = formatTime(ago(2 * DAY), NOW);
|
|
34
|
+
expect(older).not.toMatch(/ago|yesterday/i);
|
|
35
|
+
expect(older).toMatch(/\d/);
|
|
36
|
+
expect(formatTime(ago(400 * DAY), NOW)).not.toMatch(/ago/i);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('stays just inside the relative window below two days', ({ expect }) => {
|
|
40
|
+
expect(formatTime(ago(2 * DAY - MINUTE), NOW)).toMatch(/ago|yesterday/i);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Clock skew across peers can date a message slightly in the future; a "in 3 minutes" prompt would
|
|
44
|
+
// read as a bug, so fall back to the absolute date.
|
|
45
|
+
test('renders a future timestamp as a date', ({ expect }) => {
|
|
46
|
+
expect(formatTime(new Date(NOW + 5 * MINUTE).toISOString(), NOW)).not.toMatch(/ago|in \d/i);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const SECOND = 1000;
|
|
51
|
+
const MINUTE = 60 * SECOND;
|
|
52
|
+
const HOUR = 60 * MINUTE;
|
|
53
|
+
const DAY = 24 * HOUR;
|
|
54
|
+
|
|
55
|
+
const ago = (elapsed: number) => new Date(NOW - elapsed).toISOString();
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, { useCallback } from 'react';
|
|
6
|
+
|
|
7
|
+
import { IconButton, useTranslation } from '@dxos/react-ui';
|
|
8
|
+
import { type XmlWidgetProps } from '@dxos/ui-editor';
|
|
9
|
+
|
|
10
|
+
import { meta } from '#meta';
|
|
11
|
+
|
|
12
|
+
import { type MessageThreadContext } from '../sync';
|
|
13
|
+
import { formatTime } from './format-time';
|
|
14
|
+
|
|
15
|
+
export type BranchWidgetProps = XmlWidgetProps<
|
|
16
|
+
{
|
|
17
|
+
/** Id of the message to rewind to. Named to avoid colliding with the widget's own `id` prop. */
|
|
18
|
+
messageId?: string;
|
|
19
|
+
/** ISO timestamp of the message. */
|
|
20
|
+
created?: string;
|
|
21
|
+
},
|
|
22
|
+
MessageThreadContext
|
|
23
|
+
>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Mini toolbar rendered below each user prompt, offering a soft fork ("rewind") back to that prompt
|
|
27
|
+
* along with when it was sent.
|
|
28
|
+
*/
|
|
29
|
+
export const BranchWidget = ({ messageId, created, context }: BranchWidgetProps) => {
|
|
30
|
+
const { t } = useTranslation(meta.profile.key);
|
|
31
|
+
|
|
32
|
+
const handleRewind = useCallback(() => {
|
|
33
|
+
if (messageId) {
|
|
34
|
+
context?.rewind(messageId);
|
|
35
|
+
}
|
|
36
|
+
}, [context, messageId]);
|
|
37
|
+
|
|
38
|
+
if (!messageId) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<div role='toolbar' className='flex items-center p-1 gap-1 justify-end text-xs text-subdued hover:text-inherit'>
|
|
44
|
+
<IconButton
|
|
45
|
+
classNames='min-h-0 p-1'
|
|
46
|
+
icon='ph--clock-counter-clockwise--regular'
|
|
47
|
+
iconOnly
|
|
48
|
+
variant='ghost'
|
|
49
|
+
size={4}
|
|
50
|
+
label={t('rewind.label')}
|
|
51
|
+
data-testid='chat.rewind'
|
|
52
|
+
onClick={handleRewind}
|
|
53
|
+
/>
|
|
54
|
+
{created && (
|
|
55
|
+
<time dateTime={created} title={new Date(created).toLocaleString()}>
|
|
56
|
+
{formatTime(created)}
|
|
57
|
+
</time>
|
|
58
|
+
)}
|
|
59
|
+
</div>
|
|
60
|
+
);
|
|
61
|
+
};
|
|
@@ -14,8 +14,8 @@ export const FallbackWidget = ({ _tag, ...props }: XmlWidgetProps<MessageThreadC
|
|
|
14
14
|
return (
|
|
15
15
|
<TogglePanel.Root>
|
|
16
16
|
<TogglePanel.Content>
|
|
17
|
-
<TogglePanel.Header classNames='
|
|
18
|
-
<TogglePanel.Body classNames='
|
|
17
|
+
<TogglePanel.Header classNames='dx-group-surface'>{_tag}</TogglePanel.Header>
|
|
18
|
+
<TogglePanel.Body classNames='dx-modal-surface'>
|
|
19
19
|
<TogglePanel.Viewport>
|
|
20
20
|
<JsonHighlighter classNames='p-2! text-sm' data={props} />
|
|
21
21
|
</TogglePanel.Viewport>
|
|
@@ -47,7 +47,7 @@ export class ReasoningWidget extends WidgetType {
|
|
|
47
47
|
.append(
|
|
48
48
|
Domino.of('div')
|
|
49
49
|
.classNames(
|
|
50
|
-
'relative z-10
|
|
50
|
+
'relative z-10 dx-base-surface rounded-sm text-sm text-subdued py-1',
|
|
51
51
|
'grid grid-cols-[24px_1fr] gap-x-0.5 items-start',
|
|
52
52
|
)
|
|
53
53
|
.append(
|
|
@@ -23,11 +23,6 @@ export class ReferenceWidget extends WidgetType {
|
|
|
23
23
|
override toDOM() {
|
|
24
24
|
return Domino.of('div')
|
|
25
25
|
.classNames(styles.padding)
|
|
26
|
-
.append(
|
|
27
|
-
Domino.of('dx-anchor' as any)
|
|
28
|
-
.classNames('dx-tag--anchor')
|
|
29
|
-
.attributes({ dxn: this.dxn })
|
|
30
|
-
.text(this.text),
|
|
31
|
-
).root;
|
|
26
|
+
.append(Domino.of('dx-anchor').classNames('dx-tag--anchor').attributes({ dxn: this.dxn }).text(this.text)).root;
|
|
32
27
|
}
|
|
33
28
|
}
|
|
@@ -20,18 +20,27 @@ export class SuggestionWidget extends WidgetType {
|
|
|
20
20
|
|
|
21
21
|
override toDOM() {
|
|
22
22
|
// NOTE: Container must have `dx-inline-size-container` (or `dx-size-container`) to support cqi.
|
|
23
|
+
//
|
|
24
|
+
// Inline-level root so consecutive suggestions flow onto one wrapped line rather than stacking —
|
|
25
|
+
// the tag is registered `block: false` and the renderer omits the usual block separator between
|
|
26
|
+
// them.
|
|
27
|
+
//
|
|
28
|
+
// Vertical space must be **padding, never margin**: CodeMirror measures a widget from its own box,
|
|
29
|
+
// and a margin sits outside what it can see, so the height model drifts from what is rendered, the
|
|
30
|
+
// error accumulates down the document, and the turn-fold gutter markers end up visibly misaligned.
|
|
31
|
+
// Adjacent chips are likewise spaced with trailing padding rather than a margin.
|
|
23
32
|
return Domino.of('span')
|
|
24
|
-
.classNames(mx('inline-flex max-w-[calc(100cqi-8px)]
|
|
33
|
+
.classNames(mx('inline-flex max-w-[calc(100cqi-8px)] py-1 pe-1 overflow-hidden'))
|
|
25
34
|
.append(
|
|
26
35
|
Domino.of('button')
|
|
27
36
|
.attributes({
|
|
28
|
-
'data-action': 'submit',
|
|
29
37
|
'data-density': 'md',
|
|
38
|
+
'data-action': 'submit',
|
|
30
39
|
'data-value': this.text,
|
|
31
40
|
})
|
|
32
41
|
.classNames(mx('dx-button gap-2 w-full overflow-hidden'))
|
|
33
42
|
.append(
|
|
34
|
-
Domino.of('dx-icon'
|
|
43
|
+
Domino.of('dx-icon').attributes({
|
|
35
44
|
icon: 'ph--lightning--regular',
|
|
36
45
|
}),
|
|
37
46
|
Domino.of('span').classNames('flex-1 truncate min-w-0').text(this.text),
|
|
@@ -19,7 +19,7 @@ export const SummaryWidget = ({ children }: XmlWidgetProps<MessageThreadContext>
|
|
|
19
19
|
return (
|
|
20
20
|
<TogglePanel.Root>
|
|
21
21
|
<TogglePanel.Content classNames={styles.border}>
|
|
22
|
-
<TogglePanel.Header classNames='text-sm
|
|
22
|
+
<TogglePanel.Header classNames='text-sm dx-group-surface'>{t('summary.label')}</TogglePanel.Header>
|
|
23
23
|
<TogglePanel.Body>
|
|
24
24
|
<div className='p-1 text-sm text-subdued'>{children}</div>
|
|
25
25
|
</TogglePanel.Body>
|
|
@@ -5,19 +5,15 @@
|
|
|
5
5
|
import type * as Tool from '@effect/ai/Tool';
|
|
6
6
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
7
7
|
|
|
8
|
-
import { Icon, useTranslation } from '@dxos/react-ui';
|
|
8
|
+
import { Icon, IconBlock, useTranslation } from '@dxos/react-ui';
|
|
9
9
|
import { NumericTabs, TextCrawl, TogglePanel, type TogglePanelRootProps } from '@dxos/react-ui-components';
|
|
10
10
|
import { JsonHighlighter } from '@dxos/react-ui-syntax-highlighter';
|
|
11
|
-
import { type ContentBlock
|
|
11
|
+
import { type ContentBlock } from '@dxos/types';
|
|
12
12
|
import { type XmlWidgetProps } from '@dxos/ui-editor';
|
|
13
13
|
import { isNonNullable, safeParseJson } from '@dxos/util';
|
|
14
14
|
|
|
15
15
|
import { meta } from '#meta';
|
|
16
16
|
|
|
17
|
-
export const isToolMessage = (message: Message.Message) => {
|
|
18
|
-
return message.blocks.some((block: ContentBlock.Any) => block._tag === 'toolCall' || block._tag === 'toolResult');
|
|
19
|
-
};
|
|
20
|
-
|
|
21
17
|
export type ToolWidgetProps = XmlWidgetProps<{
|
|
22
18
|
blocks: ContentBlock.Any[];
|
|
23
19
|
}>;
|
|
@@ -143,9 +139,19 @@ const ToolPanel = ({ items, onChangeOpen }: ToolPanelProps) => {
|
|
|
143
139
|
return (
|
|
144
140
|
<TogglePanel.Root open={open} onChangeOpen={setOpen}>
|
|
145
141
|
<TogglePanel.Content>
|
|
146
|
-
<TogglePanel.Header classNames='flex items-center gap-2 text-sm
|
|
147
|
-
<
|
|
148
|
-
|
|
142
|
+
<TogglePanel.Header classNames='flex items-center gap-2 text-sm'>
|
|
143
|
+
<div className='w-full grid grid-cols-[1fr_auto] items-center gap-2'>
|
|
144
|
+
<TextCrawl
|
|
145
|
+
key='status-roll'
|
|
146
|
+
classNames='text-description'
|
|
147
|
+
lines={items.map((item) => item.title)}
|
|
148
|
+
autoAdvance
|
|
149
|
+
greedy
|
|
150
|
+
/>
|
|
151
|
+
<IconBlock>
|
|
152
|
+
<Icon icon={headerIcon} size={4} />
|
|
153
|
+
</IconBlock>
|
|
154
|
+
</div>
|
|
149
155
|
</TogglePanel.Header>
|
|
150
156
|
<TogglePanel.Body>
|
|
151
157
|
<TogglePanel.Viewport classNames='grid grid-cols-[32px_1fr]'>
|
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
export const styles = {
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Vertical rhythm for block widgets. Padding, never margin: CodeMirror measures a widget from its own
|
|
8
|
+
* box, so a margin sits outside what it can see and its height model drifts from what is rendered —
|
|
9
|
+
* the error accumulates down the document until the turn-fold gutter markers are visibly misaligned.
|
|
10
|
+
* Note padding does not collapse between adjacent siblings the way margins do
|
|
11
|
+
*/
|
|
12
|
+
padding: 'pt-2 pb-4',
|
|
7
13
|
border: 'border border-subdued-separator rounded-sm',
|
|
8
14
|
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
// Kept out of `BranchWidget.tsx`: react-refresh only fast-refreshes a module whose
|
|
6
|
+
// exports are all components, so values exported beside them force a full page reload on
|
|
7
|
+
// every edit.
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Relative ("5 min ago", "yesterday") within two days, absolute date beyond that. The exact
|
|
11
|
+
* timestamp is always available via the `title` tooltip.
|
|
12
|
+
*
|
|
13
|
+
* Recent prompts are the ones a reader places by elapsed time; older ones by date.
|
|
14
|
+
*/
|
|
15
|
+
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
16
|
+
|
|
17
|
+
export const formatTime = (created: string, now = Date.now()): string => {
|
|
18
|
+
const date = new Date(created);
|
|
19
|
+
if (Number.isNaN(date.getTime())) {
|
|
20
|
+
return '';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const elapsed = now - date.getTime();
|
|
24
|
+
if (elapsed < 0 || elapsed >= 2 * DAY_MS) {
|
|
25
|
+
return date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const format = new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' });
|
|
29
|
+
const minutes = Math.round(elapsed / 60_000);
|
|
30
|
+
if (minutes < 1) {
|
|
31
|
+
// Seconds rather than `format(0, 'minute')`, which renders as "this minute".
|
|
32
|
+
return format.format(-Math.max(1, Math.round(elapsed / 1000)), 'second');
|
|
33
|
+
}
|
|
34
|
+
if (minutes < 60) {
|
|
35
|
+
return format.format(-minutes, 'minute');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const hours = Math.round(minutes / 60);
|
|
39
|
+
if (hours < 24) {
|
|
40
|
+
return format.format(-hours, 'hour');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// `numeric: 'auto'` renders -1 day as "yesterday".
|
|
44
|
+
return format.format(-Math.round(hours / 24), 'day');
|
|
45
|
+
};
|
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
// Copyright 2026 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
export * from './format-time';
|
|
6
|
+
export * from './BranchWidget';
|
|
5
7
|
export * from './FallbackWidget';
|
|
6
8
|
export * from './ReasoningWidget';
|
|
7
9
|
export * from './ReferenceWidget';
|
|
8
10
|
export * from './SelectWidget';
|
|
9
11
|
export * from './StatsWidget';
|
|
10
12
|
export * from './StatusWidget';
|
|
13
|
+
export * from './SuggestionWidget';
|
|
11
14
|
export * from './SummaryWidget';
|
|
12
15
|
export * from './SurfaceWidget';
|
|
13
|
-
export * from './
|
|
16
|
+
export * from './is-tool-message';
|
|
14
17
|
export * from './ToolWidget';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ContentBlock, type Message } from '@dxos/types';
|
|
6
|
+
|
|
7
|
+
// Kept out of `ToolWidget.tsx`: react-refresh only fast-refreshes a module whose
|
|
8
|
+
// exports are all components, so values exported beside them force a full page reload on
|
|
9
|
+
// every edit.
|
|
10
|
+
|
|
11
|
+
export const isToolMessage = (message: Message.Message) => {
|
|
12
|
+
return message.blocks.some((block: ContentBlock.Any) => block._tag === 'toolCall' || block._tag === 'toolResult');
|
|
13
|
+
};
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { RegistryContext } from '@effect-atom/atom-react';
|
|
6
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
7
|
+
import * as Effect from 'effect/Effect';
|
|
8
|
+
import * as Schema from 'effect/Schema';
|
|
9
|
+
import React, { useContext, useMemo } from 'react';
|
|
10
|
+
|
|
11
|
+
import { Capability } from '@dxos/app-framework';
|
|
12
|
+
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
13
|
+
import { useCapabilities } from '@dxos/app-framework/ui';
|
|
14
|
+
import { AppActivationEvents } from '@dxos/app-toolkit';
|
|
15
|
+
import { Filter, Obj, Ref } from '@dxos/echo';
|
|
16
|
+
import { useQuery } from '@dxos/echo-react';
|
|
17
|
+
import { AccessToken, Cursor } from '@dxos/link';
|
|
18
|
+
import { ClientPlugin, initializeIdentity } from '@dxos/plugin-client/testing';
|
|
19
|
+
import { Connection, Connector, type ConnectorEntry, connectorAuthActions } from '@dxos/plugin-connector';
|
|
20
|
+
import { translations as connectorTranslations } from '@dxos/plugin-connector/translations';
|
|
21
|
+
import { Graph } from '@dxos/plugin-graph';
|
|
22
|
+
import { useActionRunner } from '@dxos/plugin-graph/hooks';
|
|
23
|
+
import { corePlugins } from '@dxos/plugin-testing';
|
|
24
|
+
import { useSpaces } from '@dxos/react-client/echo';
|
|
25
|
+
import { Menu, isToolbarAction, useGraphMenuActions } from '@dxos/react-ui-menu';
|
|
26
|
+
import { Loading, withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
27
|
+
import { Expando } from '@dxos/schema';
|
|
28
|
+
|
|
29
|
+
import { translations } from '#translations';
|
|
30
|
+
|
|
31
|
+
import { ConnectorAuthMenu } from './ConnectorAuthMenu';
|
|
32
|
+
|
|
33
|
+
/** `connector-b` already has a Connection below, so it renders as a "reuse" entry; `connector-a` has
|
|
34
|
+
* none, so it renders as a "Connect" entry — together they exercise both item kinds and the
|
|
35
|
+
* separator between them. `Default` renders the `ConnectorAuthMenu` component. `Toolbar` feeds the
|
|
36
|
+
* same `connectorAuthActions` atom into an object toolbar the way studio/ibkr/inbox do. */
|
|
37
|
+
const CredentialSchema = Schema.Struct({ apiKey: Schema.String.annotations({ title: 'API key' }) });
|
|
38
|
+
|
|
39
|
+
const makeCredentialForm = (connectorId: string) => ({
|
|
40
|
+
schema: CredentialSchema,
|
|
41
|
+
onSubmit: () => {
|
|
42
|
+
const accessToken = AccessToken.make({ source: `${connectorId}.example`, token: 'mock-token' });
|
|
43
|
+
return Effect.succeed({
|
|
44
|
+
kind: 'complete' as const,
|
|
45
|
+
accessToken,
|
|
46
|
+
connection: Connection.make({ connectorId, accessToken: Ref.make(accessToken) }),
|
|
47
|
+
});
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const testConnectors: ConnectorEntry[] = [
|
|
52
|
+
{
|
|
53
|
+
id: 'connector-a',
|
|
54
|
+
source: 'connector-a.example',
|
|
55
|
+
label: 'Connector A',
|
|
56
|
+
credentialForm: makeCredentialForm('connector-a'),
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: 'connector-b',
|
|
60
|
+
source: 'connector-b.example',
|
|
61
|
+
label: 'Connector B',
|
|
62
|
+
credentialForm: makeCredentialForm('connector-b'),
|
|
63
|
+
},
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
const CONNECTOR_IDS = ['connector-a', 'connector-b'];
|
|
67
|
+
|
|
68
|
+
const ComponentStory = () => {
|
|
69
|
+
const [space] = useSpaces();
|
|
70
|
+
const targets = useQuery(space?.db, Filter.type(Expando.Expando));
|
|
71
|
+
const target = targets[0];
|
|
72
|
+
|
|
73
|
+
if (!space || !target) {
|
|
74
|
+
return <Loading />;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<div className='p-4'>
|
|
79
|
+
<ConnectorAuthMenu connectorIds={CONNECTOR_IDS} db={space.db} existingTarget={Ref.make(target)} />
|
|
80
|
+
</div>
|
|
81
|
+
);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const TOOLBAR_NODE_ID = 'story-toolbar-target';
|
|
85
|
+
|
|
86
|
+
const ToolbarStory = () => {
|
|
87
|
+
const [space] = useSpaces();
|
|
88
|
+
const registry = useContext(RegistryContext);
|
|
89
|
+
const runAction = useActionRunner();
|
|
90
|
+
const allConnectors = useCapabilities(Connector).flat();
|
|
91
|
+
const allConnections = useQuery(space?.db, Filter.type(Connection.Connection));
|
|
92
|
+
const targets = useQuery(space?.db, Filter.type(Expando.Expando));
|
|
93
|
+
const target = targets[0];
|
|
94
|
+
|
|
95
|
+
const graph = useMemo(() => {
|
|
96
|
+
if (!space?.db || !target) {
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
const actions = connectorAuthActions({
|
|
100
|
+
connectorIds: CONNECTOR_IDS,
|
|
101
|
+
db: space.db,
|
|
102
|
+
spaceId: space.db.spaceId,
|
|
103
|
+
existingTarget: Ref.make(target),
|
|
104
|
+
allConnectors,
|
|
105
|
+
allConnections,
|
|
106
|
+
});
|
|
107
|
+
const nextGraph = Graph.make({ registry });
|
|
108
|
+
nextGraph.pipe(
|
|
109
|
+
Graph.addNodes([{ id: TOOLBAR_NODE_ID, type: 'story/toolbar-target', data: null, properties: {}, actions }]),
|
|
110
|
+
);
|
|
111
|
+
return nextGraph;
|
|
112
|
+
}, [registry, space, target, allConnectors, allConnections]);
|
|
113
|
+
|
|
114
|
+
const menuActions = useGraphMenuActions(graph, TOOLBAR_NODE_ID, { filter: isToolbarAction });
|
|
115
|
+
|
|
116
|
+
if (!space || !target) {
|
|
117
|
+
return <Loading />;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return (
|
|
121
|
+
<div className='p-4 border border-separator rounded-sm'>
|
|
122
|
+
<Menu.Root {...menuActions} onAction={runAction} attendableId={TOOLBAR_NODE_ID} alwaysActive>
|
|
123
|
+
<Menu.Toolbar />
|
|
124
|
+
</Menu.Root>
|
|
125
|
+
</div>
|
|
126
|
+
);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const meta = {
|
|
130
|
+
title: 'plugins/plugin-assistant/components/ConnectorAuthMenu',
|
|
131
|
+
decorators: [
|
|
132
|
+
withTheme(),
|
|
133
|
+
withLayout({ layout: 'column' }),
|
|
134
|
+
withPluginManager({
|
|
135
|
+
setupEvents: [AppActivationEvents.SetupSettings],
|
|
136
|
+
capabilities: [Capability.contributes(Connector, testConnectors)],
|
|
137
|
+
plugins: [
|
|
138
|
+
...corePlugins(),
|
|
139
|
+
ClientPlugin({
|
|
140
|
+
types: [Connection.Connection, Cursor.Cursor, Expando.Expando],
|
|
141
|
+
onClientInitialized: ({ client }) =>
|
|
142
|
+
Effect.gen(function* () {
|
|
143
|
+
yield* initializeIdentity(client);
|
|
144
|
+
const [space] = client.spaces.get();
|
|
145
|
+
yield* Effect.promise(() => space.waitUntilReady());
|
|
146
|
+
|
|
147
|
+
// `connector-b` already has a connection — offered for reuse.
|
|
148
|
+
const accessToken = AccessToken.make({ source: 'connector-b.example', token: 'mock-token' });
|
|
149
|
+
space.db.add(
|
|
150
|
+
Connection.make({
|
|
151
|
+
name: 'Existing Connector B',
|
|
152
|
+
connectorId: 'connector-b',
|
|
153
|
+
accessToken: Ref.make(accessToken),
|
|
154
|
+
}),
|
|
155
|
+
);
|
|
156
|
+
// Local target the reuse/connect flow would bind a new sync target to.
|
|
157
|
+
space.db.add(Obj.make(Expando.Expando, { name: 'Target Object' }));
|
|
158
|
+
|
|
159
|
+
yield* Effect.promise(() => space.db.flush({ indexes: true }));
|
|
160
|
+
}),
|
|
161
|
+
}),
|
|
162
|
+
],
|
|
163
|
+
}),
|
|
164
|
+
],
|
|
165
|
+
parameters: {
|
|
166
|
+
layout: 'fullscreen',
|
|
167
|
+
translations: [...translations, ...connectorTranslations],
|
|
168
|
+
},
|
|
169
|
+
} satisfies Meta<React.ComponentType>;
|
|
170
|
+
|
|
171
|
+
export default meta;
|
|
172
|
+
|
|
173
|
+
type Story = StoryObj<typeof meta>;
|
|
174
|
+
|
|
175
|
+
export const Default: Story = { render: ComponentStory };
|
|
176
|
+
|
|
177
|
+
export const Toolbar: Story = { render: ToolbarStory };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { RegistryContext } from '@effect-atom/atom-react';
|
|
6
|
+
import React, { useContext, useMemo } from 'react';
|
|
7
|
+
|
|
8
|
+
import { useCapabilities } from '@dxos/app-framework/ui';
|
|
9
|
+
import { type Database, Filter, type Obj, type Ref } from '@dxos/echo';
|
|
10
|
+
import { useQuery } from '@dxos/echo-react';
|
|
11
|
+
import { Connection, Connector, CONNECTOR_AUTH_GROUP_ID, connectorAuthActions } from '@dxos/plugin-connector';
|
|
12
|
+
import { Graph } from '@dxos/plugin-graph';
|
|
13
|
+
import { useActionRunner } from '@dxos/plugin-graph/hooks';
|
|
14
|
+
import { IconButton, useTranslation } from '@dxos/react-ui';
|
|
15
|
+
import { Menu, useGraphMenuActions } from '@dxos/react-ui-menu';
|
|
16
|
+
|
|
17
|
+
import { meta } from '#meta';
|
|
18
|
+
|
|
19
|
+
/** Root node the connector-auth group hangs off in the component's local graph. */
|
|
20
|
+
const NODE_ID = 'connector-auth-root';
|
|
21
|
+
|
|
22
|
+
export type ConnectorAuthMenuProps = {
|
|
23
|
+
/** Stable ids of the {@link Connector} entries this menu offers: existing connections from any of
|
|
24
|
+
* them are offered for reuse, and each (with an auth flow) gets a "Connect X" entry. */
|
|
25
|
+
connectorIds: readonly string[];
|
|
26
|
+
/** Omitted when there is no active database yet (e.g. no space selected) — nothing is offered. */
|
|
27
|
+
db: Database.Database | undefined;
|
|
28
|
+
/** Existing local object to wire up as the new connection's first sync target. */
|
|
29
|
+
existingTarget?: Ref.Ref<Obj.Unknown>;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Standalone connector-auth menu: a trigger button that opens a dropdown of the same
|
|
34
|
+
* {@link connectorAuthActions} owning plugins contribute to object toolbars. Existing
|
|
35
|
+
* {@link Connection}s are offered for reuse (bind inline) alongside a "Connect X" entry per connector
|
|
36
|
+
* with an auth flow. Renders nothing when there is nothing to offer.
|
|
37
|
+
*/
|
|
38
|
+
export const ConnectorAuthMenu = ({ connectorIds, db, existingTarget }: ConnectorAuthMenuProps) => {
|
|
39
|
+
const { t } = useTranslation(meta.profile.key);
|
|
40
|
+
const registry = useContext(RegistryContext);
|
|
41
|
+
const runAction = useActionRunner();
|
|
42
|
+
const allConnectors = useCapabilities(Connector).flat();
|
|
43
|
+
const allConnections = useQuery(db, Filter.type(Connection.Connection));
|
|
44
|
+
|
|
45
|
+
const graph = useMemo(() => {
|
|
46
|
+
if (!db) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
const actions = connectorAuthActions({
|
|
50
|
+
connectorIds,
|
|
51
|
+
db,
|
|
52
|
+
spaceId: db.spaceId,
|
|
53
|
+
existingTarget,
|
|
54
|
+
allConnectors,
|
|
55
|
+
allConnections,
|
|
56
|
+
});
|
|
57
|
+
if (actions.length === 0) {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
const nextGraph = Graph.make({ registry });
|
|
61
|
+
nextGraph.pipe(Graph.addNodes([{ id: NODE_ID, type: NODE_ID, data: null, properties: {}, actions }]));
|
|
62
|
+
return nextGraph;
|
|
63
|
+
}, [registry, connectorIds, db, existingTarget, allConnectors, allConnections]);
|
|
64
|
+
|
|
65
|
+
// Read the group's children (reuse / connect entries) as the menu content.
|
|
66
|
+
const menuActions = useGraphMenuActions(graph, CONNECTOR_AUTH_GROUP_ID);
|
|
67
|
+
|
|
68
|
+
if (!graph) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<Menu.Root {...menuActions} onAction={runAction} attendableId={NODE_ID} alwaysActive>
|
|
74
|
+
<Menu.Trigger asChild>
|
|
75
|
+
<IconButton variant='ghost' icon='ph--plugs--regular' label={t('connect.label')} />
|
|
76
|
+
</Menu.Trigger>
|
|
77
|
+
<Menu.Content />
|
|
78
|
+
</Menu.Root>
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
ConnectorAuthMenu.displayName = 'ConnectorAuthMenu';
|