@gram-ai/elements 1.27.4 → 1.27.6
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/README.md +72 -60
- package/README.typedoc.md +6 -6
- package/bin/cli.js +74 -74
- package/dist/compat-shims-CO9JXXV4.cjs.map +1 -1
- package/dist/{compat-shims-BPJ7Q68c.js → compat-shims-DxtUrORi.js} +4 -2
- package/dist/compat-shims-DxtUrORi.js.map +1 -0
- package/dist/components/ShareButton/index.d.ts +2 -2
- package/dist/components/assistant-ui/message-feedback.d.ts +1 -1
- package/dist/components/assistant-ui/tooltip-icon-button.d.ts +2 -2
- package/dist/components/ui/avatar.d.ts +2 -2
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/components/ui/calendar.d.ts +1 -1
- package/dist/components/ui/collapsible.d.ts +1 -1
- package/dist/components/ui/dialog.d.ts +4 -4
- package/dist/components/ui/popover.d.ts +2 -2
- package/dist/components/ui/skeleton.d.ts +1 -1
- package/dist/components/ui/time-range-picker.d.ts +1 -1
- package/dist/components/ui/tool-ui.d.ts +7 -7
- package/dist/components/ui/tooltip.d.ts +2 -2
- package/dist/contexts/ConnectionStatusContext.d.ts +1 -1
- package/dist/elements.cjs +1 -1
- package/dist/elements.css +1 -1
- package/dist/elements.js +2 -2
- package/dist/hooks/useDensity.d.ts +73 -73
- package/dist/hooks/useMCPTools.d.ts +1 -1
- package/dist/hooks/useRadius.d.ts +1 -1
- package/dist/{index-KSX4Qjip.cjs → index-A17b62wR.cjs} +10 -10
- package/dist/index-A17b62wR.cjs.map +1 -0
- package/dist/{index-BpJstUh1.cjs → index-C4bFBGfl.cjs} +4 -4
- package/dist/{index-BpJstUh1.cjs.map → index-C4bFBGfl.cjs.map} +1 -1
- package/dist/{index-CUitXazZ.js → index-D93pV0_o.js} +55 -55
- package/dist/{index-CUitXazZ.js.map → index-D93pV0_o.js.map} +1 -1
- package/dist/{index-D0bAYNQy.js → index-Dm2wLFTN.js} +304 -282
- package/dist/index-Dm2wLFTN.js.map +1 -0
- package/dist/lib/cassette.d.ts +4 -4
- package/dist/lib/errorTracking.d.ts +1 -1
- package/dist/lib/messageConverter.d.ts +1 -1
- package/dist/lib/models.d.ts +1 -1
- package/dist/plugins/chart/ui/bar-chart.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/accordion-wrapper.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/accordion.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/action-button.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/alert-wrapper.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/alert.d.ts +4 -4
- package/dist/plugins/generative-ui/ui/avatar.d.ts +5 -5
- package/dist/plugins/generative-ui/ui/badge.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/button-wrapper.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/button.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/card-wrapper.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/card.d.ts +8 -8
- package/dist/plugins/generative-ui/ui/checkbox.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/data-table.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/dialog.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/dropdown-menu.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/grid.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/input-wrapper.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/input.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/label.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/metric.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/pagination.d.ts +6 -6
- package/dist/plugins/generative-ui/ui/popover.d.ts +4 -4
- package/dist/plugins/generative-ui/ui/progress.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/radio-group.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/select.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/separator.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/skeleton.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/stack.d.ts +6 -6
- package/dist/plugins/generative-ui/ui/switch.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/table.d.ts +9 -9
- package/dist/plugins/generative-ui/ui/tabs-wrapper.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/tabs.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/text.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/textarea.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/tooltip.d.ts +1 -1
- package/dist/plugins.cjs +1 -1
- package/dist/plugins.js +1 -1
- package/dist/{profiler-CyzxBxVz.cjs → profiler-Cbbf4eEX.cjs} +2 -2
- package/dist/{profiler-CyzxBxVz.cjs.map → profiler-Cbbf4eEX.cjs.map} +1 -1
- package/dist/{profiler-BFkhZRxj.js → profiler-mca4IXaY.js} +2 -2
- package/dist/{profiler-BFkhZRxj.js.map → profiler-mca4IXaY.js.map} +1 -1
- package/dist/react-shim.js +1 -1
- package/dist/server/express.cjs.map +1 -1
- package/dist/server/express.js.map +1 -1
- package/dist/{startRecording-C-PPAs_Z.js → startRecording-BCafdS7B.js} +2 -2
- package/dist/{startRecording-C-PPAs_Z.js.map → startRecording-BCafdS7B.js.map} +1 -1
- package/dist/{startRecording-Dq92sEHf.cjs → startRecording-Eb5f7wqP.cjs} +2 -2
- package/dist/{startRecording-Dq92sEHf.cjs.map → startRecording-Eb5f7wqP.cjs.map} +1 -1
- package/dist/types/index.d.ts +4 -4
- package/package.json +1 -5
- package/src/compat-plugin.ts +14 -14
- package/src/compat-shims.ts +33 -31
- package/src/compat.test.ts +48 -48
- package/src/compat.ts +6 -6
- package/src/components/Chat/index.tsx +17 -17
- package/src/components/Chat/stories/Charts.stories.tsx +98 -98
- package/src/components/Chat/stories/Composer.stories.tsx +15 -15
- package/src/components/Chat/stories/ConnectionConfiguration.stories.tsx +44 -44
- package/src/components/Chat/stories/CustomComponents.stories.tsx +17 -17
- package/src/components/Chat/stories/Density.stories.tsx +20 -20
- package/src/components/Chat/stories/ErrorBoundary.stories.tsx +47 -47
- package/src/components/Chat/stories/FrontendTools.stories.tsx +39 -39
- package/src/components/Chat/stories/GenerativeUI.stories.tsx +48 -48
- package/src/components/Chat/stories/MessageFeedback.stories.tsx +52 -52
- package/src/components/Chat/stories/Modal.stories.tsx +28 -28
- package/src/components/Chat/stories/Model.stories.tsx +11 -11
- package/src/components/Chat/stories/Radius.stories.tsx +20 -20
- package/src/components/Chat/stories/Sidecar.stories.tsx +13 -13
- package/src/components/Chat/stories/StyleIsolation.stories.tsx +11 -11
- package/src/components/Chat/stories/Theme.stories.tsx +25 -25
- package/src/components/Chat/stories/Thread.stories.tsx +25 -25
- package/src/components/Chat/stories/ToolApproval.stories.tsx +55 -55
- package/src/components/Chat/stories/ToolMentions.stories.tsx +17 -17
- package/src/components/Chat/stories/Tools.stories.tsx +88 -88
- package/src/components/Chat/stories/Variants.stories.tsx +32 -32
- package/src/components/Chat/stories/Welcome.stories.tsx +14 -14
- package/src/components/ChatHistory.tsx +7 -7
- package/src/components/FrontendTools/index.tsx +5 -5
- package/src/components/Replay.stories.tsx +157 -157
- package/src/components/Replay.tsx +76 -73
- package/src/components/ShadowRoot.tsx +40 -40
- package/src/components/ShareButton/index.tsx +32 -32
- package/src/components/assistant-ui/assistant-modal.tsx +92 -87
- package/src/components/assistant-ui/assistant-sidecar.tsx +35 -35
- package/src/components/assistant-ui/attachment.tsx +80 -80
- package/src/components/assistant-ui/connection-status-indicator.tsx +33 -33
- package/src/components/assistant-ui/error-boundary.tsx +34 -34
- package/src/components/assistant-ui/follow-on-suggestions.tsx +26 -26
- package/src/components/assistant-ui/markdown-text.tsx +69 -69
- package/src/components/assistant-ui/mentioned-tools-badges.tsx +38 -38
- package/src/components/assistant-ui/message-feedback.tsx +57 -50
- package/src/components/assistant-ui/reasoning.tsx +83 -83
- package/src/components/assistant-ui/thread-list.tsx +45 -45
- package/src/components/assistant-ui/thread.tsx +278 -278
- package/src/components/assistant-ui/tool-fallback.tsx +37 -37
- package/src/components/assistant-ui/tool-group.tsx +26 -26
- package/src/components/assistant-ui/tool-mention-autocomplete.tsx +122 -122
- package/src/components/assistant-ui/tooltip-icon-button.tsx +18 -18
- package/src/components/ui/avatar.tsx +12 -12
- package/src/components/ui/button.tsx +12 -12
- package/src/components/ui/buttonVariants.ts +17 -17
- package/src/components/ui/calendar.tsx +106 -106
- package/src/components/ui/charts.stories.tsx +56 -56
- package/src/components/ui/collapsible.tsx +5 -5
- package/src/components/ui/dialog.tsx +30 -30
- package/src/components/ui/generative-ui.stories.tsx +200 -200
- package/src/components/ui/generative-ui.tsx +26 -26
- package/src/components/ui/popover.tsx +14 -14
- package/src/components/ui/skeleton.tsx +5 -5
- package/src/components/ui/time-range-picker.stories.tsx +80 -80
- package/src/components/ui/time-range-picker.tsx +248 -246
- package/src/components/ui/tool-ui.stories.tsx +37 -37
- package/src/components/ui/tool-ui.tsx +221 -215
- package/src/components/ui/tooltip.tsx +15 -15
- package/src/constants/tailwind.ts +1 -1
- package/src/contexts/ChatIdContext.tsx +7 -7
- package/src/contexts/ConnectionStatusContext.tsx +64 -64
- package/src/contexts/ElementsProvider.tsx +214 -213
- package/src/contexts/ReplayContext.ts +3 -3
- package/src/contexts/ToolApprovalContext.tsx +54 -54
- package/src/contexts/ToolExecutionContext.tsx +34 -34
- package/src/contexts/contexts.ts +7 -7
- package/src/contexts/portal-container-context.ts +2 -2
- package/src/contexts/portal-container.tsx +7 -7
- package/src/embedded.ts +1 -1
- package/src/global.css +25 -25
- package/src/hooks/useAuth.ts +72 -72
- package/src/hooks/useDensity.ts +79 -79
- package/src/hooks/useElements.ts +6 -6
- package/src/hooks/useExpanded.ts +12 -12
- package/src/hooks/useFollowOnSuggestions.ts +83 -83
- package/src/hooks/useGramThreadListAdapter.tsx +99 -99
- package/src/hooks/useMCPTools.ts +47 -47
- package/src/hooks/useModel.ts +14 -14
- package/src/hooks/usePluginComponents.ts +11 -11
- package/src/hooks/usePortalContainer.ts +5 -5
- package/src/hooks/useRadius.ts +23 -23
- package/src/hooks/useRecordCassette.ts +34 -34
- package/src/hooks/useSession.ts +11 -11
- package/src/hooks/useThemeProps.ts +13 -13
- package/src/hooks/useThreadId.ts +4 -4
- package/src/hooks/useToolApproval.ts +7 -7
- package/src/hooks/useToolMentions.ts +40 -40
- package/src/index.ts +26 -26
- package/src/lib/api.test.ts +61 -61
- package/src/lib/api.ts +4 -3
- package/src/lib/auth.ts +13 -13
- package/src/lib/cassette.ts +84 -84
- package/src/lib/easing.ts +1 -1
- package/src/lib/errorTracking.config.ts +5 -5
- package/src/lib/errorTracking.ts +29 -29
- package/src/lib/generative-ui.ts +7 -7
- package/src/lib/humanize.ts +3 -3
- package/src/lib/messageConverter.test.ts +130 -127
- package/src/lib/messageConverter.ts +196 -196
- package/src/lib/models.ts +28 -20
- package/src/lib/token.test.ts +56 -56
- package/src/lib/token.ts +14 -14
- package/src/lib/tool-mentions.ts +45 -45
- package/src/lib/tools.ts +66 -62
- package/src/lib/utils.ts +5 -5
- package/src/lib.d.ts +1 -1
- package/src/plugins/README.md +5 -5
- package/src/plugins/chart/catalog.ts +18 -18
- package/src/plugins/chart/chart.test.ts +31 -31
- package/src/plugins/chart/component.tsx +34 -34
- package/src/plugins/chart/index.ts +4 -4
- package/src/plugins/chart/ui/area-chart.tsx +42 -42
- package/src/plugins/chart/ui/bar-chart.tsx +46 -46
- package/src/plugins/chart/ui/donut-chart.tsx +48 -48
- package/src/plugins/chart/ui/index.ts +7 -7
- package/src/plugins/chart/ui/line-chart.tsx +43 -43
- package/src/plugins/chart/ui/pie-chart.tsx +44 -44
- package/src/plugins/chart/ui/radar-chart.tsx +33 -33
- package/src/plugins/chart/ui/scatter-chart.tsx +43 -43
- package/src/plugins/components/MacOSWindowFrame.tsx +15 -15
- package/src/plugins/components/PluginLoadingState.tsx +10 -10
- package/src/plugins/components/index.ts +1 -1
- package/src/plugins/generative-ui/catalog.ts +54 -54
- package/src/plugins/generative-ui/component.tsx +85 -85
- package/src/plugins/generative-ui/index.ts +4 -4
- package/src/plugins/generative-ui/ui/accordion-wrapper.tsx +16 -16
- package/src/plugins/generative-ui/ui/accordion.tsx +16 -16
- package/src/plugins/generative-ui/ui/action-button.tsx +28 -28
- package/src/plugins/generative-ui/ui/alert-wrapper.tsx +8 -8
- package/src/plugins/generative-ui/ui/alert.tsx +20 -20
- package/src/plugins/generative-ui/ui/avatar-wrapper.tsx +7 -7
- package/src/plugins/generative-ui/ui/avatar.tsx +30 -30
- package/src/plugins/generative-ui/ui/badge.tsx +22 -22
- package/src/plugins/generative-ui/ui/button-wrapper.tsx +12 -12
- package/src/plugins/generative-ui/ui/button.tsx +28 -28
- package/src/plugins/generative-ui/ui/card-wrapper.tsx +8 -8
- package/src/plugins/generative-ui/ui/card.tsx +27 -27
- package/src/plugins/generative-ui/ui/checkbox-wrapper.tsx +9 -9
- package/src/plugins/generative-ui/ui/checkbox.tsx +9 -9
- package/src/plugins/generative-ui/ui/data-table.tsx +8 -8
- package/src/plugins/generative-ui/ui/dialog.tsx +31 -31
- package/src/plugins/generative-ui/ui/dropdown-menu.tsx +44 -44
- package/src/plugins/generative-ui/ui/grid.tsx +12 -12
- package/src/plugins/generative-ui/ui/index.ts +40 -40
- package/src/plugins/generative-ui/ui/input-wrapper.tsx +11 -11
- package/src/plugins/generative-ui/ui/input.tsx +9 -9
- package/src/plugins/generative-ui/ui/label.tsx +8 -8
- package/src/plugins/generative-ui/ui/list.tsx +11 -11
- package/src/plugins/generative-ui/ui/metric.tsx +23 -23
- package/src/plugins/generative-ui/ui/pagination.tsx +28 -28
- package/src/plugins/generative-ui/ui/popover.tsx +21 -21
- package/src/plugins/generative-ui/ui/progress.tsx +13 -13
- package/src/plugins/generative-ui/ui/radio-group.tsx +12 -12
- package/src/plugins/generative-ui/ui/select-wrapper.tsx +7 -7
- package/src/plugins/generative-ui/ui/select.tsx +37 -37
- package/src/plugins/generative-ui/ui/separator.tsx +9 -9
- package/src/plugins/generative-ui/ui/skeleton-wrapper.tsx +10 -10
- package/src/plugins/generative-ui/ui/skeleton.tsx +5 -5
- package/src/plugins/generative-ui/ui/stack.tsx +28 -28
- package/src/plugins/generative-ui/ui/switch.tsx +11 -11
- package/src/plugins/generative-ui/ui/table.tsx +32 -32
- package/src/plugins/generative-ui/ui/tabs-wrapper.tsx +11 -11
- package/src/plugins/generative-ui/ui/tabs.tsx +26 -26
- package/src/plugins/generative-ui/ui/text.tsx +12 -12
- package/src/plugins/generative-ui/ui/textarea.tsx +7 -7
- package/src/plugins/generative-ui/ui/tooltip.tsx +12 -12
- package/src/plugins/index.ts +7 -7
- package/src/react-shim.ts +6 -6
- package/src/server/bun.ts +12 -12
- package/src/server/core.ts +25 -25
- package/src/server/express.ts +17 -15
- package/src/server/fastify.ts +14 -14
- package/src/server/hono.ts +9 -9
- package/src/server/nextjs.ts +12 -12
- package/src/server/tanstack-start.ts +12 -12
- package/src/server.ts +27 -27
- package/src/storybook.d.ts +4 -4
- package/src/types/index.ts +124 -124
- package/src/types/plugins.ts +7 -7
- package/src/vite-env.d.ts +12 -12
- package/dist/compat-shims-BPJ7Q68c.js.map +0 -1
- package/dist/index-D0bAYNQy.js.map +0 -1
- package/dist/index-KSX4Qjip.cjs.map +0 -1
package/src/lib/tools.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type { ToolsFilter } from
|
|
1
|
+
import type { ToolsFilter } from "@/types";
|
|
2
2
|
import {
|
|
3
3
|
AssistantToolProps,
|
|
4
4
|
Tool,
|
|
5
5
|
makeAssistantTool,
|
|
6
|
-
} from
|
|
7
|
-
import { JSONSchema7, ToolSet, type ToolCallOptions } from
|
|
8
|
-
import { FC } from
|
|
9
|
-
import z from
|
|
6
|
+
} from "@assistant-ui/react";
|
|
7
|
+
import { JSONSchema7, ToolSet, type ToolCallOptions } from "ai";
|
|
8
|
+
import { FC } from "react";
|
|
9
|
+
import z from "zod";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Converts from assistant-ui tool format to the AI SDK tool shape
|
|
@@ -21,9 +21,9 @@ export const toAISDKTools = (tools: Record<string, Tool>) => {
|
|
|
21
21
|
? z.toJSONSchema(tool.parameters)
|
|
22
22
|
: tool.parameters) as JSONSchema7,
|
|
23
23
|
},
|
|
24
|
-
])
|
|
25
|
-
)
|
|
26
|
-
}
|
|
24
|
+
]),
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Returns only frontend tools that are enabled
|
|
@@ -31,10 +31,10 @@ export const toAISDKTools = (tools: Record<string, Tool>) => {
|
|
|
31
31
|
export const getEnabledTools = (tools: Record<string, Tool>) => {
|
|
32
32
|
return Object.fromEntries(
|
|
33
33
|
Object.entries(tools).filter(
|
|
34
|
-
([, tool]) => !tool.disabled && tool.type !==
|
|
35
|
-
)
|
|
36
|
-
)
|
|
37
|
-
}
|
|
34
|
+
([, tool]) => !tool.disabled && tool.type !== "backend",
|
|
35
|
+
),
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
40
|
* A frontend tool is a tool that is defined by the user and can be used in the chat.
|
|
@@ -42,37 +42,37 @@ export const getEnabledTools = (tools: Record<string, Tool>) => {
|
|
|
42
42
|
export type FrontendTool<TArgs extends Record<string, unknown>, TResult> = FC<
|
|
43
43
|
AssistantToolProps<TArgs, TResult>
|
|
44
44
|
> & {
|
|
45
|
-
unstable_tool: AssistantToolProps<TArgs, TResult
|
|
46
|
-
}
|
|
45
|
+
unstable_tool: AssistantToolProps<TArgs, TResult>;
|
|
46
|
+
};
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
49
|
* Module-level approval config that gets set by ElementsProvider at runtime.
|
|
50
50
|
* This allows defineFrontendTool to check approval status during execute.
|
|
51
51
|
*/
|
|
52
52
|
let approvalConfig: {
|
|
53
|
-
helpers: ApprovalHelpers
|
|
54
|
-
requiresApproval: (toolName: string) => boolean
|
|
55
|
-
} | null = null
|
|
53
|
+
helpers: ApprovalHelpers;
|
|
54
|
+
requiresApproval: (toolName: string) => boolean;
|
|
55
|
+
} | null = null;
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
58
|
* Sets the approval configuration. Called by ElementsProvider.
|
|
59
59
|
*/
|
|
60
60
|
export function setFrontendToolApprovalConfig(
|
|
61
61
|
helpers: ApprovalHelpers,
|
|
62
|
-
toolsRequiringApproval: ToolsFilter
|
|
62
|
+
toolsRequiringApproval: ToolsFilter,
|
|
63
63
|
): void {
|
|
64
|
-
const requiresApproval = createRequiresApprovalFn(toolsRequiringApproval)
|
|
64
|
+
const requiresApproval = createRequiresApprovalFn(toolsRequiringApproval);
|
|
65
65
|
approvalConfig = {
|
|
66
66
|
helpers,
|
|
67
67
|
requiresApproval,
|
|
68
|
-
}
|
|
68
|
+
};
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
/**
|
|
72
72
|
* Clears the approval configuration. Called when ElementsProvider unmounts.
|
|
73
73
|
*/
|
|
74
74
|
export function clearFrontendToolApprovalConfig(): void {
|
|
75
|
-
approvalConfig = null
|
|
75
|
+
approvalConfig = null;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
/**
|
|
@@ -80,18 +80,18 @@ export function clearFrontendToolApprovalConfig(): void {
|
|
|
80
80
|
* Handles both array and function-based configurations.
|
|
81
81
|
*/
|
|
82
82
|
function createRequiresApprovalFn(
|
|
83
|
-
toolsRequiringApproval: ToolsFilter | undefined
|
|
83
|
+
toolsRequiringApproval: ToolsFilter | undefined,
|
|
84
84
|
): (toolName: string) => boolean {
|
|
85
85
|
if (!toolsRequiringApproval) {
|
|
86
|
-
return () => false
|
|
86
|
+
return () => false;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
if (typeof toolsRequiringApproval ===
|
|
90
|
-
return (toolName: string) => toolsRequiringApproval({ toolName })
|
|
89
|
+
if (typeof toolsRequiringApproval === "function") {
|
|
90
|
+
return (toolName: string) => toolsRequiringApproval({ toolName });
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
const approvalSet = new Set(toolsRequiringApproval)
|
|
94
|
-
return (toolName: string) => approvalSet.has(toolName)
|
|
93
|
+
const approvalSet = new Set(toolsRequiringApproval);
|
|
94
|
+
return (toolName: string) => approvalSet.has(toolName);
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
/**
|
|
@@ -102,42 +102,46 @@ export const defineFrontendTool = <
|
|
|
102
102
|
TResult,
|
|
103
103
|
>(
|
|
104
104
|
tool: Tool,
|
|
105
|
-
name: string
|
|
105
|
+
name: string,
|
|
106
106
|
): FrontendTool<TArgs, TResult> => {
|
|
107
107
|
type ToolExecutionContext = Parameters<
|
|
108
|
-
NonNullable<Tool<Record<string, unknown>, void>[
|
|
109
|
-
>[1]
|
|
108
|
+
NonNullable<Tool<Record<string, unknown>, void>["execute"]>
|
|
109
|
+
>[1];
|
|
110
110
|
return makeAssistantTool({
|
|
111
111
|
...tool,
|
|
112
112
|
execute: async (args: TArgs, context: ToolExecutionContext) => {
|
|
113
113
|
// Check if this tool requires approval at runtime
|
|
114
114
|
if (approvalConfig?.requiresApproval(name)) {
|
|
115
|
-
const { helpers } = approvalConfig
|
|
116
|
-
const toolCallId = context.toolCallId ??
|
|
115
|
+
const { helpers } = approvalConfig;
|
|
116
|
+
const toolCallId = context.toolCallId ?? "";
|
|
117
117
|
|
|
118
118
|
// Check if already approved (user chose "Approve always" previously)
|
|
119
119
|
if (!helpers.isToolApproved(name)) {
|
|
120
|
-
const approved = await helpers.requestApproval(
|
|
120
|
+
const approved = await helpers.requestApproval(
|
|
121
|
+
name,
|
|
122
|
+
toolCallId,
|
|
123
|
+
args,
|
|
124
|
+
);
|
|
121
125
|
|
|
122
126
|
if (!approved) {
|
|
123
127
|
return {
|
|
124
128
|
content: [
|
|
125
129
|
{
|
|
126
|
-
type:
|
|
130
|
+
type: "text",
|
|
127
131
|
text: `Tool "${name}" execution was denied by the user. Please acknowledge this and continue without using this tool's result.`,
|
|
128
132
|
},
|
|
129
133
|
],
|
|
130
134
|
isError: true,
|
|
131
|
-
} as TResult
|
|
135
|
+
} as TResult;
|
|
132
136
|
}
|
|
133
137
|
}
|
|
134
138
|
}
|
|
135
139
|
|
|
136
|
-
return tool.execute?.(args, context)
|
|
140
|
+
return tool.execute?.(args, context);
|
|
137
141
|
},
|
|
138
142
|
toolName: name,
|
|
139
|
-
} as AssistantToolProps<TArgs, TResult>)
|
|
140
|
-
}
|
|
143
|
+
} as AssistantToolProps<TArgs, TResult>);
|
|
144
|
+
};
|
|
141
145
|
|
|
142
146
|
/**
|
|
143
147
|
* Helpers for requesting and tracking tool approval state.
|
|
@@ -146,10 +150,10 @@ export interface ApprovalHelpers {
|
|
|
146
150
|
requestApproval: (
|
|
147
151
|
toolName: string,
|
|
148
152
|
toolCallId: string,
|
|
149
|
-
args: unknown
|
|
150
|
-
) => Promise<boolean
|
|
151
|
-
isToolApproved: (toolName: string) => boolean
|
|
152
|
-
whitelistTool: (toolName: string) => void
|
|
153
|
+
args: unknown,
|
|
154
|
+
) => Promise<boolean>;
|
|
155
|
+
isToolApproved: (toolName: string) => boolean;
|
|
156
|
+
whitelistTool: (toolName: string) => void;
|
|
153
157
|
}
|
|
154
158
|
|
|
155
159
|
/**
|
|
@@ -158,10 +162,10 @@ export interface ApprovalHelpers {
|
|
|
158
162
|
export function wrapToolsWithApproval(
|
|
159
163
|
tools: ToolSet,
|
|
160
164
|
toolsRequiringApproval: ToolsFilter | undefined,
|
|
161
|
-
approvalHelpers: ApprovalHelpers
|
|
165
|
+
approvalHelpers: ApprovalHelpers,
|
|
162
166
|
): ToolSet {
|
|
163
167
|
if (!toolsRequiringApproval) {
|
|
164
|
-
return tools
|
|
168
|
+
return tools;
|
|
165
169
|
}
|
|
166
170
|
|
|
167
171
|
// Handle empty array case
|
|
@@ -169,20 +173,20 @@ export function wrapToolsWithApproval(
|
|
|
169
173
|
Array.isArray(toolsRequiringApproval) &&
|
|
170
174
|
toolsRequiringApproval.length === 0
|
|
171
175
|
) {
|
|
172
|
-
return tools
|
|
176
|
+
return tools;
|
|
173
177
|
}
|
|
174
178
|
|
|
175
|
-
const requiresApproval = createRequiresApprovalFn(toolsRequiringApproval)
|
|
179
|
+
const requiresApproval = createRequiresApprovalFn(toolsRequiringApproval);
|
|
176
180
|
|
|
177
181
|
return Object.fromEntries(
|
|
178
182
|
Object.entries(tools).map(([name, tool]) => {
|
|
179
183
|
if (!requiresApproval(name)) {
|
|
180
|
-
return [name, tool]
|
|
184
|
+
return [name, tool];
|
|
181
185
|
}
|
|
182
186
|
|
|
183
|
-
const originalExecute = tool.execute
|
|
187
|
+
const originalExecute = tool.execute;
|
|
184
188
|
if (!originalExecute) {
|
|
185
|
-
return [name, tool]
|
|
189
|
+
return [name, tool];
|
|
186
190
|
}
|
|
187
191
|
|
|
188
192
|
return [
|
|
@@ -192,36 +196,36 @@ export function wrapToolsWithApproval(
|
|
|
192
196
|
execute: async (args: unknown, options?: ToolCallOptions) => {
|
|
193
197
|
const opts = (options ?? {}) as Parameters<
|
|
194
198
|
typeof originalExecute
|
|
195
|
-
>[1]
|
|
199
|
+
>[1];
|
|
196
200
|
// Extract toolCallId from options
|
|
197
201
|
const toolCallId =
|
|
198
|
-
(opts as { toolCallId?: string }).toolCallId ??
|
|
202
|
+
(opts as { toolCallId?: string }).toolCallId ?? "";
|
|
199
203
|
|
|
200
204
|
// Check if already approved (user chose "Approve always" previously)
|
|
201
205
|
if (approvalHelpers.isToolApproved(name)) {
|
|
202
206
|
return originalExecute(
|
|
203
207
|
args,
|
|
204
|
-
opts as Parameters<typeof originalExecute>[1]
|
|
205
|
-
)
|
|
208
|
+
opts as Parameters<typeof originalExecute>[1],
|
|
209
|
+
);
|
|
206
210
|
}
|
|
207
211
|
|
|
208
212
|
// Request approval using the actual toolCallId from the stream
|
|
209
213
|
const approved = await approvalHelpers.requestApproval(
|
|
210
214
|
name,
|
|
211
215
|
toolCallId,
|
|
212
|
-
args
|
|
213
|
-
)
|
|
216
|
+
args,
|
|
217
|
+
);
|
|
214
218
|
|
|
215
219
|
if (!approved) {
|
|
216
220
|
return {
|
|
217
221
|
content: [
|
|
218
222
|
{
|
|
219
|
-
type:
|
|
223
|
+
type: "text",
|
|
220
224
|
text: `Tool "${name}" execution was denied by the user. Please acknowledge this and continue without using this tool's result.`,
|
|
221
225
|
},
|
|
222
226
|
],
|
|
223
227
|
isError: true,
|
|
224
|
-
}
|
|
228
|
+
};
|
|
225
229
|
}
|
|
226
230
|
|
|
227
231
|
// Note: Tool is marked as approved via the UI when user clicks "Approve always"
|
|
@@ -229,11 +233,11 @@ export function wrapToolsWithApproval(
|
|
|
229
233
|
|
|
230
234
|
return originalExecute(
|
|
231
235
|
args,
|
|
232
|
-
opts as Parameters<typeof originalExecute>[1]
|
|
233
|
-
)
|
|
236
|
+
opts as Parameters<typeof originalExecute>[1],
|
|
237
|
+
);
|
|
234
238
|
},
|
|
235
239
|
},
|
|
236
|
-
]
|
|
237
|
-
})
|
|
238
|
-
) as ToolSet
|
|
240
|
+
];
|
|
241
|
+
}),
|
|
242
|
+
) as ToolSet;
|
|
239
243
|
}
|
package/src/lib/utils.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { clsx, type ClassValue } from
|
|
2
|
-
import { twMerge } from
|
|
1
|
+
import { clsx, type ClassValue } from "clsx";
|
|
2
|
+
import { twMerge } from "tailwind-merge";
|
|
3
3
|
|
|
4
4
|
export function cn(...inputs: ClassValue[]) {
|
|
5
|
-
return twMerge(clsx(inputs))
|
|
5
|
+
return twMerge(clsx(inputs));
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export function assertNever(value: unknown): never {
|
|
9
|
-
throw new Error(`Unexpected value: ${value}`)
|
|
9
|
+
throw new Error(`Unexpected value: ${value}`);
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export function assert(condition: unknown, message: string): asserts condition {
|
|
13
13
|
if (!condition) {
|
|
14
|
-
throw new Error(message)
|
|
14
|
+
throw new Error(message);
|
|
15
15
|
}
|
|
16
16
|
}
|
package/src/lib.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
type FIXME<T, S extends string> = (T & S) | T
|
|
1
|
+
type FIXME<T, S extends string> = (T & S) | T;
|
package/src/plugins/README.md
CHANGED
|
@@ -19,19 +19,19 @@ A plugin is defined by the following TypeScript interface:
|
|
|
19
19
|
```typescript
|
|
20
20
|
interface Plugin {
|
|
21
21
|
// The language identifier for the code fence (e.g., "vega", "mermaid", "d3")
|
|
22
|
-
language: string
|
|
22
|
+
language: string;
|
|
23
23
|
|
|
24
24
|
// Instructions for the LLM on how to use this plugin
|
|
25
|
-
prompt: string
|
|
25
|
+
prompt: string;
|
|
26
26
|
|
|
27
27
|
// Your custom React component that renders the code block
|
|
28
|
-
SyntaxHighlighter: ComponentType<SyntaxHighlighterProps
|
|
28
|
+
SyntaxHighlighter: ComponentType<SyntaxHighlighterProps>;
|
|
29
29
|
|
|
30
30
|
// Optional: Custom header component for the code block
|
|
31
|
-
CodeHeader?: ComponentType<CodeHeaderProps> | null
|
|
31
|
+
CodeHeader?: ComponentType<CodeHeaderProps> | null;
|
|
32
32
|
|
|
33
33
|
// Optional: Whether to override existing plugins with the same language
|
|
34
|
-
overrideExisting?: boolean
|
|
34
|
+
overrideExisting?: boolean;
|
|
35
35
|
}
|
|
36
36
|
```
|
|
37
37
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createCatalog } from
|
|
2
|
-
import { z } from
|
|
1
|
+
import { createCatalog } from "@json-render/core";
|
|
2
|
+
import { z } from "zod";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Data point schema - common structure for all chart types
|
|
@@ -8,7 +8,7 @@ const dataPointSchema = z.object({
|
|
|
8
8
|
label: z.string(),
|
|
9
9
|
value: z.number(),
|
|
10
10
|
color: z.string().optional(),
|
|
11
|
-
})
|
|
11
|
+
});
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Multi-series data point for line/area charts
|
|
@@ -17,7 +17,7 @@ const seriesDataPointSchema = z
|
|
|
17
17
|
.object({
|
|
18
18
|
label: z.string(),
|
|
19
19
|
})
|
|
20
|
-
.catchall(z.number())
|
|
20
|
+
.catchall(z.number());
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Chart Catalog
|
|
@@ -26,19 +26,19 @@ const seriesDataPointSchema = z
|
|
|
26
26
|
* Uses Recharts under the hood for rendering.
|
|
27
27
|
*/
|
|
28
28
|
export const chartCatalog = createCatalog({
|
|
29
|
-
name:
|
|
29
|
+
name: "chart",
|
|
30
30
|
components: {
|
|
31
31
|
BarChart: {
|
|
32
32
|
props: z.object({
|
|
33
33
|
title: z.string().optional(),
|
|
34
34
|
data: z.array(dataPointSchema),
|
|
35
|
-
layout: z.enum([
|
|
35
|
+
layout: z.enum(["vertical", "horizontal"]).optional(),
|
|
36
36
|
showGrid: z.boolean().optional(),
|
|
37
37
|
showLegend: z.boolean().optional(),
|
|
38
38
|
className: z.string().optional(),
|
|
39
39
|
}),
|
|
40
40
|
description:
|
|
41
|
-
|
|
41
|
+
"Bar chart for comparing categorical data. Use vertical for few categories, horizontal for many or long labels.",
|
|
42
42
|
},
|
|
43
43
|
|
|
44
44
|
LineChart: {
|
|
@@ -53,7 +53,7 @@ export const chartCatalog = createCatalog({
|
|
|
53
53
|
className: z.string().optional(),
|
|
54
54
|
}),
|
|
55
55
|
description:
|
|
56
|
-
|
|
56
|
+
"Line chart for showing trends over time or continuous data. Supports multiple series.",
|
|
57
57
|
},
|
|
58
58
|
|
|
59
59
|
AreaChart: {
|
|
@@ -67,7 +67,7 @@ export const chartCatalog = createCatalog({
|
|
|
67
67
|
className: z.string().optional(),
|
|
68
68
|
}),
|
|
69
69
|
description:
|
|
70
|
-
|
|
70
|
+
"Area chart for showing volume/magnitude over time. Use stacked for part-to-whole relationships.",
|
|
71
71
|
},
|
|
72
72
|
|
|
73
73
|
PieChart: {
|
|
@@ -79,7 +79,7 @@ export const chartCatalog = createCatalog({
|
|
|
79
79
|
className: z.string().optional(),
|
|
80
80
|
}),
|
|
81
81
|
description:
|
|
82
|
-
|
|
82
|
+
"Pie chart for showing proportions of a whole. Best for 2-6 categories.",
|
|
83
83
|
},
|
|
84
84
|
|
|
85
85
|
DonutChart: {
|
|
@@ -93,7 +93,7 @@ export const chartCatalog = createCatalog({
|
|
|
93
93
|
className: z.string().optional(),
|
|
94
94
|
}),
|
|
95
95
|
description:
|
|
96
|
-
|
|
96
|
+
"Donut chart (pie with center hole). Good for showing a key metric in the center.",
|
|
97
97
|
},
|
|
98
98
|
|
|
99
99
|
ScatterChart: {
|
|
@@ -106,7 +106,7 @@ export const chartCatalog = createCatalog({
|
|
|
106
106
|
label: z.string().optional(),
|
|
107
107
|
size: z.number().optional(),
|
|
108
108
|
color: z.string().optional(),
|
|
109
|
-
})
|
|
109
|
+
}),
|
|
110
110
|
),
|
|
111
111
|
xLabel: z.string().optional(),
|
|
112
112
|
yLabel: z.string().optional(),
|
|
@@ -114,7 +114,7 @@ export const chartCatalog = createCatalog({
|
|
|
114
114
|
className: z.string().optional(),
|
|
115
115
|
}),
|
|
116
116
|
description:
|
|
117
|
-
|
|
117
|
+
"Scatter plot for showing correlation between two variables.",
|
|
118
118
|
},
|
|
119
119
|
|
|
120
120
|
RadarChart: {
|
|
@@ -125,17 +125,17 @@ export const chartCatalog = createCatalog({
|
|
|
125
125
|
className: z.string().optional(),
|
|
126
126
|
}),
|
|
127
127
|
description:
|
|
128
|
-
|
|
128
|
+
"Radar/spider chart for comparing multiple attributes. Best for 3-8 dimensions.",
|
|
129
129
|
},
|
|
130
130
|
},
|
|
131
|
-
})
|
|
131
|
+
});
|
|
132
132
|
|
|
133
133
|
export type ChartCatalogComponentProps = typeof chartCatalog extends {
|
|
134
|
-
components: infer C
|
|
134
|
+
components: infer C;
|
|
135
135
|
}
|
|
136
136
|
? {
|
|
137
137
|
[K in keyof C]: C[K] extends { props: infer P }
|
|
138
138
|
? z.infer<P extends z.ZodType ? P : never>
|
|
139
|
-
: never
|
|
139
|
+
: never;
|
|
140
140
|
}
|
|
141
|
-
: never
|
|
141
|
+
: never;
|
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
import { describe, it, expect } from
|
|
2
|
-
import { parse, View, Warn } from
|
|
3
|
-
import { expressionInterpreter } from
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { parse, View, Warn } from "vega";
|
|
3
|
+
import { expressionInterpreter } from "vega-interpreter";
|
|
4
4
|
|
|
5
|
-
describe(
|
|
6
|
-
it(
|
|
5
|
+
describe("ChartRenderer CSP compliance", () => {
|
|
6
|
+
it("renders a chart using vega-interpreter without eval", async () => {
|
|
7
7
|
const spec = {
|
|
8
|
-
$schema:
|
|
8
|
+
$schema: "https://vega.github.io/schema/vega/v5.json",
|
|
9
9
|
width: 400,
|
|
10
10
|
height: 200,
|
|
11
11
|
data: [
|
|
12
12
|
{
|
|
13
|
-
name:
|
|
13
|
+
name: "table",
|
|
14
14
|
values: [
|
|
15
|
-
{ category:
|
|
16
|
-
{ category:
|
|
15
|
+
{ category: "A", amount: 28 },
|
|
16
|
+
{ category: "B", amount: 55 },
|
|
17
17
|
],
|
|
18
18
|
},
|
|
19
19
|
],
|
|
20
20
|
marks: [
|
|
21
21
|
{
|
|
22
|
-
type:
|
|
23
|
-
from: { data:
|
|
22
|
+
type: "rect",
|
|
23
|
+
from: { data: "table" },
|
|
24
24
|
encode: {
|
|
25
25
|
enter: {
|
|
26
|
-
x: { scale:
|
|
27
|
-
width: { scale:
|
|
28
|
-
y: { scale:
|
|
29
|
-
y2: { scale:
|
|
26
|
+
x: { scale: "xscale", field: "category" },
|
|
27
|
+
width: { scale: "xscale", band: 1 },
|
|
28
|
+
y: { scale: "yscale", field: "amount" },
|
|
29
|
+
y2: { scale: "yscale", value: 0 },
|
|
30
30
|
},
|
|
31
31
|
},
|
|
32
32
|
},
|
|
33
33
|
],
|
|
34
34
|
scales: [
|
|
35
35
|
{
|
|
36
|
-
name:
|
|
37
|
-
type:
|
|
38
|
-
domain: { data:
|
|
39
|
-
range:
|
|
36
|
+
name: "xscale",
|
|
37
|
+
type: "band",
|
|
38
|
+
domain: { data: "table", field: "category" },
|
|
39
|
+
range: "width",
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
|
-
name:
|
|
43
|
-
domain: { data:
|
|
44
|
-
range:
|
|
42
|
+
name: "yscale",
|
|
43
|
+
domain: { data: "table", field: "amount" },
|
|
44
|
+
range: "height",
|
|
45
45
|
},
|
|
46
46
|
],
|
|
47
|
-
}
|
|
47
|
+
};
|
|
48
48
|
|
|
49
49
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
50
|
-
const runtime = parse(spec as any, undefined, { ast: true })
|
|
50
|
+
const runtime = parse(spec as any, undefined, { ast: true });
|
|
51
51
|
|
|
52
52
|
// This is the key - using expr: vegaInterpreter means no eval() is called
|
|
53
53
|
const view = new View(runtime, {
|
|
54
|
-
renderer:
|
|
54
|
+
renderer: "none",
|
|
55
55
|
logLevel: Warn,
|
|
56
56
|
expr: expressionInterpreter,
|
|
57
|
-
})
|
|
57
|
+
});
|
|
58
58
|
|
|
59
|
-
await view.runAsync()
|
|
59
|
+
await view.runAsync();
|
|
60
60
|
|
|
61
61
|
// If we get here without error, CSP compliance works
|
|
62
|
-
expect(view.data(
|
|
62
|
+
expect(view.data("table")).toHaveLength(2);
|
|
63
63
|
|
|
64
|
-
view.finalize()
|
|
65
|
-
})
|
|
66
|
-
})
|
|
64
|
+
view.finalize();
|
|
65
|
+
});
|
|
66
|
+
});
|