@ai-matrx/chat 0.6.6 → 0.7.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/CHANGELOG.md +42 -0
- package/README.md +1 -1
- package/dist/agents/components/agent-widgets/AgentChatHistorySidebar.js +16 -55
- package/dist/agents/components/chat/chat-door.d.ts +67 -0
- package/dist/agents/components/chat/chat-door.js +100 -0
- package/dist/agents/components/conversation-history/AgentConversationList.d.ts +83 -0
- package/dist/agents/components/conversation-history/AgentConversationList.js +252 -0
- package/dist/agents/components/conversation-history/ConversationArchiveSection.d.ts +5 -1
- package/dist/agents/components/conversation-history/ConversationArchiveSection.js +22 -4
- package/dist/agents/components/conversation-history/ConversationHistorySidebar.js +20 -65
- package/dist/agents/components/inputs/input-components/TextareaInput.js +2 -0
- package/dist/agents/components/inputs/input-components/VariableInputComponent.js +7 -6
- package/dist/agents/components/inputs/smart-input/ConversationCompanionPills.d.ts +3 -0
- package/dist/agents/components/inputs/smart-input/ConversationCompanionPills.js +40 -0
- package/dist/agents/components/inputs/smart-input/ConversationContextRail.js +6 -29
- package/dist/agents/components/inputs/smart-input/DeviceToolsModeRow.d.ts +3 -0
- package/dist/agents/components/inputs/smart-input/DeviceToolsModeRow.js +35 -0
- package/dist/agents/components/inputs/smart-input/InboxQueueStrip.js +0 -8
- package/dist/agents/components/inputs/smart-input/RunToolPicker.js +15 -11
- package/dist/agents/components/inputs/smart-input/composer/ComposerPlusMenu.js +22 -0
- package/dist/agents/components/inputs/smart-input/rail-pill.d.ts +35 -0
- package/dist/agents/components/inputs/smart-input/rail-pill.js +30 -0
- package/dist/agents/components/inputs/variable-input-variations/AgentVariableForm.js +52 -48
- package/dist/agents/components/run-controls/panels/shared.d.ts +1 -1
- package/dist/agents/components/shared/AgentModeController.js +3 -2
- package/dist/agents/components/shell/AgentRunSidebarMenu.js +15 -54
- package/dist/agents/components/working-document/documents-workspace/DocumentsListRail.js +1 -2
- package/dist/agents/engine.d.ts +15 -0
- package/dist/agents/engine.js +17 -0
- package/dist/agents/hooks/useModelControls.js +3 -175
- package/dist/agents/redux/agent-definition/selectors.d.ts +237 -237
- package/dist/agents/redux/agent-shortcut-categories/selectors.d.ts +50 -50
- package/dist/agents/redux/agent-shortcuts/selectors.d.ts +147 -147
- package/dist/agents/redux/conversation-history/thunks.js +6 -18
- package/dist/agents/redux/conversation-list/conversation-list.selectors.d.ts +1 -73
- package/dist/agents/redux/conversation-list/conversation-list.selectors.js +2 -36
- package/dist/agents/redux/conversation-list/conversation-list.slice.d.ts +7 -22
- package/dist/agents/redux/conversation-list/conversation-list.slice.js +7 -62
- package/dist/agents/redux/conversation-list/conversation-list.thunks.d.ts +0 -25
- package/dist/agents/redux/conversation-list/conversation-list.thunks.js +2 -58
- package/dist/agents/redux/conversation-list/conversation-list.types.d.ts +0 -5
- package/dist/agents/redux/conversation-list/conversation-rows.d.ts +16 -0
- package/dist/agents/redux/conversation-list/conversation-rows.js +24 -0
- package/dist/agents/redux/conversation-list/conversation-trash.thunks.d.ts +1 -0
- package/dist/agents/redux/conversation-list/conversation-trash.thunks.js +13 -18
- package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.d.ts +54 -54
- package/dist/agents/redux/execution-system/context-state/context-state.selectors.d.ts +14 -14
- package/dist/agents/redux/execution-system/conversations/conversations.selectors.d.ts +5 -5
- package/dist/agents/redux/execution-system/instance-context/instance-context.selectors.d.ts +3 -3
- package/dist/agents/redux/execution-system/instance-resources/instance-resources.selectors.d.ts +8 -8
- package/dist/agents/redux/execution-system/instance-ui-state/instance-ui-state.selectors.d.ts +5 -5
- package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.selectors.d.ts +7 -7
- package/dist/agents/redux/execution-system/messages/messages.selectors.d.ts +1 -1
- package/dist/agents/redux/execution-system/observability/observability.selectors.d.ts +7 -7
- package/dist/agents/redux/execution-system/observational-memory/observational-memory.selectors.d.ts +1 -1
- package/dist/agents/redux/execution-system/selectors/aggregate.selectors.d.ts +14 -14
- package/dist/agents/redux/execution-system/thunks/create-instance.thunk.d.ts +10 -1
- package/dist/agents/redux/execution-system/thunks/create-instance.thunk.js +114 -265
- package/dist/agents/redux/execution-system/thunks/dispatch-matrx-extend-tool.thunk.js +18 -2
- package/dist/agents/redux/execution-system/thunks/dispatch-surface-client-tool.thunk.js +10 -28
- package/dist/agents/redux/execution-system/thunks/dispatch-surface-write.thunk.js +10 -25
- package/dist/agents/redux/execution-system/thunks/execute-instance.thunk.js +20 -0
- package/dist/agents/redux/execution-system/thunks/execute-manual-instance.thunk.js +6 -1
- package/dist/agents/redux/execution-system/thunks/notify-and-play-dispatcher.d.ts +58 -0
- package/dist/agents/redux/execution-system/thunks/notify-and-play-dispatcher.js +62 -0
- package/dist/agents/redux/execution-system/thunks/post-delegated-tool-outcome.d.ts +23 -0
- package/dist/agents/redux/execution-system/thunks/post-delegated-tool-outcome.js +37 -0
- package/dist/agents/redux/execution-system/thunks/resume-instance.thunk.js +10 -2
- package/dist/agents/redux/execution-system/utils/build-tool-injection.d.ts +7 -0
- package/dist/agents/redux/execution-system/utils/build-tool-injection.js +18 -6
- package/dist/agents/redux/execution-system/utils/host-turn.d.ts +45 -0
- package/dist/agents/redux/execution-system/utils/host-turn.js +119 -0
- package/dist/agents/redux/proposed-directives/proposedDirectivesSlice.d.ts +1 -1
- package/dist/agents/scribe-tools/dispatcher/dispatch-scribe-tool.thunk.d.ts +50 -20
- package/dist/agents/scribe-tools/dispatcher/dispatch-scribe-tool.thunk.js +9 -101
- package/dist/agents/types/tool-injection.types.d.ts +18 -2
- package/dist/agents/ui-first-tools/redux/agent-lists.selectors.d.ts +2 -2
- package/dist/agents/ui-first-tools/redux/pending-asks.slice.d.ts +2 -1
- package/dist/agents/ui-first-tools/redux/resolve-asks-with-input.thunk.js +1 -1
- package/dist/agents/ui-first-tools/tools/ask-response.d.ts +29 -0
- package/dist/agents/ui-first-tools/tools/ask-response.js +15 -0
- package/dist/agents/ui-first-tools/tools/schemas.d.ts +3 -25
- package/dist/agents/ui-first-tools/tools/schemas.js +1 -12
- package/dist/agents/ui-first-tools/ui/ApprovalCard.js +1 -1
- package/dist/agents/ui-first-tools/ui/AskWizard.d.ts +1 -1
- package/dist/agents/ui-first-tools/ui/AskWizard.js +1 -1
- package/dist/cx-chat/_legacy-stubs.d.ts +5 -5
- package/dist/cx-chat/components/SsrSidebarChats.js +13 -15
- package/dist/cx-chat/components/messages/UserMessage.d.ts +2 -2
- package/dist/cx-chat/types/conversation.d.ts +6 -6
- package/dist/cx-chat/utils/buildContentBlocksForSave.d.ts +1 -1
- package/dist/cx-chat/utils/cx-content-converter.d.ts +1 -1
- package/dist/host/bare-host-chrome.js +9 -3
- package/dist/host/composer-extensions.d.ts +75 -0
- package/dist/host/composer-extensions.js +92 -0
- package/dist/host/configure.js +1 -0
- package/dist/host/contract.d.ts +105 -13
- package/dist/host/defaults/confirm.d.ts +15 -0
- package/dist/host/defaults/confirm.js +25 -0
- package/dist/host/defaults/files-ui.d.ts +85 -0
- package/dist/host/defaults/files-ui.js +158 -0
- package/dist/host/defaults/gates.d.ts +27 -0
- package/dist/host/defaults/gates.js +72 -0
- package/dist/host/defaults/media-client.d.ts +15 -0
- package/dist/host/defaults/media-client.js +40 -0
- package/dist/host/defaults/voice.d.ts +81 -0
- package/dist/host/defaults/voice.js +239 -0
- package/dist/host/device-tool-handoff.d.ts +26 -0
- package/dist/host/device-tool-handoff.js +45 -0
- package/dist/host/index.d.ts +1 -0
- package/dist/host/index.js +4 -1
- package/dist/host/microphone.d.ts +11 -0
- package/dist/host/microphone.js +17 -0
- package/dist/host/ui-slots.d.ts +29 -74
- package/dist/host/ui-slots.js +40 -42
- package/dist/store/create-chat-store.d.ts +2 -2
- package/dist/store/middlewares.d.ts +5 -5
- package/dist/store/slices.d.ts +1 -1
- package/dist/surfaces/redux/selectors.d.ts +2 -2
- package/dist/tool-call-visualization/components/ToolCallVisualization.js +3 -2
- package/dist/tool-call-visualization/configured-rows/ConfiguredRowRenderer.d.ts +15 -0
- package/dist/tool-call-visualization/configured-rows/ConfiguredRowRenderer.js +36 -0
- package/dist/tool-call-visualization/configured-rows/ConfiguredToolRow.d.ts +40 -0
- package/dist/tool-call-visualization/configured-rows/ConfiguredToolRow.js +296 -0
- package/dist/tool-call-visualization/configured-rows/CopyToolButton.d.ts +23 -0
- package/dist/tool-call-visualization/configured-rows/CopyToolButton.js +62 -0
- package/dist/tool-call-visualization/configured-rows/ToolProgressView.d.ts +23 -0
- package/dist/tool-call-visualization/configured-rows/ToolProgressView.js +147 -0
- package/dist/tool-call-visualization/configured-rows/field-components.d.ts +15 -0
- package/dist/tool-call-visualization/configured-rows/field-components.js +244 -0
- package/dist/tool-call-visualization/configured-rows/helpers.d.ts +39 -0
- package/dist/tool-call-visualization/configured-rows/helpers.js +110 -0
- package/dist/tool-call-visualization/configured-rows/register.d.ts +25 -0
- package/dist/tool-call-visualization/configured-rows/register.js +51 -0
- package/dist/tool-call-visualization/configured-rows/registries.d.ts +27 -0
- package/dist/tool-call-visualization/configured-rows/registries.js +14 -0
- package/dist/tool-call-visualization/configured-rows/to-row-entry.d.ts +8 -0
- package/dist/tool-call-visualization/configured-rows/to-row-entry.js +38 -0
- package/dist/tool-call-visualization/configured-rows/transforms.d.ts +14 -0
- package/dist/tool-call-visualization/configured-rows/transforms.js +30 -0
- package/dist/tool-call-visualization/configured-rows/types.d.ts +140 -0
- package/dist/tool-call-visualization/redux/selectors.d.ts +1 -1
- package/dist/tool-call-visualization/registry/registry.d.ts +1 -1
- package/dist/tool-call-visualization/registry/registry.js +8 -1
- package/dist/tool-call-visualization/types.d.ts +1 -1
- package/dist/ui/chat-protocol-types.d.ts +0 -1
- package/dist/ui/ownership.d.ts +25 -0
- package/dist/ui/ownership.js +18 -0
- package/dist/voice-agent/audio/audioCapture.js +11 -6
- package/dist/window-panels/windows/agents/AgentRunHistoryWindow.d.ts +1 -2
- package/dist/window-panels/windows/agents/AgentRunHistoryWindow.js +21 -181
- package/dist/window-panels/windows/agents/AgentRunWindow.js +26 -13
- package/package.json +4627 -125
- package/dist/agents/components/agent-widgets/chat-assistant/AssistantMessageCard.d.ts +0 -7
- package/dist/agents/components/agent-widgets/chat-assistant/AssistantMessageCard.js +0 -33
- package/dist/agents/components/agent-widgets/chat-assistant/StatusCard.d.ts +0 -6
- package/dist/agents/components/agent-widgets/chat-assistant/StatusCard.js +0 -21
- package/dist/agents/components/agent-widgets/chat-assistant/UserMessageCard.d.ts +0 -6
- package/dist/agents/components/agent-widgets/chat-assistant/UserMessageCard.js +0 -11
- package/dist/agents/components/agent-widgets/chat-assistant/VariableInputCard.d.ts +0 -12
- package/dist/agents/components/agent-widgets/chat-assistant/VariableInputCard.js +0 -7
- package/dist/agents/components/agent-widgets/execution-gates/PreExecutionCard.d.ts +0 -4
- package/dist/agents/components/agent-widgets/execution-gates/PreExecutionCard.js +0 -81
- package/dist/agents/components/run/run-sidebar/SidebarHeader.d.ts +0 -21
- package/dist/agents/components/run/run-sidebar/SidebarHeader.js +0 -50
- package/dist/agents/components/run-controls/AdvancedRunSettings/index.d.ts +0 -6
- package/dist/agents/components/run-controls/AdvancedRunSettings/index.js +0 -32
- package/dist/agents/components/run-controls/RunSettingsModal.d.ts +0 -5
- package/dist/agents/components/run-controls/RunSettingsModal.js +0 -22
- package/dist/agents/components/shell/AgentBuildSidebarExtras.d.ts +0 -6
- package/dist/agents/components/shell/AgentBuildSidebarExtras.js +0 -30
- package/dist/agents/constants/agent-system-competitors.d.ts +0 -9
- package/dist/agents/constants/agent-system-competitors.js +0 -125
- package/dist/agents/hooks/message-crud/useMessageActions.d.ts +0 -29
- package/dist/agents/hooks/message-crud/useMessageActions.js +0 -119
- package/dist/agents/hooks/useConversationPendingCalls.d.ts +0 -30
- package/dist/agents/hooks/useConversationPendingCalls.js +0 -42
- package/dist/agents/model-registry/model-classes.d.ts +0 -1
- package/dist/agents/model-registry/model-classes.js +0 -1
- package/dist/agents/redux/conversation-history/index.d.ts +0 -18
- package/dist/agents/redux/conversation-history/index.js +0 -4
- package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.thunks.d.ts +0 -38
- package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.thunks.js +0 -42
- package/dist/agents/redux/execution-system/message-crud/server/compact-turns.thunk.d.ts +0 -58
- package/dist/agents/redux/execution-system/message-crud/server/compact-turns.thunk.js +0 -50
- package/dist/agents/redux/execution-system/message-crud/server/fork-and-run-server.thunk.d.ts +0 -76
- package/dist/agents/redux/execution-system/message-crud/server/fork-and-run-server.thunk.js +0 -101
- package/dist/agents/redux/execution-system/thunks/attach-workflow-run.d.ts +0 -38
- package/dist/agents/redux/execution-system/thunks/attach-workflow-run.js +0 -25
- package/dist/agents/redux/execution-system/utils/source-slice-helpers.d.ts +0 -45
- package/dist/agents/redux/execution-system/utils/source-slice-helpers.js +0 -50
- package/dist/agents/runtime/realtime/launchRealtimeSession.thunk.d.ts +0 -25
- package/dist/agents/runtime/realtime/launchRealtimeSession.thunk.js +0 -15
- package/dist/agents/services/agentService.d.ts +0 -12
- package/dist/agents/services/agentService.js +0 -92
- package/dist/agents/utils/escape-code-fences.d.ts +0 -15
- package/dist/agents/utils/escape-code-fences.js +0 -9
- package/dist/agents/utils/normalize-managed-options.d.ts +0 -30
- package/dist/agents/utils/normalize-managed-options.js +0 -29
- package/dist/agents/utils/processedDocumentContext.d.ts +0 -51
- package/dist/agents/utils/processedDocumentContext.js +0 -51
- package/dist/agents/utils/variable-validation.d.ts +0 -28
- package/dist/agents/utils/variable-validation.js +0 -54
- package/dist/cx-chat/components/ChatConversationSkeleton.d.ts +0 -9
- package/dist/cx-chat/components/ChatConversationSkeleton.js +0 -45
- package/dist/cx-chat/components/ChatPanelBackButton.d.ts +0 -1
- package/dist/cx-chat/components/ChatPanelBackButton.js +0 -26
- package/dist/cx-chat/components/messages/MessageErrorBoundary.d.ts +0 -20
- package/dist/cx-chat/components/messages/MessageErrorBoundary.js +0 -40
- package/dist/cx-chat/components/variable-inputs/CheckboxGroupInput.d.ts +0 -14
- package/dist/cx-chat/components/variable-inputs/CheckboxGroupInput.js +0 -160
- package/dist/cx-chat/components/variable-inputs/NumberInput.d.ts +0 -15
- package/dist/cx-chat/components/variable-inputs/NumberInput.js +0 -79
- package/dist/cx-chat/components/variable-inputs/RadioGroupInput.d.ts +0 -14
- package/dist/cx-chat/components/variable-inputs/RadioGroupInput.js +0 -125
- package/dist/cx-chat/components/variable-inputs/SelectInput.d.ts +0 -14
- package/dist/cx-chat/components/variable-inputs/SelectInput.js +0 -92
- package/dist/cx-chat/components/variable-inputs/TextareaInput.d.ts +0 -14
- package/dist/cx-chat/components/variable-inputs/TextareaInput.js +0 -46
- package/dist/cx-chat/components/variable-inputs/ToggleInput.d.ts +0 -14
- package/dist/cx-chat/components/variable-inputs/ToggleInput.js +0 -46
- package/dist/cx-chat/hooks/useChatPersistence.d.ts +0 -28
- package/dist/cx-chat/hooks/useChatPersistence.js +0 -180
- package/dist/cx-chat/hooks/useInstanceBootstrap.d.ts +0 -1
- package/dist/cx-chat/hooks/useInstanceBootstrap.js +0 -115
- package/dist/cx-chat/types/content.d.ts +0 -184
- package/dist/cx-chat/types/content.js +0 -91
- package/dist/cx-chat/types/cx-tables.d.ts +0 -176
- package/dist/cx-chat/utils/settings-diff.d.ts +0 -13
- package/dist/cx-chat/utils/settings-diff.js +0 -25
- package/dist/public-chat/components/AgentSelector.d.ts +0 -22
- package/dist/public-chat/components/AgentSelector.js +0 -80
- package/dist/public-chat/components/GuidedVariableInputs.d.ts +0 -25
- package/dist/public-chat/components/GuidedVariableInputs.js +0 -623
- package/dist/public-chat/components/PublicVariableInputs.d.ts +0 -29
- package/dist/public-chat/components/PublicVariableInputs.js +0 -172
- package/dist/public-chat/types/content.d.ts +0 -184
- package/dist/public-chat/types/content.js +0 -91
- package/dist/tool-call-visualization/renderers/_shared-entity/EntityOpenActions.d.ts +0 -15
- package/dist/tool-call-visualization/renderers/_shared-entity/EntityOpenActions.js +0 -31
- package/dist/tool-call-visualization/utils/toolCallBlockToLifecycleEntry.d.ts +0 -24
- package/dist/tool-call-visualization/utils/toolCallBlockToLifecycleEntry.js +0 -26
- package/dist/ui/AudioOutputBlockSkeleton.d.ts +0 -17
- package/dist/ui/AudioOutputBlockSkeleton.js +0 -78
- package/dist/ui/lazy/PublicChatVariableInputs.d.ts +0 -2
- package/dist/ui/lazy/PublicChatVariableInputs.js +0 -16
- package/dist/utils/xml/readXmlTag.d.ts +0 -12
- package/dist/utils/xml/readXmlTag.js +0 -66
- /package/dist/{cx-chat/types/cx-tables.js → tool-call-visualization/configured-rows/types.js} +0 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* host/composer-extensions — what a host adds AROUND a conversation's composer, never inside the
|
|
3
|
+
* package's required pieces. Two optional registrations; with nothing registered both draw
|
|
4
|
+
* NOTHING (no stand-in text, no empty row) and the package behaves exactly as before.
|
|
5
|
+
*
|
|
6
|
+
* 1. ATTACHMENT SOURCES — a host-owned thing the person attaches to the next message (a page
|
|
7
|
+
* highlight, a connected-drive file). A source contributes
|
|
8
|
+
* - `Chip`: its chip, drawn in the composer's EXISTING attachment rail (never a new row;
|
|
9
|
+
* the chip decides for itself whether it renders anything), and
|
|
10
|
+
* - `contribute`: the payload that rides the outgoing turn as `context` keys, through the
|
|
11
|
+
* same door the host's pre-send gate uses (`execute-instance` merges it onto the request).
|
|
12
|
+
*
|
|
13
|
+
* 2. CONVERSATION COMPANION PANELS — a host panel keyed by conversation id (a task panel, notes).
|
|
14
|
+
* The rail draws one small pill per registered companion; the pill opens/closes the host's
|
|
15
|
+
* `Panel`, which the host draws however it likes (a drawer, a sheet).
|
|
16
|
+
*
|
|
17
|
+
* Both are plain host registrations (like `registerChatUi`): `register…` returns the release.
|
|
18
|
+
*/
|
|
19
|
+
import { type ComponentType, type ReactNode } from "react";
|
|
20
|
+
import type { LucideIcon } from "lucide-react";
|
|
21
|
+
export interface ComposerAttachmentSourceInput {
|
|
22
|
+
conversationId: string;
|
|
23
|
+
}
|
|
24
|
+
export interface ComposerAttachmentSource {
|
|
25
|
+
/** Stable id; registering the same id again replaces the earlier registration. */
|
|
26
|
+
id: string;
|
|
27
|
+
/** The chip, drawn inline in the composer's attachment rail. Return null to draw nothing. */
|
|
28
|
+
Chip: ComponentType<ComposerAttachmentSourceInput>;
|
|
29
|
+
/**
|
|
30
|
+
* Context keys this source puts on the outgoing turn. Return null/undefined/{} to add nothing.
|
|
31
|
+
* Runs once per send, just before the request is assembled; a throw is reported and skipped
|
|
32
|
+
* (the turn still goes — a broken optional source never blocks a message).
|
|
33
|
+
*/
|
|
34
|
+
contribute?: (input: ComposerAttachmentSourceInput) => Record<string, unknown> | null | undefined | Promise<Record<string, unknown> | null | undefined>;
|
|
35
|
+
}
|
|
36
|
+
export interface ConversationCompanionPanelProps {
|
|
37
|
+
conversationId: string;
|
|
38
|
+
open: boolean;
|
|
39
|
+
onClose: () => void;
|
|
40
|
+
}
|
|
41
|
+
export interface ConversationCompanionPanel {
|
|
42
|
+
id: string;
|
|
43
|
+
/** Full name — the pill's tooltip and the overflow-menu row. */
|
|
44
|
+
label: string;
|
|
45
|
+
/** ONE word on the pill face. */
|
|
46
|
+
word: string;
|
|
47
|
+
icon: LucideIcon;
|
|
48
|
+
/** Optional live state for the pill; `hidden` removes it for this conversation. */
|
|
49
|
+
usePill?: (conversationId: string) => {
|
|
50
|
+
detail?: string;
|
|
51
|
+
hidden?: boolean;
|
|
52
|
+
} | null | undefined;
|
|
53
|
+
/** The host's panel. Drawn always (so it can animate); it draws nothing itself while `open` is false. */
|
|
54
|
+
Panel: ComponentType<ConversationCompanionPanelProps>;
|
|
55
|
+
}
|
|
56
|
+
/** Register a composer attachment source. Returns the release. */
|
|
57
|
+
export declare const registerComposerAttachmentSource: (item: ComposerAttachmentSource) => () => void;
|
|
58
|
+
/** Register a conversation companion panel. Returns the release. */
|
|
59
|
+
export declare const registerConversationCompanion: (item: ConversationCompanionPanel) => () => void;
|
|
60
|
+
export declare function listComposerAttachmentSources(): readonly ComposerAttachmentSource[];
|
|
61
|
+
export declare function listConversationCompanions(): readonly ConversationCompanionPanel[];
|
|
62
|
+
/** Tests only. */
|
|
63
|
+
export declare function resetComposerExtensionsForTests(): void;
|
|
64
|
+
export declare function useComposerAttachmentSources(): readonly ComposerAttachmentSource[];
|
|
65
|
+
export declare function useConversationCompanions(): readonly ConversationCompanionPanel[];
|
|
66
|
+
/**
|
|
67
|
+
* Every registered source's chip, in registration order. Draws NOTHING when none is registered.
|
|
68
|
+
* Chips are expected to be inline pills sized like the rail's own (they sit in its row).
|
|
69
|
+
*/
|
|
70
|
+
export declare function ComposerAttachmentSourceChips({ conversationId }: ComposerAttachmentSourceInput): ReactNode;
|
|
71
|
+
/**
|
|
72
|
+
* The context every registered source puts on this turn, merged in registration order. A source
|
|
73
|
+
* that throws or rejects is skipped and reported through `onError`; the others still contribute.
|
|
74
|
+
*/
|
|
75
|
+
export declare function collectAttachmentSourceContext(conversationId: string, onError?: (sourceId: string, error: unknown) => void): Promise<Record<string, unknown> | null>;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
Fragment,
|
|
4
|
+
useSyncExternalStore
|
|
5
|
+
} from "react";
|
|
6
|
+
import { createElement } from "react";
|
|
7
|
+
const EMPTY = [];
|
|
8
|
+
function createRegistry() {
|
|
9
|
+
let items = EMPTY;
|
|
10
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
11
|
+
const emit = () => {
|
|
12
|
+
for (const l of [...listeners]) l();
|
|
13
|
+
};
|
|
14
|
+
return {
|
|
15
|
+
register(item) {
|
|
16
|
+
items = [...items.filter((i) => i.id !== item.id), item];
|
|
17
|
+
emit();
|
|
18
|
+
return () => {
|
|
19
|
+
if (items.includes(item)) {
|
|
20
|
+
items = items.filter((i) => i !== item);
|
|
21
|
+
emit();
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
list: () => items,
|
|
26
|
+
subscribe(listener) {
|
|
27
|
+
listeners.add(listener);
|
|
28
|
+
return () => {
|
|
29
|
+
listeners.delete(listener);
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
clear() {
|
|
33
|
+
items = EMPTY;
|
|
34
|
+
emit();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const sources = createRegistry();
|
|
39
|
+
const companions = createRegistry();
|
|
40
|
+
const registerComposerAttachmentSource = sources.register;
|
|
41
|
+
const registerConversationCompanion = companions.register;
|
|
42
|
+
function listComposerAttachmentSources() {
|
|
43
|
+
return sources.list();
|
|
44
|
+
}
|
|
45
|
+
function listConversationCompanions() {
|
|
46
|
+
return companions.list();
|
|
47
|
+
}
|
|
48
|
+
function resetComposerExtensionsForTests() {
|
|
49
|
+
sources.clear();
|
|
50
|
+
companions.clear();
|
|
51
|
+
}
|
|
52
|
+
function useComposerAttachmentSources() {
|
|
53
|
+
return useSyncExternalStore(sources.subscribe, sources.list, sources.list);
|
|
54
|
+
}
|
|
55
|
+
function useConversationCompanions() {
|
|
56
|
+
return useSyncExternalStore(companions.subscribe, companions.list, companions.list);
|
|
57
|
+
}
|
|
58
|
+
function ComposerAttachmentSourceChips({ conversationId }) {
|
|
59
|
+
const list = useComposerAttachmentSources();
|
|
60
|
+
if (list.length === 0) return null;
|
|
61
|
+
return createElement(
|
|
62
|
+
Fragment,
|
|
63
|
+
null,
|
|
64
|
+
list.map((source) => createElement(source.Chip, { key: source.id, conversationId }))
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
async function collectAttachmentSourceContext(conversationId, onError) {
|
|
68
|
+
const list = sources.list();
|
|
69
|
+
if (list.length === 0) return null;
|
|
70
|
+
const merged = {};
|
|
71
|
+
for (const source of list) {
|
|
72
|
+
if (!source.contribute) continue;
|
|
73
|
+
try {
|
|
74
|
+
const part = await source.contribute({ conversationId });
|
|
75
|
+
if (part) Object.assign(merged, part);
|
|
76
|
+
} catch (error) {
|
|
77
|
+
onError?.(source.id, error);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return Object.keys(merged).length > 0 ? merged : null;
|
|
81
|
+
}
|
|
82
|
+
export {
|
|
83
|
+
ComposerAttachmentSourceChips,
|
|
84
|
+
collectAttachmentSourceContext,
|
|
85
|
+
listComposerAttachmentSources,
|
|
86
|
+
listConversationCompanions,
|
|
87
|
+
registerComposerAttachmentSource,
|
|
88
|
+
registerConversationCompanion,
|
|
89
|
+
resetComposerExtensionsForTests,
|
|
90
|
+
useComposerAttachmentSources,
|
|
91
|
+
useConversationCompanions
|
|
92
|
+
};
|
package/dist/host/configure.js
CHANGED
|
@@ -146,6 +146,7 @@ function resolveChatHost(host) {
|
|
|
146
146
|
canvas: host.canvas ?? createUnhostedCanvas(() => ref.diagnostics),
|
|
147
147
|
routing: host.routing ?? ANY_ROUTING,
|
|
148
148
|
deviceTools: host.deviceTools ?? null,
|
|
149
|
+
microphone: host.microphone ?? null,
|
|
149
150
|
engineHeldTools: new Set(host.engineHeldTools ?? []),
|
|
150
151
|
overridden
|
|
151
152
|
});
|
package/dist/host/contract.d.ts
CHANGED
|
@@ -522,17 +522,17 @@ export interface ChatWindowsPort {
|
|
|
522
522
|
Shell?: ComponentType<ChatWindowShellProps>;
|
|
523
523
|
}
|
|
524
524
|
/**
|
|
525
|
-
* Host registrations (R5).
|
|
526
|
-
*
|
|
525
|
+
* Host registrations (R5). Only what the package reads: tool renderers, context-item bodies,
|
|
526
|
+
* message widgets, surface manifests and compute targets register through their own doors
|
|
527
|
+
* (`registerToolRenderer`, `registerChatUi`, `registerSurfaceManifests`, ...), never here.
|
|
527
528
|
*/
|
|
528
529
|
export interface ChatRegistrations {
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
builderDoors?: Readonly<Record<string, unknown>>;
|
|
530
|
+
/**
|
|
531
|
+
* The host's per-turn context sources (`ChatContextSource`): each adds capabilities + state,
|
|
532
|
+
* context entries and/or the turn's device reference to every request, start and resume.
|
|
533
|
+
* Absent or empty: requests are exactly what the package builds.
|
|
534
|
+
*/
|
|
535
|
+
contextSources?: readonly ChatContextSource[];
|
|
536
536
|
}
|
|
537
537
|
export interface ChatHeaderPortalProps {
|
|
538
538
|
desktop?: ReactNode;
|
|
@@ -780,11 +780,99 @@ export type ChatDeviceToolInvocation = {
|
|
|
780
780
|
* wedge). Absent: delegated device tools go to the installed browser extension through the server
|
|
781
781
|
* port (`invokeMatrxExtendTool`), as on the web.
|
|
782
782
|
*/
|
|
783
|
+
export interface ChatMicrophonePort {
|
|
784
|
+
/**
|
|
785
|
+
* Obtain microphone permission where the host CAN show the browser's prompt (an extension side
|
|
786
|
+
* panel cannot; its host opens a small window that can). Called by package code that opens the
|
|
787
|
+
* microphone when the browser refused it (`NotAllowedError`). Resolve `true` once the person
|
|
788
|
+
* allowed it — the package then retries the capture once — `false` if they did not.
|
|
789
|
+
*/
|
|
790
|
+
requestPermission(): Promise<boolean>;
|
|
791
|
+
}
|
|
783
792
|
export interface ChatDeviceToolsPort {
|
|
784
|
-
invoke(toolName: string, args: Record<string, unknown>, context:
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
793
|
+
invoke(toolName: string, args: Record<string, unknown>, context: ChatDeviceToolContext): Promise<ChatDeviceToolInvocation>;
|
|
794
|
+
/**
|
|
795
|
+
* The document is going away (`pagehide`) with delegated device-tool calls still awaiting their
|
|
796
|
+
* answer (running, or waiting on the person's approval). The package will NOT submit those
|
|
797
|
+
* results — this document is dying — so the host owns each handed-off call from here: finish it
|
|
798
|
+
* (the run it already started, or start it if it never began), submit the result to the server
|
|
799
|
+
* durably (with replay if the network is down), and let the run continue. On reopen the package
|
|
800
|
+
* rejoins the conversation as usual. Optional: absent = the call stays pending on the server and
|
|
801
|
+
* the package re-surfaces it on reopen (cold resume), as before. Must not throw; return fast.
|
|
802
|
+
*/
|
|
803
|
+
handOff?(calls: readonly ChatDeviceToolHandOff[]): void;
|
|
804
|
+
}
|
|
805
|
+
/** A delegated device-tool call handed to the host as the document goes away (`ChatDeviceToolsPort.handOff`). */
|
|
806
|
+
export interface ChatDeviceToolHandOff {
|
|
807
|
+
conversationId: string;
|
|
808
|
+
/** The package's request key for the turn the call belongs to. */
|
|
809
|
+
requestId: string;
|
|
810
|
+
callId: string;
|
|
811
|
+
toolName: string;
|
|
812
|
+
args: Record<string, unknown>;
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* Whether a device tool that changes something asks the person first (`"ask"`) or just acts
|
|
816
|
+
* (`"act"`). Chosen per agent in the composer (shown only when the host has `deviceTools`), stored
|
|
817
|
+
* through the prefs port, latched when the person sends, and handed to every call of that turn.
|
|
818
|
+
* The host's own gate enforces it; privileged tools always ask.
|
|
819
|
+
*/
|
|
820
|
+
export type ChatDevicePermissionMode = "ask" | "act";
|
|
821
|
+
/** What every device-tool call carries besides its name and arguments. */
|
|
822
|
+
export interface ChatDeviceToolContext {
|
|
823
|
+
conversationId: string;
|
|
824
|
+
callId: string;
|
|
825
|
+
/** The conversation's agent, when known. */
|
|
826
|
+
agentId: string | null;
|
|
827
|
+
/** The person's ask/act choice for this agent, latched at send time. */
|
|
828
|
+
permissionMode: ChatDevicePermissionMode;
|
|
829
|
+
/**
|
|
830
|
+
* The host's opaque reference for the device state the person sent from (a browser host: the
|
|
831
|
+
* tab), as its context sources returned it when the turn started. Undefined when the host gave none.
|
|
832
|
+
*/
|
|
833
|
+
deviceRef?: unknown;
|
|
834
|
+
}
|
|
835
|
+
/** Which moment of a turn the package is building a request for. */
|
|
836
|
+
export type ChatHostTurnPhase = "start" | "resume";
|
|
837
|
+
export interface ChatHostTurnInput {
|
|
838
|
+
conversationId: string;
|
|
839
|
+
agentId: string | null;
|
|
840
|
+
phase: ChatHostTurnPhase;
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* What a host adds to one turn's request. Every member is optional; an empty contribution adds
|
|
844
|
+
* nothing.
|
|
845
|
+
*/
|
|
846
|
+
export interface ChatHostTurnContribution {
|
|
847
|
+
/**
|
|
848
|
+
* Server-registered client capabilities this host offers, by name, each with its
|
|
849
|
+
* `client.state` payload — or `null` for a stateless capability (declared, no state entry).
|
|
850
|
+
* A name the package's own providers already declared is left to them.
|
|
851
|
+
*/
|
|
852
|
+
capabilities?: Readonly<Record<string, Record<string, unknown> | null>>;
|
|
853
|
+
/**
|
|
854
|
+
* Entries merged into the request's `context`. Never overwrites a key the person or the agent
|
|
855
|
+
* already set.
|
|
856
|
+
*/
|
|
857
|
+
context?: Readonly<Record<string, unknown>>;
|
|
858
|
+
/**
|
|
859
|
+
* An opaque reference captured when the person sends (a browser host: the tab they sent
|
|
860
|
+
* from). Handed back to `deviceTools.invoke` for every call of that turn, resumes included.
|
|
861
|
+
*/
|
|
862
|
+
deviceRef?: unknown;
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* One host context source (registered in `ChatRegistrations.contextSources`): the page the
|
|
866
|
+
* person is on, the browser's tool capability, an auto-attach rule… Asked on BOTH turn start and
|
|
867
|
+
* resume — the package's one envelope builder serves both. Every source runs in parallel under a
|
|
868
|
+
* bounded wait; one that answers too late or throws is skipped for that request and the skip is
|
|
869
|
+
* announced through diagnostics. Sources merge in registration order: the first to name a
|
|
870
|
+
* capability, a context key or a device reference keeps it.
|
|
871
|
+
*/
|
|
872
|
+
export interface ChatContextSource {
|
|
873
|
+
/** Stable id, for diagnostics. */
|
|
874
|
+
id: string;
|
|
875
|
+
contribute(input: ChatHostTurnInput): Promise<ChatHostTurnContribution | null>;
|
|
788
876
|
}
|
|
789
877
|
export interface ChatRoutingPort {
|
|
790
878
|
policy(conversationId: string): ChatRoutingPolicy;
|
|
@@ -870,6 +958,8 @@ export interface ChatHost {
|
|
|
870
958
|
routing?: ChatRoutingPort;
|
|
871
959
|
/** Default: none — delegated device tools go to the browser extension via the server port. */
|
|
872
960
|
deviceTools?: ChatDeviceToolsPort;
|
|
961
|
+
/** Default: none — a refused microphone stays refused (see `ChatMicrophonePort`). */
|
|
962
|
+
microphone?: ChatMicrophonePort;
|
|
873
963
|
/**
|
|
874
964
|
* Delegated tools THIS HOST'S OWN ENGINE holds and answers, so the package must not: Matrx Local's
|
|
875
965
|
* engine parks `google_email_send` for the person's review (it survives a reload or a closed
|
|
@@ -908,6 +998,8 @@ export interface ResolvedChatHost {
|
|
|
908
998
|
routing: ChatRoutingPort;
|
|
909
999
|
/** The host's on-device tool executor, or null. */
|
|
910
1000
|
deviceTools: ChatDeviceToolsPort | null;
|
|
1001
|
+
/** The host's microphone grant flow, or null. */
|
|
1002
|
+
microphone: ChatMicrophonePort | null;
|
|
911
1003
|
/** Delegated tool names the host's own engine answers (`ChatHost.engineHeldTools`). */
|
|
912
1004
|
engineHeldTools: ReadonlySet<string>;
|
|
913
1005
|
overridden: ReadonlySet<ChatPortName>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The package's own confirm (gap 4, AUDIT-C): a bare host asks the person for real.
|
|
3
|
+
*
|
|
4
|
+
* `confirm({...})` is kit's imperative opener (`@ai-matrx/kit/confirm-opener`) and the dialog body
|
|
5
|
+
* is design-system's `ConfirmDialogHost`, which `BareHostChrome` mounts. A host that registers its
|
|
6
|
+
* own `confirm` (matrx-frontend: its `ConfirmDialogHost` wrapper) is used instead.
|
|
7
|
+
*
|
|
8
|
+
* It always settles: the person answers; or no dialog host appeared within the wait, and then the
|
|
9
|
+
* host's notifier says the question could not be asked and the answer is `false` (nothing is done,
|
|
10
|
+
* and the person is told why — never a button that silently does nothing).
|
|
11
|
+
*/
|
|
12
|
+
import { type ConfirmOptions } from "@ai-matrx/kit/confirm-opener";
|
|
13
|
+
/** How long a call waits for a dialog host to register (it mounts with the chat provider). */
|
|
14
|
+
export declare const CONFIRM_HOST_WAIT_MS = 5000;
|
|
15
|
+
export declare function defaultConfirm(options: ConfirmOptions, waitMs?: number): Promise<boolean>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { confirm as openConfirm, confirmOpener } from "@ai-matrx/kit/confirm-opener";
|
|
2
|
+
import { getChatHost, isChatHostConfigured } from "../configure.js";
|
|
3
|
+
const CONFIRM_HOST_WAIT_MS = 5e3;
|
|
4
|
+
async function waitForConfirmHost(timeoutMs) {
|
|
5
|
+
if (confirmOpener._hasHost()) return true;
|
|
6
|
+
const deadline = Date.now() + timeoutMs;
|
|
7
|
+
while (Date.now() < deadline) {
|
|
8
|
+
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
9
|
+
if (confirmOpener._hasHost()) return true;
|
|
10
|
+
}
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
async function defaultConfirm(options, waitMs = CONFIRM_HOST_WAIT_MS) {
|
|
14
|
+
if (!await waitForConfirmHost(waitMs)) {
|
|
15
|
+
const sentence = "The question could not be shown, so nothing was done. Reload and try again.";
|
|
16
|
+
if (isChatHostConfigured()) getChatHost().notify.error(sentence);
|
|
17
|
+
console.error(`[chat confirm] no confirm dialog is mounted. ${sentence}`);
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
return openConfirm(options);
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
CONFIRM_HOST_WAIT_MS,
|
|
24
|
+
defaultConfirm
|
|
25
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export declare function useDefaultFileActions(fileId: string): {
|
|
2
|
+
download: () => Promise<void>;
|
|
3
|
+
};
|
|
4
|
+
export interface DefaultFileDocument {
|
|
5
|
+
processed_document_id: string;
|
|
6
|
+
derivation_kind: string;
|
|
7
|
+
total_pages: number | null;
|
|
8
|
+
chunk_count: number | null;
|
|
9
|
+
has_clean_content: boolean;
|
|
10
|
+
updated_at: string;
|
|
11
|
+
}
|
|
12
|
+
export type DefaultFileDocumentState = {
|
|
13
|
+
status: "idle";
|
|
14
|
+
} | {
|
|
15
|
+
status: "loading";
|
|
16
|
+
} | {
|
|
17
|
+
status: "found";
|
|
18
|
+
doc: DefaultFileDocument;
|
|
19
|
+
} | {
|
|
20
|
+
status: "absent";
|
|
21
|
+
} | {
|
|
22
|
+
status: "unavailable";
|
|
23
|
+
reason: string;
|
|
24
|
+
};
|
|
25
|
+
/** The newest live processed document whose source is this file (the same read the website makes). */
|
|
26
|
+
export declare function lookupDefaultFileDocument(fileId: string): Promise<DefaultFileDocumentState>;
|
|
27
|
+
export declare function useDefaultFileDocument(fileId: string | null): {
|
|
28
|
+
state: DefaultFileDocumentState;
|
|
29
|
+
refresh: () => void;
|
|
30
|
+
};
|
|
31
|
+
export interface DefaultFileFamilyRepresentation {
|
|
32
|
+
key: string;
|
|
33
|
+
label: string;
|
|
34
|
+
category: string;
|
|
35
|
+
count: number;
|
|
36
|
+
promotable: boolean;
|
|
37
|
+
fetch_tool: string;
|
|
38
|
+
}
|
|
39
|
+
export interface DefaultFileResourceFamily {
|
|
40
|
+
schema_version: number;
|
|
41
|
+
resource_type: "file";
|
|
42
|
+
requested_file_id: string;
|
|
43
|
+
root_file_id: string | null;
|
|
44
|
+
files: ReadonlyArray<Record<string, unknown>>;
|
|
45
|
+
processed_documents: ReadonlyArray<Record<string, unknown>>;
|
|
46
|
+
representations: DefaultFileFamilyRepresentation[];
|
|
47
|
+
capabilities: string[];
|
|
48
|
+
counts: Record<string, number>;
|
|
49
|
+
}
|
|
50
|
+
export declare function parseDefaultFileResourceFamily(value: unknown): DefaultFileResourceFamily;
|
|
51
|
+
export declare function useDefaultFileResourceFamily(fileId: string | null): {
|
|
52
|
+
data: DefaultFileResourceFamily | null;
|
|
53
|
+
loading: boolean;
|
|
54
|
+
error: string | null;
|
|
55
|
+
};
|
|
56
|
+
export interface DefaultFileResourceChipProps {
|
|
57
|
+
fileId: string | null | undefined;
|
|
58
|
+
fileHint?: {
|
|
59
|
+
fileName?: string | null;
|
|
60
|
+
mimeType?: string | null;
|
|
61
|
+
} | null;
|
|
62
|
+
nameOverride?: string | null;
|
|
63
|
+
badge?: string | null;
|
|
64
|
+
size?: "xs" | "sm" | "md";
|
|
65
|
+
onOpen?: () => void;
|
|
66
|
+
onRemove?: () => void;
|
|
67
|
+
className?: string;
|
|
68
|
+
}
|
|
69
|
+
/** One attached file as a chip: its icon and name (read from the files engine), open and remove. */
|
|
70
|
+
export declare function DefaultFileResourceChip({ fileId, fileHint, nameOverride, badge, onOpen, onRemove, className }: DefaultFileResourceChipProps): import("react").JSX.Element;
|
|
71
|
+
export interface DefaultMediaAttachmentThumbnailProps {
|
|
72
|
+
mediaRef: {
|
|
73
|
+
file_id?: string | null;
|
|
74
|
+
url?: string | null;
|
|
75
|
+
mime_type?: string | null;
|
|
76
|
+
file_name?: string | null;
|
|
77
|
+
} | string;
|
|
78
|
+
status?: "pending" | "error" | "ready";
|
|
79
|
+
title?: string;
|
|
80
|
+
onOpen?: () => void;
|
|
81
|
+
onRemove?: () => void;
|
|
82
|
+
className?: string;
|
|
83
|
+
}
|
|
84
|
+
/** An attached image or file as a small thumbnail (the files engine resolves its bytes). */
|
|
85
|
+
export declare function DefaultMediaAttachmentThumbnail({ mediaRef, status, title, onOpen, onRemove, className }: DefaultMediaAttachmentThumbnailProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useCallback, useEffect, useState } from "react";
|
|
4
|
+
import { X } from "lucide-react";
|
|
5
|
+
import { downloadFile as saveBlob } from "@ai-matrx/kit/download";
|
|
6
|
+
import { FileIcon, MediaThumbnail } from "@ai-matrx/media/react";
|
|
7
|
+
import { downloadFile } from "@ai-matrx/media/files/engine/api/files";
|
|
8
|
+
import { useFile } from "@ai-matrx/media/files/engine/handler/hooks/useFile";
|
|
9
|
+
import { getChatHost, isChatHostConfigured } from "../configure.js";
|
|
10
|
+
const isSyntheticId = (id) => id.startsWith("vfs:");
|
|
11
|
+
function rpc() {
|
|
12
|
+
if (!isChatHostConfigured()) return null;
|
|
13
|
+
const db = getChatHost().db;
|
|
14
|
+
return (name, args) => db.rpc(name, args);
|
|
15
|
+
}
|
|
16
|
+
function useDefaultFileActions(fileId) {
|
|
17
|
+
const download = useCallback(async () => {
|
|
18
|
+
if (!fileId || isSyntheticId(fileId)) throw new Error("This file has no stored bytes to download.");
|
|
19
|
+
const { blob, filename } = await downloadFile(fileId);
|
|
20
|
+
saveBlob(filename ?? "download", blob, blob.type);
|
|
21
|
+
}, [fileId]);
|
|
22
|
+
return { download };
|
|
23
|
+
}
|
|
24
|
+
const DOC_COLUMNS = "id, derivation_kind, total_pages, updated_at, clean_content_completed_at";
|
|
25
|
+
async function lookupDefaultFileDocument(fileId) {
|
|
26
|
+
if (!isChatHostConfigured()) return { status: "unavailable", reason: "no chat host" };
|
|
27
|
+
const db = getChatHost().db;
|
|
28
|
+
try {
|
|
29
|
+
const { data, error } = await db.schema("docproc").from("processed_documents").select(DOC_COLUMNS).is("deleted_at", null).is("archived_at", null).eq("source_kind", "cld_file").eq("source_id", fileId).order("updated_at", { ascending: false }).limit(1).maybeSingle();
|
|
30
|
+
if (error) return { status: "unavailable", reason: error.message };
|
|
31
|
+
if (!data) return { status: "absent" };
|
|
32
|
+
return {
|
|
33
|
+
status: "found",
|
|
34
|
+
doc: {
|
|
35
|
+
processed_document_id: data.id,
|
|
36
|
+
derivation_kind: data.derivation_kind,
|
|
37
|
+
total_pages: data.total_pages,
|
|
38
|
+
chunk_count: null,
|
|
39
|
+
has_clean_content: data.clean_content_completed_at != null,
|
|
40
|
+
updated_at: data.updated_at
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
} catch (cause) {
|
|
44
|
+
return { status: "unavailable", reason: cause instanceof Error ? cause.message : String(cause) };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function useDefaultFileDocument(fileId) {
|
|
48
|
+
const [state, setState] = useState({ status: "idle" });
|
|
49
|
+
const [tick, setTick] = useState(0);
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (!fileId) {
|
|
52
|
+
setState({ status: "idle" });
|
|
53
|
+
return void 0;
|
|
54
|
+
}
|
|
55
|
+
if (isSyntheticId(fileId)) {
|
|
56
|
+
setState({ status: "absent" });
|
|
57
|
+
return void 0;
|
|
58
|
+
}
|
|
59
|
+
let live = true;
|
|
60
|
+
setState({ status: "loading" });
|
|
61
|
+
void lookupDefaultFileDocument(fileId).then((next) => live && setState(next));
|
|
62
|
+
return () => {
|
|
63
|
+
live = false;
|
|
64
|
+
};
|
|
65
|
+
}, [fileId, tick]);
|
|
66
|
+
return { state, refresh: () => setTick((t) => t + 1) };
|
|
67
|
+
}
|
|
68
|
+
const isRecord = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
69
|
+
function parseDefaultFileResourceFamily(value) {
|
|
70
|
+
if (!isRecord(value) || value.resource_type !== "file") throw new Error("The file-family RPC returned an invalid resource envelope.");
|
|
71
|
+
const list = (v) => Array.isArray(v) ? v.filter(isRecord) : [];
|
|
72
|
+
return {
|
|
73
|
+
schema_version: typeof value.schema_version === "number" ? value.schema_version : 1,
|
|
74
|
+
resource_type: "file",
|
|
75
|
+
requested_file_id: typeof value.requested_file_id === "string" ? value.requested_file_id : "",
|
|
76
|
+
root_file_id: typeof value.root_file_id === "string" ? value.root_file_id : null,
|
|
77
|
+
files: list(value.files),
|
|
78
|
+
processed_documents: list(value.processed_documents),
|
|
79
|
+
representations: list(value.representations).filter((r) => typeof r.key === "string" && typeof r.label === "string").map((r) => ({
|
|
80
|
+
key: r.key,
|
|
81
|
+
label: r.label,
|
|
82
|
+
category: typeof r.category === "string" ? r.category : "other",
|
|
83
|
+
count: typeof r.count === "number" ? r.count : 0,
|
|
84
|
+
promotable: r.promotable === true,
|
|
85
|
+
fetch_tool: typeof r.fetch_tool === "string" ? r.fetch_tool : "context"
|
|
86
|
+
})),
|
|
87
|
+
capabilities: Array.isArray(value.capabilities) ? value.capabilities.filter((c) => typeof c === "string") : [],
|
|
88
|
+
counts: isRecord(value.counts) ? Object.fromEntries(Object.entries(value.counts).filter((e) => typeof e[1] === "number")) : {}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function useDefaultFileResourceFamily(fileId) {
|
|
92
|
+
const [state, setState] = useState({
|
|
93
|
+
fileId: null,
|
|
94
|
+
data: null,
|
|
95
|
+
error: null
|
|
96
|
+
});
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
if (!fileId) return void 0;
|
|
99
|
+
let live = true;
|
|
100
|
+
const call = rpc();
|
|
101
|
+
if (!call) {
|
|
102
|
+
setState({ fileId, data: null, error: "No chat host to read the file family from." });
|
|
103
|
+
return void 0;
|
|
104
|
+
}
|
|
105
|
+
void call("get_file_resource_family", { p_file_id: fileId }).then(({ data, error }) => {
|
|
106
|
+
if (!live) return;
|
|
107
|
+
if (error) setState({ fileId, data: null, error: error.message });
|
|
108
|
+
else setState({ fileId, data: parseDefaultFileResourceFamily(data), error: null });
|
|
109
|
+
}).catch((cause) => live && setState({ fileId, data: null, error: cause instanceof Error ? cause.message : "Unable to load file family" }));
|
|
110
|
+
return () => {
|
|
111
|
+
live = false;
|
|
112
|
+
};
|
|
113
|
+
}, [fileId]);
|
|
114
|
+
if (!fileId) return { data: null, loading: false, error: null };
|
|
115
|
+
if (state.fileId !== fileId) return { data: null, loading: true, error: null };
|
|
116
|
+
return { data: state.data, loading: false, error: state.error };
|
|
117
|
+
}
|
|
118
|
+
const formatBytes = (n) => n == null ? null : n < 1024 ? `${n} B` : n < 1024 * 1024 ? `${(n / 1024).toFixed(0)} KB` : `${(n / 1024 / 1024).toFixed(1)} MB`;
|
|
119
|
+
function DefaultFileResourceChip({ fileId, fileHint, nameOverride, badge, onOpen, onRemove, className }) {
|
|
120
|
+
const { file, status } = useFile(fileId && !isSyntheticId(fileId) ? { kind: "file_id", fileId } : null);
|
|
121
|
+
const name = nameOverride || file?.meta.fileName || fileHint?.fileName || (status === "resolving" ? "Loading\u2026" : "File");
|
|
122
|
+
const mime = file?.meta.mime ?? fileHint?.mimeType ?? null;
|
|
123
|
+
const size = formatBytes(file?.meta.sizeBytes);
|
|
124
|
+
const body = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
125
|
+
/* @__PURE__ */ jsx(FileIcon, { fileName: name, mimeType: mime, size: 14 }),
|
|
126
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: name }),
|
|
127
|
+
badge || size ? /* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground", children: badge ?? size }) : null
|
|
128
|
+
] });
|
|
129
|
+
return /* @__PURE__ */ jsxs(
|
|
130
|
+
"span",
|
|
131
|
+
{
|
|
132
|
+
className: `inline-flex max-w-64 items-center gap-1.5 rounded-md border border-border bg-card px-2 py-1 text-xs ${className ?? ""}`,
|
|
133
|
+
"data-chat-default": "file-chip",
|
|
134
|
+
title: name,
|
|
135
|
+
children: [
|
|
136
|
+
onOpen ? /* @__PURE__ */ jsx("button", { type: "button", className: "inline-flex min-w-0 items-center gap-1.5", onClick: onOpen, children: body }) : body,
|
|
137
|
+
onRemove ? /* @__PURE__ */ jsx("button", { type: "button", "aria-label": `Remove ${name}`, className: "shrink-0 text-muted-foreground hover:text-foreground", onClick: onRemove, children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" }) }) : null
|
|
138
|
+
]
|
|
139
|
+
}
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
function DefaultMediaAttachmentThumbnail({ mediaRef, status = "ready", title, onOpen, onRemove, className }) {
|
|
143
|
+
const ref = typeof mediaRef === "string" ? { file_id: mediaRef } : mediaRef;
|
|
144
|
+
const name = title || ref.file_name || "Attachment";
|
|
145
|
+
return /* @__PURE__ */ jsxs("span", { className: `relative inline-flex h-12 w-12 overflow-hidden rounded-md border border-border ${status === "pending" ? "opacity-60" : ""} ${className ?? ""}`, "data-chat-default": "media-thumbnail", title: name, children: [
|
|
146
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "h-full w-full", onClick: onOpen, disabled: !onOpen, "aria-label": `Open ${name}`, children: /* @__PURE__ */ jsx(MediaThumbnail, { mediaRef, fileName: name, mimeType: ref.mime_type ?? null, iconSize: 20, className: "h-full w-full" }) }),
|
|
147
|
+
onRemove ? /* @__PURE__ */ jsx("button", { type: "button", "aria-label": `Remove ${name}`, className: "absolute right-0.5 top-0.5 rounded bg-background/80 p-0.5", onClick: onRemove, children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" }) }) : null
|
|
148
|
+
] });
|
|
149
|
+
}
|
|
150
|
+
export {
|
|
151
|
+
DefaultFileResourceChip,
|
|
152
|
+
DefaultMediaAttachmentThumbnail,
|
|
153
|
+
lookupDefaultFileDocument,
|
|
154
|
+
parseDefaultFileResourceFamily,
|
|
155
|
+
useDefaultFileActions,
|
|
156
|
+
useDefaultFileDocument,
|
|
157
|
+
useDefaultFileResourceFamily
|
|
158
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type ResourceAccess } from "../../ui/access-core.js";
|
|
2
|
+
import { type PermissionLevel } from "../../ui/permission-levels.js";
|
|
3
|
+
export declare function useDefaultAccess(resourceType: string | undefined, resourceId: string | undefined): ResourceAccess & {
|
|
4
|
+
loading: boolean;
|
|
5
|
+
refresh: () => Promise<void>;
|
|
6
|
+
};
|
|
7
|
+
export type DefaultOrganizationState = "resolving" | "required" | "ready" | "unavailable" | "signed_out";
|
|
8
|
+
export declare function useDefaultOrganizationRequired(): {
|
|
9
|
+
organizationId: string | null;
|
|
10
|
+
canLoad: boolean;
|
|
11
|
+
organizationRequired: boolean;
|
|
12
|
+
resolving: boolean;
|
|
13
|
+
organizationState: "ready" | "required" | "signed_out" | "unavailable";
|
|
14
|
+
unavailableReason: string | null;
|
|
15
|
+
retry: () => void;
|
|
16
|
+
};
|
|
17
|
+
export interface DefaultOrgAvailabilityOptions {
|
|
18
|
+
resourceType: string;
|
|
19
|
+
resourceId: string;
|
|
20
|
+
organizationId: string;
|
|
21
|
+
permissionLevel?: PermissionLevel;
|
|
22
|
+
}
|
|
23
|
+
export declare function defaultEnsureOrgAvailability(options: DefaultOrgAvailabilityOptions): Promise<{
|
|
24
|
+
success: boolean;
|
|
25
|
+
error?: string;
|
|
26
|
+
message?: string;
|
|
27
|
+
}>;
|