@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,36 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useMemo, useState } from "react";
|
|
4
|
+
import { GenericRenderer } from "../registry/GenericRenderer.js";
|
|
5
|
+
import { ConfiguredToolRow, ToolDisplayBoundary } from "./ConfiguredToolRow.js";
|
|
6
|
+
import { toRowEntry } from "./to-row-entry.js";
|
|
7
|
+
const loaded = /* @__PURE__ */ new WeakMap();
|
|
8
|
+
function useConfig(bare, cfg, load) {
|
|
9
|
+
const [fetched, setFetched] = useState(null);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (cfg || !load) return;
|
|
12
|
+
let alive = true;
|
|
13
|
+
let p = loaded.get(load);
|
|
14
|
+
if (!p) loaded.set(load, p = load());
|
|
15
|
+
void p.then((all) => alive && setFetched(all[bare] ?? null));
|
|
16
|
+
return () => {
|
|
17
|
+
alive = false;
|
|
18
|
+
};
|
|
19
|
+
}, [bare, cfg, load]);
|
|
20
|
+
return cfg ?? fetched;
|
|
21
|
+
}
|
|
22
|
+
function ConfiguredRowRenderer({
|
|
23
|
+
props,
|
|
24
|
+
bare,
|
|
25
|
+
cfg: given,
|
|
26
|
+
load,
|
|
27
|
+
stripPrefix
|
|
28
|
+
}) {
|
|
29
|
+
const cfg = useConfig(bare, given, load);
|
|
30
|
+
const row = useMemo(() => toRowEntry(props.entry, stripPrefix), [props.entry, stripPrefix]);
|
|
31
|
+
if (!cfg) return /* @__PURE__ */ jsx("div", { className: "h-5", "aria-hidden": true });
|
|
32
|
+
return /* @__PURE__ */ jsx(ToolDisplayBoundary, { toolName: props.entry.toolName, fallback: /* @__PURE__ */ jsx(GenericRenderer, { ...props }), children: /* @__PURE__ */ jsx(ConfiguredToolRow, { entry: row, kind: "client", cfg }) });
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
ConfiguredRowRenderer
|
|
36
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renders a tool entry using a `ToolDisplayEntry` from the registry. Used
|
|
3
|
+
* by both `ToolTimelineRow` (client tools) and `ServerToolRow` (server
|
|
4
|
+
* tools); the `kind` prop affects only the outer card styling so each
|
|
5
|
+
* surface keeps its existing look.
|
|
6
|
+
*
|
|
7
|
+
* Anything that goes wrong inside this component (missing path, unknown
|
|
8
|
+
* icon, throwing field component, throwing transform) is logged and the
|
|
9
|
+
* problematic field is skipped — the row never breaks the chat surface.
|
|
10
|
+
* For total failure (e.g. the registry config itself is malformed), the
|
|
11
|
+
* caller's `ToolDisplayBoundary` falls back to the default row.
|
|
12
|
+
*/
|
|
13
|
+
import { Component, type ReactNode } from 'react';
|
|
14
|
+
import type { ToolDisplayEntry, ToolRowEntry } from './types.js';
|
|
15
|
+
interface Props {
|
|
16
|
+
entry: ToolRowEntry;
|
|
17
|
+
kind: 'server' | 'client';
|
|
18
|
+
cfg: ToolDisplayEntry;
|
|
19
|
+
}
|
|
20
|
+
export declare function ConfiguredToolRow({ entry, kind, cfg }: Props): import("react").JSX.Element | null;
|
|
21
|
+
/**
|
|
22
|
+
* React error boundary that catches anything thrown deeper in the
|
|
23
|
+
* configurable render and falls back to a passed-in default row.
|
|
24
|
+
* Class component is the only React mechanism that catches render errors.
|
|
25
|
+
*/
|
|
26
|
+
interface BoundaryProps {
|
|
27
|
+
toolName: string;
|
|
28
|
+
fallback: ReactNode;
|
|
29
|
+
children: ReactNode;
|
|
30
|
+
}
|
|
31
|
+
interface BoundaryState {
|
|
32
|
+
errored: boolean;
|
|
33
|
+
}
|
|
34
|
+
export declare class ToolDisplayBoundary extends Component<BoundaryProps, BoundaryState> {
|
|
35
|
+
state: BoundaryState;
|
|
36
|
+
static getDerivedStateFromError(): BoundaryState;
|
|
37
|
+
componentDidCatch(error: Error, info: unknown): void;
|
|
38
|
+
render(): ReactNode;
|
|
39
|
+
}
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "@ai-matrx/design-system";
|
|
3
|
+
import { ShimmerText } from "@ai-matrx/rich-content/utils/lifted/ShimmerText";
|
|
4
|
+
import { ChevronRight, Globe } from "lucide-react";
|
|
5
|
+
import { Component, useState } from "react";
|
|
6
|
+
import { CopyToolButton } from "./CopyToolButton.js";
|
|
7
|
+
import { ToolProgressView } from "./ToolProgressView.js";
|
|
8
|
+
import { applyTransforms, getByPath, resolveColor, resolveIcon, resolvePhase } from "./helpers.js";
|
|
9
|
+
import { fieldComponents } from "./field-components.js";
|
|
10
|
+
import { FIELD_OVERRIDES } from "./registries.js";
|
|
11
|
+
function ConfiguredToolRow({ entry, kind, cfg }) {
|
|
12
|
+
const [open, setOpen] = useState(false);
|
|
13
|
+
const phase = entry.phase;
|
|
14
|
+
const inline = cfg.inline ?? {};
|
|
15
|
+
const results = cfg.results ?? {};
|
|
16
|
+
const inlineHidden = resolvePhase(inline.hidden, phase);
|
|
17
|
+
if (inlineHidden) return null;
|
|
18
|
+
const colorClass = resolveColor(resolvePhase(inline.color, phase), phase);
|
|
19
|
+
const shouldSpin = resolvePhase(inline.spinIcon, phase) ?? phase === "started";
|
|
20
|
+
const prefix = resolvePhase(inline.prefix, phase) ?? "";
|
|
21
|
+
const namePart = resolvePhase(inline.name, phase);
|
|
22
|
+
const resolvedName = resolveNamePart(entry, namePart);
|
|
23
|
+
const displayName = resolvedName === void 0 ? titleCase(entry.toolName) : resolvedName;
|
|
24
|
+
const suffix = resolvePhase(inline.suffix, phase) ?? "";
|
|
25
|
+
const infoText = resolveInfo(entry, resolvePhase(inline.info, phase));
|
|
26
|
+
const headerSegments = [prefix, displayName, suffix].filter((s) => s && s.length > 0);
|
|
27
|
+
const headerLabel = headerSegments.join(" ");
|
|
28
|
+
const shimmer = phase === "started" && (inline.shimmerOnRunning ?? true);
|
|
29
|
+
const alwaysShowResults = phase === "completed" && results.alwaysShow === true && !resolvePhase(results.hidden, phase) && entry.output != null;
|
|
30
|
+
return /* @__PURE__ */ jsxs("div", { className: "group rounded py-0.5 pr-1 text-xs hover:bg-muted/40", children: [
|
|
31
|
+
/* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-1.5", children: [
|
|
32
|
+
/* @__PURE__ */ jsxs(
|
|
33
|
+
"button",
|
|
34
|
+
{
|
|
35
|
+
type: "button",
|
|
36
|
+
onClick: () => setOpen((v) => !v),
|
|
37
|
+
className: "flex flex-1 items-center gap-1.5 text-left",
|
|
38
|
+
"aria-expanded": open,
|
|
39
|
+
children: [
|
|
40
|
+
kind === "server" && /* @__PURE__ */ jsx(
|
|
41
|
+
ChevronRight,
|
|
42
|
+
{
|
|
43
|
+
className: `size-3 shrink-0 text-muted-foreground transition-transform ${open ? "rotate-90" : ""}`
|
|
44
|
+
}
|
|
45
|
+
),
|
|
46
|
+
/* @__PURE__ */ jsx(
|
|
47
|
+
InlineIcon,
|
|
48
|
+
{
|
|
49
|
+
entry,
|
|
50
|
+
phase,
|
|
51
|
+
value: resolvePhase(inline.icon, phase),
|
|
52
|
+
colorClass,
|
|
53
|
+
spin: shouldSpin
|
|
54
|
+
}
|
|
55
|
+
),
|
|
56
|
+
headerLabel && /* @__PURE__ */ jsx("span", { className: cn("truncate text-foreground", shimmer && "min-w-0"), children: shimmer ? /* @__PURE__ */ jsx(ShimmerText, { text: headerLabel }) : headerLabel }),
|
|
57
|
+
infoText && /* @__PURE__ */ jsx(
|
|
58
|
+
"span",
|
|
59
|
+
{
|
|
60
|
+
className: cn(
|
|
61
|
+
"text-muted-foreground",
|
|
62
|
+
inline.isMultiline ? "whitespace-pre-wrap" : "truncate"
|
|
63
|
+
),
|
|
64
|
+
children: infoText
|
|
65
|
+
}
|
|
66
|
+
),
|
|
67
|
+
phase !== "started" && entry.endedAt && /* @__PURE__ */ jsxs("span", { className: "ml-auto text-[10px] text-muted-foreground", children: [
|
|
68
|
+
Math.max(1, entry.endedAt - entry.startedAt),
|
|
69
|
+
"ms"
|
|
70
|
+
] })
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
),
|
|
74
|
+
/* @__PURE__ */ jsx(
|
|
75
|
+
CopyToolButton,
|
|
76
|
+
{
|
|
77
|
+
data: {
|
|
78
|
+
toolName: entry.toolName,
|
|
79
|
+
args: entry.args,
|
|
80
|
+
result: entry.output,
|
|
81
|
+
message: entry.message,
|
|
82
|
+
phase,
|
|
83
|
+
startedAt: entry.startedAt,
|
|
84
|
+
endedAt: entry.endedAt,
|
|
85
|
+
callId: entry.callId
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
] }),
|
|
90
|
+
!resolvePhase(cfg.progress?.hidden, phase) && /* @__PURE__ */ jsx(ToolProgressView, { progress: entry.progress, phase, cfg: cfg.progress }),
|
|
91
|
+
alwaysShowResults && /* @__PURE__ */ jsx("div", { className: "mt-1 ml-5", children: /* @__PURE__ */ jsx(ResultsSection, { result: entry.output, cfg: results }) }),
|
|
92
|
+
open && /* @__PURE__ */ jsx(ExpandedBody, { entry, kind, cfg, skipResults: alwaysShowResults })
|
|
93
|
+
] });
|
|
94
|
+
}
|
|
95
|
+
function InlineIcon({
|
|
96
|
+
entry,
|
|
97
|
+
phase,
|
|
98
|
+
value,
|
|
99
|
+
colorClass,
|
|
100
|
+
spin
|
|
101
|
+
}) {
|
|
102
|
+
const [imgErr, setImgErr] = useState(false);
|
|
103
|
+
let resolved;
|
|
104
|
+
if (typeof value === "string") {
|
|
105
|
+
resolved = value;
|
|
106
|
+
} else if (value && typeof value === "object") {
|
|
107
|
+
const text = resolveInfo(entry, value);
|
|
108
|
+
resolved = text || void 0;
|
|
109
|
+
}
|
|
110
|
+
const isUrl = typeof resolved === "string" && (resolved.startsWith("http") || resolved.startsWith("data:"));
|
|
111
|
+
if (isUrl && !imgErr && resolved) {
|
|
112
|
+
return /* @__PURE__ */ jsx(
|
|
113
|
+
"img",
|
|
114
|
+
{
|
|
115
|
+
src: resolved,
|
|
116
|
+
alt: "",
|
|
117
|
+
className: cn("size-3.5 shrink-0 rounded-sm object-contain", colorClass),
|
|
118
|
+
onError: () => setImgErr(true)
|
|
119
|
+
}
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
if (isUrl && imgErr) {
|
|
123
|
+
return /* @__PURE__ */ jsx(Globe, { className: cn("size-3.5 shrink-0", colorClass) });
|
|
124
|
+
}
|
|
125
|
+
const LucideIcon = resolveIcon(resolved, phase);
|
|
126
|
+
return /* @__PURE__ */ jsx(LucideIcon, { className: cn("size-3.5 shrink-0", colorClass, spin && "animate-spin") });
|
|
127
|
+
}
|
|
128
|
+
function ExpandedBody({ entry, cfg, skipResults = false }) {
|
|
129
|
+
const phase = entry.phase;
|
|
130
|
+
const args = cfg.args ?? {};
|
|
131
|
+
const results = cfg.results ?? {};
|
|
132
|
+
const argsHidden = resolvePhase(args.hidden, phase);
|
|
133
|
+
const resultsHidden = resolvePhase(results.hidden, phase);
|
|
134
|
+
const showArgs = !argsHidden && entry.args != null;
|
|
135
|
+
const showResults = !skipResults && !resultsHidden && phase === "completed" && entry.output != null;
|
|
136
|
+
const showError = phase === "error" && entry.message;
|
|
137
|
+
if (!showArgs && !showResults && !showError) return null;
|
|
138
|
+
return /* @__PURE__ */ jsxs("div", { className: "mt-1 ml-5 space-y-1.5", children: [
|
|
139
|
+
showArgs && /* @__PURE__ */ jsx(ArgsSection, { args: entry.args, cfg: args }),
|
|
140
|
+
showResults && /* @__PURE__ */ jsx(ResultsSection, { result: entry.output, cfg: results }),
|
|
141
|
+
showError && /* @__PURE__ */ jsx(SectionLabel, { label: "error", children: /* @__PURE__ */ jsx("pre", { className: preClass, children: entry.message }) })
|
|
142
|
+
] });
|
|
143
|
+
}
|
|
144
|
+
const preClass = "mt-0.5 max-h-48 overflow-auto rounded-md bg-background/60 p-1.5 text-[11px] leading-snug";
|
|
145
|
+
function SectionLabel({ label, children }) {
|
|
146
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
147
|
+
/* @__PURE__ */ jsx("div", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: label }),
|
|
148
|
+
children
|
|
149
|
+
] });
|
|
150
|
+
}
|
|
151
|
+
function ArgsSection({ args, cfg }) {
|
|
152
|
+
const displayType = cfg.displayType ?? "json";
|
|
153
|
+
return /* @__PURE__ */ jsx(SectionLabel, { label: "args", children: renderStandardDisplay(args, displayType) });
|
|
154
|
+
}
|
|
155
|
+
function ResultsSection({ result, cfg }) {
|
|
156
|
+
const displayType = cfg.displayType ?? "json";
|
|
157
|
+
if (displayType === "custom") {
|
|
158
|
+
return /* @__PURE__ */ jsx(SectionLabel, { label: "result", children: /* @__PURE__ */ jsx(CustomResults, { result, keysInfo: cfg.keysInfo ?? [] }) });
|
|
159
|
+
}
|
|
160
|
+
return /* @__PURE__ */ jsx(SectionLabel, { label: "result", children: renderStandardDisplay(result, displayType) });
|
|
161
|
+
}
|
|
162
|
+
function renderStandardDisplay(value, displayType) {
|
|
163
|
+
if (displayType === "key-value" || displayType === "values-only") {
|
|
164
|
+
if (value == null || typeof value !== "object" || Array.isArray(value)) {
|
|
165
|
+
return /* @__PURE__ */ jsx("pre", { className: preClass, children: safeStringify(value) });
|
|
166
|
+
}
|
|
167
|
+
const entries = Object.entries(value);
|
|
168
|
+
if (entries.length === 0) return null;
|
|
169
|
+
if (displayType === "values-only") {
|
|
170
|
+
return /* @__PURE__ */ jsx("ul", { className: "mt-0.5 list-disc space-y-0.5 pl-4 text-[11px] text-foreground", children: entries.map(([k, v]) => /* @__PURE__ */ jsx("li", { children: stringifyValue(v) }, k)) });
|
|
171
|
+
}
|
|
172
|
+
return /* @__PURE__ */ jsx("div", { className: "mt-0.5 grid grid-cols-[minmax(0,auto)_1fr] gap-x-2 gap-y-0.5 text-[11px]", children: entries.map(([k, v]) => /* @__PURE__ */ jsx(FieldRow, { k, v }, k)) });
|
|
173
|
+
}
|
|
174
|
+
return /* @__PURE__ */ jsx("pre", { className: preClass, children: safeStringify(value) });
|
|
175
|
+
}
|
|
176
|
+
function FieldRow({ k, v }) {
|
|
177
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
178
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-muted-foreground", children: k }),
|
|
179
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate text-foreground", children: stringifyValue(v) })
|
|
180
|
+
] });
|
|
181
|
+
}
|
|
182
|
+
function CustomResults({ result, keysInfo }) {
|
|
183
|
+
if (result == null || typeof result !== "object") return null;
|
|
184
|
+
return /* @__PURE__ */ jsx("div", { className: "mt-0.5 space-y-1.5", children: keysInfo.map((info, i) => /* @__PURE__ */ jsx(
|
|
185
|
+
CustomResultField,
|
|
186
|
+
{
|
|
187
|
+
result,
|
|
188
|
+
info
|
|
189
|
+
},
|
|
190
|
+
`${info.key}-${i}`
|
|
191
|
+
)) });
|
|
192
|
+
}
|
|
193
|
+
function CustomResultField({
|
|
194
|
+
result,
|
|
195
|
+
info
|
|
196
|
+
}) {
|
|
197
|
+
const FieldComponent = FIELD_OVERRIDES[info.component] ?? fieldComponents[info.component];
|
|
198
|
+
if (!FieldComponent) {
|
|
199
|
+
console.warn(`[configured-row] unknown field component: "${info.component}"`);
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
const raw = !info.key || info.key === "*" ? result : info.key.includes(".") ? lookupShallow(result, info.key) : result[info.key];
|
|
203
|
+
if (raw == null || raw === "") {
|
|
204
|
+
if (info.fallback) {
|
|
205
|
+
return /* @__PURE__ */ jsx(FieldComponent, { value: info.fallback, className: info.className });
|
|
206
|
+
}
|
|
207
|
+
console.warn(`[configured-row] missing key "${info.key}" in result`, { result });
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
const value = applyTransforms(raw, info.transform ?? null);
|
|
211
|
+
try {
|
|
212
|
+
return /* @__PURE__ */ jsx(FieldComponent, { value, className: info.className });
|
|
213
|
+
} catch (err) {
|
|
214
|
+
console.warn(`[configured-row] field component "${info.component}" threw:`, err, { info, value });
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
function lookupShallow(obj, path) {
|
|
219
|
+
const segments = path.split(".");
|
|
220
|
+
let cursor = obj;
|
|
221
|
+
for (const seg of segments) {
|
|
222
|
+
if (cursor == null) return void 0;
|
|
223
|
+
if (Array.isArray(cursor)) {
|
|
224
|
+
const idx = Number(seg);
|
|
225
|
+
if (!Number.isInteger(idx)) return void 0;
|
|
226
|
+
cursor = cursor[idx];
|
|
227
|
+
} else if (typeof cursor === "object") {
|
|
228
|
+
cursor = cursor[seg];
|
|
229
|
+
} else {
|
|
230
|
+
return void 0;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return cursor;
|
|
234
|
+
}
|
|
235
|
+
function safeStringify(value) {
|
|
236
|
+
if (value == null) return "";
|
|
237
|
+
if (typeof value === "string") return value;
|
|
238
|
+
try {
|
|
239
|
+
return JSON.stringify(value, null, 2);
|
|
240
|
+
} catch {
|
|
241
|
+
return String(value);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function stringifyValue(value) {
|
|
245
|
+
if (value == null) return "";
|
|
246
|
+
if (typeof value === "string") return value;
|
|
247
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
248
|
+
try {
|
|
249
|
+
return JSON.stringify(value);
|
|
250
|
+
} catch {
|
|
251
|
+
return String(value);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
function titleCase(name) {
|
|
255
|
+
return name.split(/[_\s]+/).filter(Boolean).map((p) => p[0] ? p[0].toUpperCase() + p.slice(1) : p).join(" ");
|
|
256
|
+
}
|
|
257
|
+
function resolveNamePart(entry, value) {
|
|
258
|
+
if (value === void 0) return void 0;
|
|
259
|
+
if (typeof value === "string") return value;
|
|
260
|
+
return resolveInfo(entry, value);
|
|
261
|
+
}
|
|
262
|
+
function resolveInfo(entry, info) {
|
|
263
|
+
if (!info) return "";
|
|
264
|
+
const spec = typeof info === "string" ? { path: info } : info;
|
|
265
|
+
const raw = getByPath(entry, spec.path);
|
|
266
|
+
if (raw == null || raw === "") {
|
|
267
|
+
return spec.fallback ?? "";
|
|
268
|
+
}
|
|
269
|
+
const transformed = applyTransforms(raw, spec.transform ?? null);
|
|
270
|
+
if (transformed == null || transformed === "") return spec.fallback ?? "";
|
|
271
|
+
if (typeof transformed === "string") return transformed;
|
|
272
|
+
if (typeof transformed === "number" || typeof transformed === "boolean")
|
|
273
|
+
return String(transformed);
|
|
274
|
+
try {
|
|
275
|
+
return JSON.stringify(transformed);
|
|
276
|
+
} catch {
|
|
277
|
+
return String(transformed);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
class ToolDisplayBoundary extends Component {
|
|
281
|
+
state = { errored: false };
|
|
282
|
+
static getDerivedStateFromError() {
|
|
283
|
+
return { errored: true };
|
|
284
|
+
}
|
|
285
|
+
componentDidCatch(error, info) {
|
|
286
|
+
console.warn(`[configured-row] custom render threw for "${this.props.toolName}":`, error, info);
|
|
287
|
+
}
|
|
288
|
+
render() {
|
|
289
|
+
if (this.state.errored) return this.props.fallback;
|
|
290
|
+
return this.props.children;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
export {
|
|
294
|
+
ConfiguredToolRow,
|
|
295
|
+
ToolDisplayBoundary
|
|
296
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small clipboard button that copies the full tool-call payload (name, args,
|
|
3
|
+
* result/output, error message, phase, duration, callId) as pretty-printed
|
|
4
|
+
* JSON. Used by every row variant — default and configurable. Shows a green
|
|
5
|
+
* check for ~1.5s after a successful copy.
|
|
6
|
+
*
|
|
7
|
+
* The button stops click propagation so it doesn't toggle the row open/close
|
|
8
|
+
* when the parent row is also clickable.
|
|
9
|
+
*/
|
|
10
|
+
export interface ToolCopyData {
|
|
11
|
+
toolName: string;
|
|
12
|
+
args?: unknown;
|
|
13
|
+
result?: unknown;
|
|
14
|
+
message?: string | undefined;
|
|
15
|
+
phase: 'started' | 'completed' | 'error';
|
|
16
|
+
startedAt: number;
|
|
17
|
+
endedAt?: number | undefined;
|
|
18
|
+
callId?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function CopyToolButton({ data, className }: {
|
|
21
|
+
data: ToolCopyData;
|
|
22
|
+
className?: string;
|
|
23
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "@ai-matrx/design-system";
|
|
3
|
+
import { Check, Copy } from "lucide-react";
|
|
4
|
+
import { useCallback, useEffect, useState } from "react";
|
|
5
|
+
function buildPayload(data) {
|
|
6
|
+
const payload = {
|
|
7
|
+
tool: data.toolName,
|
|
8
|
+
phase: data.phase,
|
|
9
|
+
args: data.args ?? null,
|
|
10
|
+
result: data.result ?? null
|
|
11
|
+
};
|
|
12
|
+
if (data.message !== void 0) {
|
|
13
|
+
if (data.phase === "error") payload.error = data.message;
|
|
14
|
+
else payload.message = data.message;
|
|
15
|
+
}
|
|
16
|
+
if (data.endedAt !== void 0) payload.duration_ms = Math.max(0, data.endedAt - data.startedAt);
|
|
17
|
+
if (data.callId !== void 0) payload.callId = data.callId;
|
|
18
|
+
try {
|
|
19
|
+
return JSON.stringify(payload, null, 2);
|
|
20
|
+
} catch {
|
|
21
|
+
return String(payload);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function CopyToolButton({ data, className }) {
|
|
25
|
+
const [copied, setCopied] = useState(false);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (!copied) return;
|
|
28
|
+
const t = setTimeout(() => setCopied(false), 1500);
|
|
29
|
+
return () => clearTimeout(t);
|
|
30
|
+
}, [copied]);
|
|
31
|
+
const handleClick = useCallback(
|
|
32
|
+
async (e) => {
|
|
33
|
+
e.stopPropagation();
|
|
34
|
+
const text = buildPayload(data);
|
|
35
|
+
try {
|
|
36
|
+
await navigator.clipboard.writeText(text);
|
|
37
|
+
setCopied(true);
|
|
38
|
+
} catch (err) {
|
|
39
|
+
console.warn("[configured-row] clipboard write failed", err);
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
[data]
|
|
43
|
+
);
|
|
44
|
+
return /* @__PURE__ */ jsx(
|
|
45
|
+
"button",
|
|
46
|
+
{
|
|
47
|
+
type: "button",
|
|
48
|
+
onClick: handleClick,
|
|
49
|
+
title: copied ? "Copied!" : "Copy tool data",
|
|
50
|
+
"aria-label": "Copy tool data",
|
|
51
|
+
className: cn(
|
|
52
|
+
"inline-flex size-5 shrink-0 items-center justify-center rounded text-muted-foreground opacity-0 transition-opacity hover:bg-muted/60 hover:text-foreground focus:opacity-100 group-hover:opacity-100",
|
|
53
|
+
copied && "opacity-100 text-emerald-600 dark:text-emerald-400",
|
|
54
|
+
className
|
|
55
|
+
),
|
|
56
|
+
children: copied ? /* @__PURE__ */ jsx(Check, { className: "size-3" }) : /* @__PURE__ */ jsx(Copy, { className: "size-3" })
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
export {
|
|
61
|
+
CopyToolButton
|
|
62
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renders the incremental progress log a long-running tool emits. Shown ONLY
|
|
3
|
+
* when a tool actually reported progress — every other tool renders nothing
|
|
4
|
+
* here, so this never becomes the default chrome for normal tool calls.
|
|
5
|
+
*
|
|
6
|
+
* Three modes (registry-selectable via `ProgressConfig.mode`, default 'log'):
|
|
7
|
+
* - 'log' chronological recent lines while running; collapses to a
|
|
8
|
+
* "N updates" toggle once the tool finishes (unless showWhenComplete)
|
|
9
|
+
* - 'latest' a single status line that the latest update replaces
|
|
10
|
+
* - 'steps' named steps grouped by `step`, ticking pending→active→done/error
|
|
11
|
+
*
|
|
12
|
+
* Used by both the configurable rows and the default rows (the generic
|
|
13
|
+
* fallback), so a tool that emits progress but has no registry entry still
|
|
14
|
+
* gets a sensible display.
|
|
15
|
+
*/
|
|
16
|
+
import type { Phase, ProgressConfig, ToolProgressRow as ToolProgressEntry } from './types.js';
|
|
17
|
+
interface Props {
|
|
18
|
+
progress: ToolProgressEntry[] | undefined;
|
|
19
|
+
phase: Phase;
|
|
20
|
+
cfg?: ProgressConfig | undefined;
|
|
21
|
+
}
|
|
22
|
+
export declare function ToolProgressView({ progress, phase, cfg }: Props): import("react").JSX.Element | null;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "@ai-matrx/design-system";
|
|
3
|
+
import { AlertTriangle, Check, ChevronDown, ChevronRight, Loader2 } from "lucide-react";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
function ToolProgressView({ progress, phase, cfg }) {
|
|
6
|
+
const entries = progress ?? [];
|
|
7
|
+
if (entries.length === 0) return null;
|
|
8
|
+
const mode = cfg?.mode ?? "log";
|
|
9
|
+
const running = phase === "started";
|
|
10
|
+
const showWhenComplete = cfg?.showWhenComplete ?? false;
|
|
11
|
+
if (mode === "steps") {
|
|
12
|
+
return /* @__PURE__ */ jsx(StepsProgress, { entries, running });
|
|
13
|
+
}
|
|
14
|
+
if (mode === "latest") {
|
|
15
|
+
return /* @__PURE__ */ jsx(LatestProgress, { entries, running });
|
|
16
|
+
}
|
|
17
|
+
return /* @__PURE__ */ jsx(
|
|
18
|
+
LogProgress,
|
|
19
|
+
{
|
|
20
|
+
entries,
|
|
21
|
+
running,
|
|
22
|
+
showWhenComplete,
|
|
23
|
+
visibleWhileRunning: cfg?.visibleWhileRunning ?? 4
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
const lineClass = "flex items-center gap-1.5 text-[11px] leading-snug text-muted-foreground";
|
|
28
|
+
const wrapClass = "mt-1 ml-5 border-l border-border/50 pl-2 space-y-0.5";
|
|
29
|
+
function entryLabel(e) {
|
|
30
|
+
return e.label ?? e.step ?? e.status ?? "\u2026";
|
|
31
|
+
}
|
|
32
|
+
function PercentBar({ percent }) {
|
|
33
|
+
const pct = percent <= 1 ? percent * 100 : percent;
|
|
34
|
+
const clamped = Math.max(0, Math.min(100, pct));
|
|
35
|
+
return /* @__PURE__ */ jsxs("span", { className: "ml-auto inline-flex items-center gap-1", children: [
|
|
36
|
+
/* @__PURE__ */ jsx("span", { className: "h-1 w-16 overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsx(
|
|
37
|
+
"span",
|
|
38
|
+
{
|
|
39
|
+
className: "block h-full rounded-full bg-primary/70 transition-all",
|
|
40
|
+
style: { width: `${clamped}%` }
|
|
41
|
+
}
|
|
42
|
+
) }),
|
|
43
|
+
/* @__PURE__ */ jsxs("span", { className: "tabular-nums text-[9px]", children: [
|
|
44
|
+
Math.round(clamped),
|
|
45
|
+
"%"
|
|
46
|
+
] })
|
|
47
|
+
] });
|
|
48
|
+
}
|
|
49
|
+
function LogProgress({
|
|
50
|
+
entries,
|
|
51
|
+
running,
|
|
52
|
+
showWhenComplete,
|
|
53
|
+
visibleWhileRunning
|
|
54
|
+
}) {
|
|
55
|
+
const [open, setOpen] = useState(false);
|
|
56
|
+
if (!running && !showWhenComplete) {
|
|
57
|
+
return /* @__PURE__ */ jsxs("div", { className: "mt-1 ml-5", children: [
|
|
58
|
+
/* @__PURE__ */ jsxs(
|
|
59
|
+
"button",
|
|
60
|
+
{
|
|
61
|
+
type: "button",
|
|
62
|
+
onClick: () => setOpen((v) => !v),
|
|
63
|
+
className: "inline-flex items-center gap-1 text-[10px] text-muted-foreground hover:text-foreground",
|
|
64
|
+
children: [
|
|
65
|
+
open ? /* @__PURE__ */ jsx(ChevronDown, { className: "size-3" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "size-3" }),
|
|
66
|
+
entries.length,
|
|
67
|
+
" update",
|
|
68
|
+
entries.length === 1 ? "" : "s"
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
),
|
|
72
|
+
open && /* @__PURE__ */ jsx("div", { className: wrapClass, children: entries.map((e, i) => /* @__PURE__ */ jsx(ProgressLine, { e, active: false }, i)) })
|
|
73
|
+
] });
|
|
74
|
+
}
|
|
75
|
+
const visible = entries.slice(-visibleWhileRunning);
|
|
76
|
+
const hiddenCount = entries.length - visible.length;
|
|
77
|
+
return /* @__PURE__ */ jsxs("div", { className: wrapClass, children: [
|
|
78
|
+
hiddenCount > 0 && /* @__PURE__ */ jsxs("div", { className: "text-[9px] text-muted-foreground/60", children: [
|
|
79
|
+
"+",
|
|
80
|
+
hiddenCount,
|
|
81
|
+
" earlier"
|
|
82
|
+
] }),
|
|
83
|
+
visible.map((e, i) => {
|
|
84
|
+
const isLatest = i === visible.length - 1;
|
|
85
|
+
return /* @__PURE__ */ jsx(ProgressLine, { e, active: running && isLatest }, i);
|
|
86
|
+
})
|
|
87
|
+
] });
|
|
88
|
+
}
|
|
89
|
+
function ProgressLine({ e, active }) {
|
|
90
|
+
const errored = e.status === "error";
|
|
91
|
+
return /* @__PURE__ */ jsxs("div", { className: cn(lineClass, errored && "text-red-600 dark:text-red-400"), children: [
|
|
92
|
+
active ? /* @__PURE__ */ jsx(Loader2, { className: "size-3 shrink-0 animate-spin text-primary" }) : errored ? /* @__PURE__ */ jsx(AlertTriangle, { className: "size-3 shrink-0" }) : /* @__PURE__ */ jsx("span", { className: "size-3 shrink-0 text-center text-muted-foreground/40", children: "\xB7" }),
|
|
93
|
+
/* @__PURE__ */ jsx("span", { className: cn(active ? "truncate text-foreground" : "truncate"), children: entryLabel(e) }),
|
|
94
|
+
typeof e.percent === "number" && /* @__PURE__ */ jsx(PercentBar, { percent: e.percent })
|
|
95
|
+
] });
|
|
96
|
+
}
|
|
97
|
+
function LatestProgress({
|
|
98
|
+
entries,
|
|
99
|
+
running
|
|
100
|
+
}) {
|
|
101
|
+
const last = entries[entries.length - 1];
|
|
102
|
+
if (!last) return null;
|
|
103
|
+
return /* @__PURE__ */ jsx("div", { className: wrapClass, children: /* @__PURE__ */ jsx(ProgressLine, { e: last, active: running }) });
|
|
104
|
+
}
|
|
105
|
+
function StepsProgress({
|
|
106
|
+
entries,
|
|
107
|
+
running
|
|
108
|
+
}) {
|
|
109
|
+
const order = [];
|
|
110
|
+
const latest = /* @__PURE__ */ new Map();
|
|
111
|
+
for (const e of entries) {
|
|
112
|
+
const key = e.step ?? e.label ?? "\u2026";
|
|
113
|
+
if (!latest.has(key)) order.push(key);
|
|
114
|
+
latest.set(key, e);
|
|
115
|
+
}
|
|
116
|
+
return /* @__PURE__ */ jsx("div", { className: wrapClass, children: order.map((key) => {
|
|
117
|
+
const e = latest.get(key);
|
|
118
|
+
if (!e) return null;
|
|
119
|
+
const status = e.status ?? (running ? "active" : "done");
|
|
120
|
+
return /* @__PURE__ */ jsxs(
|
|
121
|
+
"div",
|
|
122
|
+
{
|
|
123
|
+
className: cn(
|
|
124
|
+
lineClass,
|
|
125
|
+
status === "error" && "text-red-600 dark:text-red-400",
|
|
126
|
+
status === "done" && "text-foreground"
|
|
127
|
+
),
|
|
128
|
+
children: [
|
|
129
|
+
/* @__PURE__ */ jsx(StepIcon, { status }),
|
|
130
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: e.label ?? key }),
|
|
131
|
+
typeof e.percent === "number" && /* @__PURE__ */ jsx(PercentBar, { percent: e.percent })
|
|
132
|
+
]
|
|
133
|
+
},
|
|
134
|
+
key
|
|
135
|
+
);
|
|
136
|
+
}) });
|
|
137
|
+
}
|
|
138
|
+
function StepIcon({ status }) {
|
|
139
|
+
if (status === "active") return /* @__PURE__ */ jsx(Loader2, { className: "size-3 shrink-0 animate-spin text-primary" });
|
|
140
|
+
if (status === "done")
|
|
141
|
+
return /* @__PURE__ */ jsx(Check, { className: "size-3 shrink-0 text-emerald-600 dark:text-emerald-400" });
|
|
142
|
+
if (status === "error") return /* @__PURE__ */ jsx(AlertTriangle, { className: "size-3 shrink-0" });
|
|
143
|
+
return /* @__PURE__ */ jsx("span", { className: "size-3 shrink-0 rounded-full border border-muted-foreground/40" });
|
|
144
|
+
}
|
|
145
|
+
export {
|
|
146
|
+
ToolProgressView
|
|
147
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field components used by `results.keysInfo` (and reusable for any future
|
|
3
|
+
* config that names a component to render a single value). Each one accepts
|
|
4
|
+
* `{ value: unknown; className?: string }` and is responsible for coercing
|
|
5
|
+
* the value into something renderable. Anything weird (null, object) should
|
|
6
|
+
* render as empty / a JSON dump rather than throw.
|
|
7
|
+
*/
|
|
8
|
+
import type { ComponentType } from 'react';
|
|
9
|
+
import type { FieldComponentName } from './types.js';
|
|
10
|
+
interface FieldProps {
|
|
11
|
+
value: unknown;
|
|
12
|
+
className?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare const fieldComponents: Record<FieldComponentName, ComponentType<FieldProps>>;
|
|
15
|
+
export {};
|