mirror of
https://github.com/Mintplex-Labs/anything-llm.git
synced 2024-11-13 02:00:10 +01:00
Agent skill: chart generation (#1103)
* WIP agent support * move agent folder * wip frontend socket * checkpoint * fix schema * Checkpoint for plugins and AgentHandler * refactor plugins and agent arch * agent error reporting and handling * add frontend elements for agents in prompt input * WIP integrations for agents * enable web-search agent config from frontend * persist chat history * update alert * update migration remove console logs update close state for agent invocations * add examples to dockerignore Extract statusResponse to its own component * update close method * wrap scraping rejections * add RAG search as funciton * Add telem and link highlight * chat support * patch memory * Add rechart as a plugin option * Toggles for abilites of default agent (system wide) Validate values for agent skills Enable dynamic loading of skills UI for toggle of skills * add UI for toggle of configs for agent * toggle WS or WSS protocol * update NGNIX proxy pass * move components around and capture failed websocket creation * fix name * tmp docker image * reset workflow * safety mark functions * telem on tool calls * remove hardcode short circuit * separate web-browser from scrape * extract summarizer to util add abort handlers and controller for langchain stuff so socket close kills process * langchain summarize verbose when in dev * chart styling improvements + add title to chart * fix legend from being cutoff in chart downloads * remove cursor blink --------- Co-authored-by: shatfield4 <seanhatfield5@gmail.com>
This commit is contained in:
parent
331423f864
commit
2e813846dc
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -5,7 +5,10 @@
|
||||
"aibitat",
|
||||
"anythingllm",
|
||||
"Astra",
|
||||
"Chartable",
|
||||
"comkey",
|
||||
"cooldown",
|
||||
"cooldowns",
|
||||
"Deduplicator",
|
||||
"Dockerized",
|
||||
"Embeddable",
|
||||
|
@ -14,6 +14,7 @@
|
||||
"@metamask/jazzicon": "^2.0.0",
|
||||
"@microsoft/fetch-event-source": "^2.0.1",
|
||||
"@phosphor-icons/react": "^2.0.13",
|
||||
"@tremor/react": "^3.15.1",
|
||||
"dompurify": "^3.0.8",
|
||||
"file-saver": "^2.0.5",
|
||||
"he": "^1.2.0",
|
||||
@ -30,6 +31,8 @@
|
||||
"react-tag-input-component": "^2.0.2",
|
||||
"react-toastify": "^9.1.3",
|
||||
"react-tooltip": "^5.25.2",
|
||||
"recharts": "^2.12.5",
|
||||
"recharts-to-png": "^2.3.1",
|
||||
"text-case": "^1.0.9",
|
||||
"truncate": "^3.0.0",
|
||||
"uuid": "^9.0.0"
|
||||
|
@ -0,0 +1,50 @@
|
||||
export default function CustomCell({ ...props }) {
|
||||
const {
|
||||
root,
|
||||
depth,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
index,
|
||||
payload,
|
||||
colors,
|
||||
rank,
|
||||
name,
|
||||
} = props;
|
||||
return (
|
||||
<g>
|
||||
<rect
|
||||
x={x}
|
||||
y={y}
|
||||
width={width}
|
||||
height={height}
|
||||
style={{
|
||||
fill:
|
||||
depth < 2
|
||||
? colors[Math.floor((index / root.children.length) * 6)]
|
||||
: "#ffffff00",
|
||||
stroke: "#fff",
|
||||
strokeWidth: 2 / (depth + 1e-10),
|
||||
strokeOpacity: 1 / (depth + 1e-10),
|
||||
}}
|
||||
/>
|
||||
{depth === 1 ? (
|
||||
<text
|
||||
x={x + width / 2}
|
||||
y={y + height / 2 + 7}
|
||||
textAnchor="middle"
|
||||
fill="#fff"
|
||||
fontSize={14}
|
||||
>
|
||||
{name}
|
||||
</text>
|
||||
) : null}
|
||||
{depth === 1 ? (
|
||||
<text x={x + 4} y={y + 18} fill="#fff" fontSize={16} fillOpacity={0.9}>
|
||||
{index + 1}
|
||||
</text>
|
||||
) : null}
|
||||
</g>
|
||||
);
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
import { Tooltip as RechartsTooltip } from "recharts";
|
||||
|
||||
// Given a hex, convert to the opposite highest-contrast color
|
||||
// and if `bw` is enabled, force it to be black/white to normalize
|
||||
// interface.
|
||||
function invertColor(hex, bw) {
|
||||
if (hex.indexOf("#") === 0) {
|
||||
hex = hex.slice(1);
|
||||
}
|
||||
// convert 3-digit hex to 6-digits.
|
||||
if (hex.length === 3) {
|
||||
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
|
||||
}
|
||||
if (hex.length !== 6) {
|
||||
throw new Error("Invalid HEX color.");
|
||||
}
|
||||
var r = parseInt(hex.slice(0, 2), 16),
|
||||
g = parseInt(hex.slice(2, 4), 16),
|
||||
b = parseInt(hex.slice(4, 6), 16);
|
||||
if (bw) {
|
||||
// https://stackoverflow.com/a/3943023/112731
|
||||
return r * 0.299 + g * 0.587 + b * 0.114 > 186 ? "#FFFFFF" : "#000000";
|
||||
// : '#FFFFFF';
|
||||
}
|
||||
// invert color components
|
||||
r = (255 - r).toString(16);
|
||||
g = (255 - g).toString(16);
|
||||
b = (255 - b).toString(16);
|
||||
// pad each with zeros and return
|
||||
return "#" + padZero(r) + padZero(g) + padZero(b);
|
||||
}
|
||||
|
||||
function padZero(str, len) {
|
||||
len = len || 2;
|
||||
var zeros = new Array(len).join("0");
|
||||
return (zeros + str).slice(-len);
|
||||
}
|
||||
|
||||
export default function Tooltip({ legendColor, ...props }) {
|
||||
return (
|
||||
<RechartsTooltip
|
||||
wrapperStyle={{ outline: "none" }}
|
||||
isAnimationActive={false}
|
||||
cursor={{ fill: "#d1d5db", opacity: "0.15" }}
|
||||
position={{ y: 0 }}
|
||||
{...props}
|
||||
content={({ active, payload, label }) => {
|
||||
return active && payload ? (
|
||||
<div className="bg-white text-sm rounded-md border shadow-lg">
|
||||
<div className="border-b py-2 px-4">
|
||||
<p className="text-elem text-gray-700 font-medium">{label}</p>
|
||||
</div>
|
||||
<div className="space-y-1 py-2 px-4">
|
||||
{payload.map(({ value, name }, idx) => (
|
||||
<div
|
||||
key={`id-${idx}`}
|
||||
className="flex items-center justify-between space-x-8"
|
||||
>
|
||||
<div className="flex items-center space-x-2">
|
||||
<span
|
||||
className="shrink-0 h-3 w-3 border-white rounded-md rounded-full border-2 shadow-md"
|
||||
style={{ backgroundColor: legendColor }}
|
||||
/>
|
||||
<p
|
||||
style={{
|
||||
color: invertColor(legendColor, true),
|
||||
}}
|
||||
className="font-medium tabular-nums text-right whitespace-nowrap"
|
||||
>
|
||||
{value}
|
||||
</p>
|
||||
</div>
|
||||
<p
|
||||
style={{
|
||||
color: invertColor(legendColor, true),
|
||||
}}
|
||||
className="whitespace-nowrap font-normal"
|
||||
>
|
||||
{name}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : null;
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
export const Colors = {
|
||||
blue: "#3b82f6",
|
||||
sky: "#0ea5e9",
|
||||
cyan: "#06b6d4",
|
||||
teal: "#14b8a6",
|
||||
emerald: "#10b981",
|
||||
green: "#22c55e",
|
||||
lime: "#84cc16",
|
||||
yellow: "#eab308",
|
||||
amber: "#f59e0b",
|
||||
orange: "#f97316",
|
||||
red: "#ef4444",
|
||||
rose: "#f43f5e",
|
||||
pink: "#ec4899",
|
||||
fuchsia: "#d946ef",
|
||||
purple: "#a855f7",
|
||||
violet: "#8b5cf6",
|
||||
indigo: "#6366f1",
|
||||
neutral: "#737373",
|
||||
stone: "#78716c",
|
||||
gray: "#6b7280",
|
||||
slate: "#64748b",
|
||||
zinc: "#71717a",
|
||||
};
|
||||
|
||||
export function getTremorColor(color) {
|
||||
switch (color) {
|
||||
case "blue":
|
||||
return Colors.blue;
|
||||
case "sky":
|
||||
return Colors.sky;
|
||||
case "cyan":
|
||||
return Colors.cyan;
|
||||
case "teal":
|
||||
return Colors.teal;
|
||||
case "emerald":
|
||||
return Colors.emerald;
|
||||
case "green":
|
||||
return Colors.green;
|
||||
case "lime":
|
||||
return Colors.lime;
|
||||
case "yellow":
|
||||
return Colors.yellow;
|
||||
case "amber":
|
||||
return Colors.amber;
|
||||
case "orange":
|
||||
return Colors.orange;
|
||||
case "red":
|
||||
return Colors.red;
|
||||
case "rose":
|
||||
return Colors.rose;
|
||||
case "pink":
|
||||
return Colors.pink;
|
||||
case "fuchsia":
|
||||
return Colors.fuchsia;
|
||||
case "purple":
|
||||
return Colors.purple;
|
||||
case "violet":
|
||||
return Colors.violet;
|
||||
case "indigo":
|
||||
return Colors.indigo;
|
||||
case "neutral":
|
||||
return Colors.neutral;
|
||||
case "stone":
|
||||
return Colors.stone;
|
||||
case "gray":
|
||||
return Colors.gray;
|
||||
case "slate":
|
||||
return Colors.slate;
|
||||
case "zinc":
|
||||
return Colors.zinc;
|
||||
}
|
||||
}
|
||||
|
||||
export const themeColorRange = [
|
||||
"slate",
|
||||
"gray",
|
||||
"zinc",
|
||||
"neutral",
|
||||
"stone",
|
||||
"red",
|
||||
"orange",
|
||||
"amber",
|
||||
"yellow",
|
||||
"lime",
|
||||
"green",
|
||||
"emerald",
|
||||
"teal",
|
||||
"cyan",
|
||||
"sky",
|
||||
"blue",
|
||||
"indigo",
|
||||
"violet",
|
||||
"purple",
|
||||
"fuchsia",
|
||||
"pink",
|
||||
"rose",
|
||||
];
|
@ -0,0 +1,467 @@
|
||||
import { v4 } from "uuid";
|
||||
import {
|
||||
AreaChart,
|
||||
BarChart,
|
||||
DonutChart,
|
||||
Legend,
|
||||
LineChart,
|
||||
} from "@tremor/react";
|
||||
import {
|
||||
Bar,
|
||||
CartesianGrid,
|
||||
ComposedChart,
|
||||
Funnel,
|
||||
FunnelChart,
|
||||
Line,
|
||||
PolarAngleAxis,
|
||||
PolarGrid,
|
||||
PolarRadiusAxis,
|
||||
Radar,
|
||||
RadarChart,
|
||||
RadialBar,
|
||||
RadialBarChart,
|
||||
Scatter,
|
||||
ScatterChart,
|
||||
Treemap,
|
||||
XAxis,
|
||||
YAxis,
|
||||
} from "recharts";
|
||||
import { Colors, getTremorColor } from "./chart-utils.js";
|
||||
import CustomCell from "./CustomCell.jsx";
|
||||
import Tooltip from "./CustomTooltip.jsx";
|
||||
import { safeJsonParse } from "@/utils/request.js";
|
||||
import renderMarkdown from "@/utils/chat/markdown.js";
|
||||
import { WorkspaceProfileImage } from "../PromptReply/index.jsx";
|
||||
import { memo, useCallback, useState } from "react";
|
||||
import { saveAs } from "file-saver";
|
||||
import { useGenerateImage } from "recharts-to-png";
|
||||
import { CircleNotch, DownloadSimple } from "@phosphor-icons/react";
|
||||
|
||||
const dataFormatter = (number) => {
|
||||
return Intl.NumberFormat("us").format(number).toString();
|
||||
};
|
||||
|
||||
export function Chartable({ props, workspace }) {
|
||||
const [getDivJpeg, { ref }] = useGenerateImage({
|
||||
quality: 1,
|
||||
type: "image/jpeg",
|
||||
options: {
|
||||
backgroundColor: "#393d43",
|
||||
padding: 20,
|
||||
},
|
||||
});
|
||||
const handleDownload = useCallback(async () => {
|
||||
const jpeg = await getDivJpeg();
|
||||
if (jpeg) saveAs(jpeg, `chart-${v4().split("-")[0]}.jpg`);
|
||||
}, []);
|
||||
|
||||
const color = null;
|
||||
const showLegend = true;
|
||||
const content =
|
||||
typeof props.content === "string"
|
||||
? safeJsonParse(props.content, null)
|
||||
: props.content;
|
||||
if (content === null) return null;
|
||||
|
||||
const chartType = content?.type?.toLowerCase();
|
||||
const data =
|
||||
typeof content.dataset === "string"
|
||||
? safeJsonParse(content.dataset, null)
|
||||
: content.dataset;
|
||||
const value = data.length > 0 ? Object.keys(data[0])[1] : "value";
|
||||
const title = content?.title;
|
||||
|
||||
const renderChart = () => {
|
||||
switch (chartType) {
|
||||
case "area":
|
||||
return (
|
||||
<div className="bg-zinc-900 p-8 rounded-xl text-white">
|
||||
<h3 className="text-lg font-medium">{title}</h3>
|
||||
<AreaChart
|
||||
className="h-[350px]"
|
||||
data={data}
|
||||
index="name"
|
||||
categories={[value]}
|
||||
colors={[color || "blue", "cyan"]}
|
||||
showLegend={showLegend}
|
||||
valueFormatter={dataFormatter}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
case "bar":
|
||||
return (
|
||||
<div className="bg-zinc-900 p-8 rounded-xl text-white">
|
||||
<h3 className="text-lg font-medium">{title}</h3>
|
||||
<BarChart
|
||||
className="h-[350px]"
|
||||
data={data}
|
||||
index="name"
|
||||
categories={[value]}
|
||||
colors={[color || "blue"]}
|
||||
showLegend={showLegend}
|
||||
valueFormatter={dataFormatter}
|
||||
layout={"vertical"}
|
||||
yAxisWidth={100}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
case "line":
|
||||
return (
|
||||
<div className="bg-zinc-900 p-8 pb-12 rounded-xl text-white h-[500px]">
|
||||
<h3 className="text-lg font-medium">{title}</h3>
|
||||
<LineChart
|
||||
className="h-[400px]"
|
||||
data={data}
|
||||
index="name"
|
||||
categories={[value]}
|
||||
colors={[color || "blue"]}
|
||||
showLegend={showLegend}
|
||||
valueFormatter={dataFormatter}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
case "composed":
|
||||
return (
|
||||
<div className="bg-zinc-900 p-8 rounded-xl text-white">
|
||||
<h3 className="text-lg font-medium">{title}</h3>
|
||||
{showLegend && (
|
||||
<Legend
|
||||
categories={[value]}
|
||||
colors={[color || "blue", color || "blue"]}
|
||||
className="mb-5 justify-end"
|
||||
/>
|
||||
)}
|
||||
<ComposedChart width={500} height={260} data={data}>
|
||||
<CartesianGrid
|
||||
strokeDasharray="3 3"
|
||||
horizontal
|
||||
vertical={false}
|
||||
/>
|
||||
<XAxis
|
||||
dataKey="name"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
interval="preserveStartEnd"
|
||||
tick={{ transform: "translate(0, 6)", fill: "white" }}
|
||||
style={{
|
||||
fontSize: "12px",
|
||||
fontFamily: "Inter; Helvetica",
|
||||
}}
|
||||
padding={{ left: 10, right: 10 }}
|
||||
/>
|
||||
<YAxis
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
type="number"
|
||||
tick={{ transform: "translate(-3, 0)", fill: "white" }}
|
||||
style={{
|
||||
fontSize: "12px",
|
||||
fontFamily: "Inter; Helvetica",
|
||||
}}
|
||||
/>
|
||||
<Tooltip legendColor={getTremorColor(color || "blue")} />
|
||||
<Line
|
||||
type="linear"
|
||||
dataKey={value}
|
||||
stroke={getTremorColor(color || "blue")}
|
||||
dot={false}
|
||||
strokeWidth={2}
|
||||
/>
|
||||
<Bar
|
||||
dataKey="value"
|
||||
name="value"
|
||||
type="linear"
|
||||
fill={getTremorColor(color || "blue")}
|
||||
/>
|
||||
</ComposedChart>
|
||||
</div>
|
||||
);
|
||||
case "scatter":
|
||||
return (
|
||||
<div className="bg-zinc-900 p-8 rounded-xl text-white">
|
||||
<h3 className="text-lg font-medium">{title}</h3>
|
||||
{showLegend && (
|
||||
<div className="flex justify-end">
|
||||
<Legend
|
||||
categories={[value]}
|
||||
colors={[color || "blue", color || "blue"]}
|
||||
className="mb-5"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<ScatterChart width={500} height={260} data={data}>
|
||||
<CartesianGrid
|
||||
strokeDasharray="3 3"
|
||||
horizontal
|
||||
vertical={false}
|
||||
/>
|
||||
<XAxis
|
||||
dataKey="name"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
interval="preserveStartEnd"
|
||||
tick={{ transform: "translate(0, 6)", fill: "white" }}
|
||||
style={{
|
||||
fontSize: "12px",
|
||||
fontFamily: "Inter; Helvetica",
|
||||
}}
|
||||
padding={{ left: 10, right: 10 }}
|
||||
/>
|
||||
<YAxis
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
type="number"
|
||||
tick={{ transform: "translate(-3, 0)", fill: "white" }}
|
||||
style={{
|
||||
fontSize: "12px",
|
||||
fontFamily: "Inter; Helvetica",
|
||||
}}
|
||||
/>
|
||||
<Tooltip legendColor={getTremorColor(color || "blue")} />
|
||||
<Scatter dataKey={value} fill={getTremorColor(color || "blue")} />
|
||||
</ScatterChart>
|
||||
</div>
|
||||
);
|
||||
case "pie":
|
||||
return (
|
||||
<div className="bg-zinc-900 p-8 rounded-xl text-white">
|
||||
<h3 className="text-lg font-medium">{title}</h3>
|
||||
<DonutChart
|
||||
data={data}
|
||||
category={value}
|
||||
index="name"
|
||||
colors={[
|
||||
color || "cyan",
|
||||
"violet",
|
||||
"rose",
|
||||
"amber",
|
||||
"emerald",
|
||||
"teal",
|
||||
"fuchsia",
|
||||
]}
|
||||
// No actual legend for pie chart, but this will toggle the central text
|
||||
showLabel={showLegend}
|
||||
valueFormatter={dataFormatter}
|
||||
customTooltip={customTooltip}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
case "radar":
|
||||
return (
|
||||
<div className="bg-zinc-900 p-8 rounded-xl text-white">
|
||||
<h3 className="text-lg font-medium">{title}</h3>
|
||||
{showLegend && (
|
||||
<div className="flex justify-end">
|
||||
<Legend
|
||||
categories={[value]}
|
||||
colors={[color || "blue", color || "blue"]}
|
||||
className="mb-5"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<RadarChart
|
||||
cx={300}
|
||||
cy={250}
|
||||
outerRadius={150}
|
||||
width={600}
|
||||
height={500}
|
||||
data={data}
|
||||
>
|
||||
<PolarGrid />
|
||||
<PolarAngleAxis dataKey="name" tick={{ fill: "white" }} />
|
||||
<PolarRadiusAxis tick={{ fill: "white" }} />
|
||||
<Tooltip legendColor={getTremorColor(color || "blue")} />
|
||||
<Radar
|
||||
dataKey="value"
|
||||
stroke={getTremorColor(color || "blue")}
|
||||
fill={getTremorColor(color || "blue")}
|
||||
fillOpacity={0.6}
|
||||
/>
|
||||
</RadarChart>
|
||||
</div>
|
||||
);
|
||||
case "radialbar":
|
||||
return (
|
||||
<div className="bg-zinc-900 p-8 rounded-xl text-white">
|
||||
<h3 className="text-lg font-medium">{title}</h3>
|
||||
{showLegend && (
|
||||
<div className="flex justify-end">
|
||||
<Legend
|
||||
categories={[value]}
|
||||
colors={[color || "blue", color || "blue"]}
|
||||
className="mb-5"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<RadialBarChart
|
||||
width={500}
|
||||
height={300}
|
||||
cx={150}
|
||||
cy={150}
|
||||
innerRadius={20}
|
||||
outerRadius={140}
|
||||
barSize={10}
|
||||
data={data}
|
||||
>
|
||||
<RadialBar
|
||||
angleAxisId={15}
|
||||
label={{
|
||||
position: "insideStart",
|
||||
fill: getTremorColor(color || "blue"),
|
||||
}}
|
||||
dataKey="value"
|
||||
/>
|
||||
<Tooltip legendColor={getTremorColor(color || "blue")} />
|
||||
</RadialBarChart>
|
||||
</div>
|
||||
);
|
||||
case "treemap":
|
||||
return (
|
||||
<div className="bg-zinc-900 p-8 rounded-xl text-white">
|
||||
<h3 className="text-lg font-medium">{title}</h3>
|
||||
{showLegend && (
|
||||
<div className="flex justify-end">
|
||||
<Legend
|
||||
categories={[value]}
|
||||
colors={[color || "blue", color || "blue"]}
|
||||
className="mb-5"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<Treemap
|
||||
width={500}
|
||||
height={260}
|
||||
data={data}
|
||||
dataKey="value"
|
||||
stroke="#fff"
|
||||
fill={getTremorColor(color || "blue")}
|
||||
content={<CustomCell colors={Object.values(Colors)} />}
|
||||
>
|
||||
<Tooltip legendColor={getTremorColor(color || "blue")} />
|
||||
</Treemap>
|
||||
</div>
|
||||
);
|
||||
case "funnel":
|
||||
return (
|
||||
<div className="bg-zinc-900 p-8 rounded-xl text-white">
|
||||
<h3 className="text-lg font-medium">{title}</h3>
|
||||
{showLegend && (
|
||||
<div className="flex justify-end">
|
||||
<Legend
|
||||
categories={[value]}
|
||||
colors={[color || "blue", color || "blue"]}
|
||||
className="mb-5"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<FunnelChart width={500} height={300} data={data}>
|
||||
<Tooltip legendColor={getTremorColor(color || "blue")} />
|
||||
<Funnel dataKey="value" color={getTremorColor(color || "blue")} />
|
||||
</FunnelChart>
|
||||
</div>
|
||||
);
|
||||
default:
|
||||
return <p>Unsupported chart type.</p>;
|
||||
}
|
||||
};
|
||||
|
||||
if (!!props.chatId) {
|
||||
return (
|
||||
<div className="flex justify-center items-end w-full">
|
||||
<div className="py-2 px-4 w-full flex gap-x-5 md:max-w-[800px] flex-col">
|
||||
<div className="flex gap-x-5">
|
||||
<WorkspaceProfileImage workspace={workspace} />
|
||||
<div className="relative">
|
||||
<DownloadGraph onClick={handleDownload} />
|
||||
<div ref={ref}>{renderChart()}</div>
|
||||
<span
|
||||
className={`flex flex-col gap-y-1 mt-2`}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: renderMarkdown(content.caption),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex justify-center items-end w-full">
|
||||
<div className="py-2 px-4 w-full flex gap-x-5 md:max-w-[800px] flex-col">
|
||||
<div className="relative">
|
||||
<DownloadGraph onClick={handleDownload} />
|
||||
<div ref={ref}>{renderChart()}</div>
|
||||
</div>
|
||||
<div className="flex gap-x-5">
|
||||
<span
|
||||
className={`flex flex-col gap-y-1 mt-2`}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: renderMarkdown(content.caption),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const customTooltip = (props) => {
|
||||
const { payload, active } = props;
|
||||
if (!active || !payload) return null;
|
||||
const categoryPayload = payload?.[0];
|
||||
if (!categoryPayload) return null;
|
||||
return (
|
||||
<div className="w-56 bg-zinc-400 rounded-lg border p-2 text-white">
|
||||
<div className="flex flex-1 space-x-2.5">
|
||||
<div
|
||||
className={`flex w-1.5 flex-col bg-${categoryPayload?.color}-500 rounded`}
|
||||
/>
|
||||
<div className="w-full">
|
||||
<div className="flex items-center justify-between space-x-8">
|
||||
<p className="whitespace-nowrap text-right text-tremor-content">
|
||||
{categoryPayload.name}
|
||||
</p>
|
||||
<p className="whitespace-nowrap text-right font-medium text-tremor-content-emphasis">
|
||||
{categoryPayload.value}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
function DownloadGraph({ onClick }) {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const handleClick = async () => {
|
||||
setLoading(true);
|
||||
await onClick?.();
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="absolute top-3 right-3 z-50 cursor-pointer">
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="p-1 rounded-full border-none">
|
||||
{loading ? (
|
||||
<CircleNotch
|
||||
className="text-white/50 w-5 h-5 animate-spin"
|
||||
aria-label="Downloading image..."
|
||||
/>
|
||||
) : (
|
||||
<DownloadSimple
|
||||
weight="bold"
|
||||
className="text-white/50 w-5 h-5 hover:text-white"
|
||||
onClick={handleClick}
|
||||
aria-label="Download graph image"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(Chartable);
|
@ -71,7 +71,7 @@ const PromptReply = ({
|
||||
);
|
||||
};
|
||||
|
||||
function WorkspaceProfileImage({ workspace }) {
|
||||
export function WorkspaceProfileImage({ workspace }) {
|
||||
if (!!workspace.pfpUrl) {
|
||||
return (
|
||||
<div className="relative w-[35px] h-[35px] rounded-full flex-shrink-0 overflow-hidden">
|
||||
|
@ -6,6 +6,7 @@ import ManageWorkspace from "../../../Modals/MangeWorkspace";
|
||||
import { ArrowDown } from "@phosphor-icons/react";
|
||||
import debounce from "lodash.debounce";
|
||||
import useUser from "@/hooks/useUser";
|
||||
import Chartable from "./Chartable";
|
||||
|
||||
export default function ChatHistory({ history = [], workspace, sendCommand }) {
|
||||
const { user } = useUser();
|
||||
@ -133,6 +134,12 @@ export default function ChatHistory({ history = [], workspace, sendCommand }) {
|
||||
return <StatusResponse key={props.uuid} props={props} />;
|
||||
}
|
||||
|
||||
if (props.type === "rechartVisualize" && !!props.content) {
|
||||
return (
|
||||
<Chartable key={props.uuid} workspace={workspace} props={props} />
|
||||
);
|
||||
}
|
||||
|
||||
if (isLastBotReply && props.animate) {
|
||||
return (
|
||||
<PromptReply
|
||||
|
@ -89,6 +89,7 @@ export function AvailableAgents({
|
||||
<AbilityTag text="save-file-to-browser" />
|
||||
<AbilityTag text="list-documents" />
|
||||
<AbilityTag text="summarize-document" />
|
||||
<AbilityTag text="chart-generation" />
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
|
@ -679,3 +679,16 @@ does not extend the close button beyond the viewport. */
|
||||
.white-scrollbar::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #cccccc;
|
||||
}
|
||||
|
||||
/* Recharts rendering styles */
|
||||
.recharts-text > * {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
.recharts-legend-wrapper {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.text-tremor-content {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ function AvailableAgentSkills({ skills, settings, toggleAgentSkill }) {
|
||||
disabled={true}
|
||||
/>
|
||||
<GenericSkill
|
||||
title="View and summarize documents"
|
||||
title="View & summarize documents"
|
||||
description="Allow the agent to list and summarize the content of workspace files currently embedded."
|
||||
settings={settings}
|
||||
enabled={true}
|
||||
@ -183,6 +183,14 @@ function AvailableAgentSkills({ skills, settings, toggleAgentSkill }) {
|
||||
enabled={true}
|
||||
disabled={true}
|
||||
/>
|
||||
<GenericSkill
|
||||
title="Generate charts"
|
||||
description="Enable the default agent to generate various types of charts from data provided or given in chat."
|
||||
skill="create-chart"
|
||||
settings={settings}
|
||||
toggleSkill={toggleAgentSkill}
|
||||
enabled={skills.includes("create-chart")}
|
||||
/>
|
||||
<GenericSkill
|
||||
title="Generate & save files to browser"
|
||||
description="Enable the default agent to generate and write to files that save and can be downloaded in your browser."
|
||||
|
@ -11,6 +11,7 @@ const handledEvents = [
|
||||
"fileDownload",
|
||||
"awaitingFeedback",
|
||||
"wssFailure",
|
||||
"rechartVisualize",
|
||||
];
|
||||
|
||||
export function websocketURI() {
|
||||
@ -50,6 +51,25 @@ export default function handleSocketResponse(event, setChatHistory) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.type === "rechartVisualize") {
|
||||
return setChatHistory((prev) => {
|
||||
return [
|
||||
...prev.filter((msg) => !!msg.content),
|
||||
{
|
||||
type: "rechartVisualize",
|
||||
uuid: v4(),
|
||||
content: data.content,
|
||||
role: "assistant",
|
||||
sources: [],
|
||||
closed: true,
|
||||
error: null,
|
||||
animate: false,
|
||||
pending: false,
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
if (data.type === "wssFailure") {
|
||||
return setChatHistory((prev) => {
|
||||
return [
|
||||
|
@ -1,5 +1,6 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
darkMode: 'false',
|
||||
content: {
|
||||
relative: true,
|
||||
files: [
|
||||
@ -9,7 +10,8 @@ export default {
|
||||
"./src/pages/**/*.{js,jsx}",
|
||||
"./src/utils/**/*.js",
|
||||
"./src/*.jsx",
|
||||
"./index.html"
|
||||
"./index.html",
|
||||
'./node_modules/@tremor/**/*.{js,ts,jsx,tsx}'
|
||||
]
|
||||
},
|
||||
theme: {
|
||||
@ -86,5 +88,35 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
// Required for rechart styles to show since they can be rendered dynamically and will be tree-shaken if not safe-listed.
|
||||
safelist: [
|
||||
{
|
||||
pattern:
|
||||
/^(bg-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,
|
||||
variants: ['hover', 'ui-selected'],
|
||||
},
|
||||
{
|
||||
pattern:
|
||||
/^(text-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,
|
||||
variants: ['hover', 'ui-selected'],
|
||||
},
|
||||
{
|
||||
pattern:
|
||||
/^(border-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,
|
||||
variants: ['hover', 'ui-selected'],
|
||||
},
|
||||
{
|
||||
pattern:
|
||||
/^(ring-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,
|
||||
},
|
||||
{
|
||||
pattern:
|
||||
/^(stroke-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,
|
||||
},
|
||||
{
|
||||
pattern:
|
||||
/^(fill-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,
|
||||
},
|
||||
],
|
||||
plugins: []
|
||||
}
|
||||
|
@ -184,6 +184,13 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.22.5"
|
||||
|
||||
"@babel/runtime@^7.21.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7":
|
||||
version "7.24.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.4.tgz#de795accd698007a66ba44add6cc86542aff1edd"
|
||||
integrity sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.14.0"
|
||||
|
||||
"@babel/template@^7.22.15":
|
||||
version "7.22.15"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38"
|
||||
@ -365,6 +372,13 @@
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.53.0.tgz#bea56f2ed2b5baea164348ff4d5a879f6f81f20d"
|
||||
integrity sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==
|
||||
|
||||
"@floating-ui/core@^1.0.0":
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.0.tgz#fa41b87812a16bf123122bf945946bae3fdf7fc1"
|
||||
integrity sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==
|
||||
dependencies:
|
||||
"@floating-ui/utils" "^0.2.1"
|
||||
|
||||
"@floating-ui/core@^1.5.3":
|
||||
version "1.5.3"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.3.tgz#b6aa0827708d70971c8679a16cf680a515b8a52a"
|
||||
@ -380,11 +394,48 @@
|
||||
"@floating-ui/core" "^1.5.3"
|
||||
"@floating-ui/utils" "^0.2.0"
|
||||
|
||||
"@floating-ui/utils@^0.2.0":
|
||||
"@floating-ui/dom@^1.2.1":
|
||||
version "1.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.3.tgz#954e46c1dd3ad48e49db9ada7218b0985cee75ef"
|
||||
integrity sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==
|
||||
dependencies:
|
||||
"@floating-ui/core" "^1.0.0"
|
||||
"@floating-ui/utils" "^0.2.0"
|
||||
|
||||
"@floating-ui/react-dom@^1.3.0":
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-1.3.0.tgz#4d35d416eb19811c2b0e9271100a6aa18c1579b3"
|
||||
integrity sha512-htwHm67Ji5E/pROEAr7f8IKFShuiCKHwUC/UY4vC3I5jiSvGFAYnSYiZO5MlGmads+QqvUkR9ANHEguGrDv72g==
|
||||
dependencies:
|
||||
"@floating-ui/dom" "^1.2.1"
|
||||
|
||||
"@floating-ui/react@^0.19.2":
|
||||
version "0.19.2"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/react/-/react-0.19.2.tgz#c6e4d2097ed0dca665a7c042ddf9cdecc95e9412"
|
||||
integrity sha512-JyNk4A0Ezirq8FlXECvRtQOX/iBe5Ize0W/pLkrZjfHW9GUV7Xnq6zm6fyZuQzaHHqEnVizmvlA96e1/CkZv+w==
|
||||
dependencies:
|
||||
"@floating-ui/react-dom" "^1.3.0"
|
||||
aria-hidden "^1.1.3"
|
||||
tabbable "^6.0.1"
|
||||
|
||||
"@floating-ui/utils@^0.2.0", "@floating-ui/utils@^0.2.1":
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2"
|
||||
integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==
|
||||
|
||||
"@headlessui/react@^1.7.18":
|
||||
version "1.7.18"
|
||||
resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.7.18.tgz#30af4634d2215b2ca1aa29d07f33d02bea82d9d7"
|
||||
integrity sha512-4i5DOrzwN4qSgNsL4Si61VMkUcWbcSKueUV7sFhpHzQcSShdlHENE5+QBntMSRvHt8NyoFO2AGG8si9lq+w4zQ==
|
||||
dependencies:
|
||||
"@tanstack/react-virtual" "^3.0.0-beta.60"
|
||||
client-only "^0.0.1"
|
||||
|
||||
"@headlessui/tailwindcss@^0.2.0":
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@headlessui/tailwindcss/-/tailwindcss-0.2.0.tgz#2c55c98fd8eee4b4f21ec6eb35a014b840059eec"
|
||||
integrity sha512-fpL830Fln1SykOCboExsWr3JIVeQKieLJ3XytLe/tt1A0XzqUthOftDmjcCYLW62w7mQI7wXcoPXr3tZ9QfGxw==
|
||||
|
||||
"@humanwhocodes/config-array@^0.11.13":
|
||||
version "0.11.13"
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297"
|
||||
@ -492,6 +543,32 @@
|
||||
resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.14.1.tgz#6d2dd03d52e604279c38911afc1079d58c50a755"
|
||||
integrity sha512-Qg4DMQsfPNAs88rb2xkdk03N3bjK4jgX5fR24eHCTR9q6PrhZQZ4UJBPzCHJkIpTRN1UKxx2DzjZmnC+7Lj0Ow==
|
||||
|
||||
"@tanstack/react-virtual@^3.0.0-beta.60":
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.2.1.tgz#58ac9af23ff08b5f05a6dfe6a59deac2f9451508"
|
||||
integrity sha512-i9Nt0ssIh2bSjomJZlr6Iq5usT/9+ewo2/fKHRNk6kjVKS8jrhXbnO8NEawarCuBx/efv0xpoUUKKGxa0cQb4Q==
|
||||
dependencies:
|
||||
"@tanstack/virtual-core" "3.2.1"
|
||||
|
||||
"@tanstack/virtual-core@3.2.1":
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.2.1.tgz#b3e4214b8f462054501d80e8777068faa139bd06"
|
||||
integrity sha512-nO0d4vRzsmpBQCJYyClNHPPoUMI4nXNfrm6IcCRL33ncWMoNVpURh9YebEHPw8KrtsP2VSJIHE4gf4XFGk1OGg==
|
||||
|
||||
"@tremor/react@^3.15.1":
|
||||
version "3.15.1"
|
||||
resolved "https://registry.yarnpkg.com/@tremor/react/-/react-3.15.1.tgz#a9c10887bd067ffe0e18ca763e425db057f3722f"
|
||||
integrity sha512-vCUqgYo993VePn6yOs4102ibY2XYcDDp7I1ZV/+i5hdfp+XgsHyQvYeixQcETBMpcajwM8E8NOOO7k9ANLkrrw==
|
||||
dependencies:
|
||||
"@floating-ui/react" "^0.19.2"
|
||||
"@headlessui/react" "^1.7.18"
|
||||
"@headlessui/tailwindcss" "^0.2.0"
|
||||
date-fns "^2.30.0"
|
||||
react-day-picker "^8.9.1"
|
||||
react-transition-state "^2.1.1"
|
||||
recharts "^2.10.3"
|
||||
tailwind-merge "^1.14.0"
|
||||
|
||||
"@types/babel__core@^7.20.3":
|
||||
version "7.20.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.3.tgz#d5625a50b6f18244425a1359a858c73d70340778"
|
||||
@ -525,6 +602,57 @@
|
||||
dependencies:
|
||||
"@babel/types" "^7.20.7"
|
||||
|
||||
"@types/d3-array@^3.0.3":
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.2.1.tgz#1f6658e3d2006c4fceac53fde464166859f8b8c5"
|
||||
integrity sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==
|
||||
|
||||
"@types/d3-color@*":
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.3.tgz#368c961a18de721da8200e80bf3943fb53136af2"
|
||||
integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==
|
||||
|
||||
"@types/d3-ease@^3.0.0":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.2.tgz#e28db1bfbfa617076f7770dd1d9a48eaa3b6c51b"
|
||||
integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==
|
||||
|
||||
"@types/d3-interpolate@^3.0.1":
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz#412b90e84870285f2ff8a846c6eb60344f12a41c"
|
||||
integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==
|
||||
dependencies:
|
||||
"@types/d3-color" "*"
|
||||
|
||||
"@types/d3-path@*":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.1.0.tgz#2b907adce762a78e98828f0b438eaca339ae410a"
|
||||
integrity sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==
|
||||
|
||||
"@types/d3-scale@^4.0.2":
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.8.tgz#d409b5f9dcf63074464bf8ddfb8ee5a1f95945bb"
|
||||
integrity sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==
|
||||
dependencies:
|
||||
"@types/d3-time" "*"
|
||||
|
||||
"@types/d3-shape@^3.1.0":
|
||||
version "3.1.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.6.tgz#65d40d5a548f0a023821773e39012805e6e31a72"
|
||||
integrity sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==
|
||||
dependencies:
|
||||
"@types/d3-path" "*"
|
||||
|
||||
"@types/d3-time@*", "@types/d3-time@^3.0.0":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.3.tgz#3c186bbd9d12b9d84253b6be6487ca56b54f88be"
|
||||
integrity sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==
|
||||
|
||||
"@types/d3-timer@^3.0.0":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.2.tgz#70bbda77dc23aa727413e22e214afa3f0e852f70"
|
||||
integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==
|
||||
|
||||
"@types/history@^4.7.11":
|
||||
version "4.7.11"
|
||||
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64"
|
||||
@ -651,6 +779,13 @@ argparse@^2.0.1:
|
||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
|
||||
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
|
||||
|
||||
aria-hidden@^1.1.3:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.4.tgz#b78e383fdbc04d05762c78b4a25a501e736c4522"
|
||||
integrity sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==
|
||||
dependencies:
|
||||
tslib "^2.0.0"
|
||||
|
||||
array-buffer-byte-length@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead"
|
||||
@ -748,6 +883,11 @@ balanced-match@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
base64-arraybuffer@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#1c37589a7c4b0746e34bd1feb951da2df01c1bdc"
|
||||
integrity sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==
|
||||
|
||||
base64-js@^1.3.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
||||
@ -871,6 +1011,11 @@ classnames@^2.3.0:
|
||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b"
|
||||
integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==
|
||||
|
||||
client-only@^0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1"
|
||||
integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==
|
||||
|
||||
cliui@^8.0.1:
|
||||
version "8.0.1"
|
||||
resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa"
|
||||
@ -890,6 +1035,11 @@ clsx@^1.1.1:
|
||||
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
|
||||
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
|
||||
|
||||
clsx@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.0.tgz#e851283bcb5c80ee7608db18487433f7b23f77cb"
|
||||
integrity sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==
|
||||
|
||||
color-convert@^1.3.0, color-convert@^1.9.0:
|
||||
version "1.9.3"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
||||
@ -954,6 +1104,13 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3:
|
||||
shebang-command "^2.0.0"
|
||||
which "^2.0.1"
|
||||
|
||||
css-line-break@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/css-line-break/-/css-line-break-2.1.0.tgz#bfef660dfa6f5397ea54116bb3cb4873edbc4fa0"
|
||||
integrity sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==
|
||||
dependencies:
|
||||
utrie "^1.0.2"
|
||||
|
||||
cssesc@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
|
||||
@ -964,6 +1121,84 @@ csstype@^3.0.2:
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b"
|
||||
integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
|
||||
|
||||
"d3-array@2 - 3", "d3-array@2.10.0 - 3", d3-array@^3.1.6:
|
||||
version "3.2.4"
|
||||
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.4.tgz#15fec33b237f97ac5d7c986dc77da273a8ed0bb5"
|
||||
integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==
|
||||
dependencies:
|
||||
internmap "1 - 2"
|
||||
|
||||
"d3-color@1 - 3":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2"
|
||||
integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==
|
||||
|
||||
d3-ease@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4"
|
||||
integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==
|
||||
|
||||
"d3-format@1 - 3":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641"
|
||||
integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==
|
||||
|
||||
"d3-interpolate@1.2.0 - 3", d3-interpolate@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d"
|
||||
integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==
|
||||
dependencies:
|
||||
d3-color "1 - 3"
|
||||
|
||||
d3-path@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.1.0.tgz#22df939032fb5a71ae8b1800d61ddb7851c42526"
|
||||
integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==
|
||||
|
||||
d3-scale@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396"
|
||||
integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==
|
||||
dependencies:
|
||||
d3-array "2.10.0 - 3"
|
||||
d3-format "1 - 3"
|
||||
d3-interpolate "1.2.0 - 3"
|
||||
d3-time "2.1.1 - 3"
|
||||
d3-time-format "2 - 4"
|
||||
|
||||
d3-shape@^3.1.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.2.0.tgz#a1a839cbd9ba45f28674c69d7f855bcf91dfc6a5"
|
||||
integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==
|
||||
dependencies:
|
||||
d3-path "^3.1.0"
|
||||
|
||||
"d3-time-format@2 - 4":
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a"
|
||||
integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==
|
||||
dependencies:
|
||||
d3-time "1 - 3"
|
||||
|
||||
"d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7"
|
||||
integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==
|
||||
dependencies:
|
||||
d3-array "2 - 3"
|
||||
|
||||
d3-timer@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0"
|
||||
integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==
|
||||
|
||||
date-fns@^2.30.0:
|
||||
version "2.30.0"
|
||||
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0"
|
||||
integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.21.0"
|
||||
|
||||
debug@^4.1.0, debug@^4.1.1, debug@^4.3.2:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
|
||||
@ -971,6 +1206,11 @@ debug@^4.1.0, debug@^4.1.1, debug@^4.3.2:
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
decimal.js-light@^2.4.1:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934"
|
||||
integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==
|
||||
|
||||
deep-is@^0.1.3:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
|
||||
@ -1046,6 +1286,14 @@ doctrine@^3.0.0:
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
|
||||
dom-helpers@^5.0.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
|
||||
integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.8.7"
|
||||
csstype "^3.0.2"
|
||||
|
||||
dompurify@^3.0.8:
|
||||
version "3.0.8"
|
||||
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.8.tgz#e0021ab1b09184bc8af7e35c7dd9063f43a8a437"
|
||||
@ -1342,6 +1590,11 @@ esutils@^2.0.2:
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
|
||||
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
||||
|
||||
eventemitter3@^4.0.1:
|
||||
version "4.0.7"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
||||
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
|
||||
|
||||
execa@^5.0.0:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
|
||||
@ -1382,6 +1635,11 @@ fast-diff@^1.1.2:
|
||||
resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0"
|
||||
integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==
|
||||
|
||||
fast-equals@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-5.0.1.tgz#a4eefe3c5d1c0d021aeed0bc10ba5e0c12ee405d"
|
||||
integrity sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==
|
||||
|
||||
fast-glob@^3.3.0:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4"
|
||||
@ -1698,6 +1956,14 @@ highlight.js@^11.9.0:
|
||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.9.0.tgz#04ab9ee43b52a41a047432c8103e2158a1b8b5b0"
|
||||
integrity sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==
|
||||
|
||||
html2canvas@^1.2.0:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/html2canvas/-/html2canvas-1.4.1.tgz#7cef1888311b5011d507794a066041b14669a543"
|
||||
integrity sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==
|
||||
dependencies:
|
||||
css-line-break "^2.1.0"
|
||||
text-segmentation "^1.0.3"
|
||||
|
||||
human-signals@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
|
||||
@ -1753,6 +2019,11 @@ internal-slot@^1.0.5:
|
||||
hasown "^2.0.0"
|
||||
side-channel "^1.0.4"
|
||||
|
||||
"internmap@1 - 2":
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009"
|
||||
integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==
|
||||
|
||||
is-array-buffer@^3.0.1, is-array-buffer@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe"
|
||||
@ -2483,7 +2754,7 @@ prettier@^3.0.3:
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.3.tgz#432a51f7ba422d1469096c0fdc28e235db8f9643"
|
||||
integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==
|
||||
|
||||
prop-types@^15.8.1:
|
||||
prop-types@^15.6.2, prop-types@^15.8.1:
|
||||
version "15.8.1"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||
@ -2502,6 +2773,11 @@ queue-microtask@^1.2.2:
|
||||
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
||||
|
||||
react-day-picker@^8.9.1:
|
||||
version "8.10.0"
|
||||
resolved "https://registry.yarnpkg.com/react-day-picker/-/react-day-picker-8.10.0.tgz#729c5b9564967a924213978fb9c0751884a60595"
|
||||
integrity sha512-mz+qeyrOM7++1NCb1ARXmkjMkzWVh2GL9YiPbRjKe0zHccvekk4HE+0MPOZOrosn8r8zTHIIeOUXTmXRqmkRmg==
|
||||
|
||||
react-device-detect@^2.2.2:
|
||||
version "2.2.3"
|
||||
resolved "https://registry.yarnpkg.com/react-device-detect/-/react-device-detect-2.2.3.tgz#97a7ae767cdd004e7c3578260f48cf70c036e7ca"
|
||||
@ -2526,7 +2802,7 @@ react-dropzone@^14.2.3:
|
||||
file-selector "^0.6.0"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
react-is@^16.13.1:
|
||||
react-is@^16.10.2, react-is@^16.13.1:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||
@ -2556,6 +2832,15 @@ react-router@6.21.1:
|
||||
dependencies:
|
||||
"@remix-run/router" "1.14.1"
|
||||
|
||||
react-smooth@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-4.0.1.tgz#6200d8699bfe051ae40ba187988323b1449eab1a"
|
||||
integrity sha512-OE4hm7XqR0jNOq3Qmk9mFLyd6p2+j6bvbPJ7qlB7+oo0eNcL2l7WQzG6MBnT3EXY6xzkLMUBec3AfewJdA0J8w==
|
||||
dependencies:
|
||||
fast-equals "^5.0.1"
|
||||
prop-types "^15.8.1"
|
||||
react-transition-group "^4.4.5"
|
||||
|
||||
react-tag-input-component@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-tag-input-component/-/react-tag-input-component-2.0.2.tgz#f62f013c6a535141dd1c6c3a88858223170150f1"
|
||||
@ -2576,6 +2861,21 @@ react-tooltip@^5.25.2:
|
||||
"@floating-ui/dom" "^1.0.0"
|
||||
classnames "^2.3.0"
|
||||
|
||||
react-transition-group@^4.4.5:
|
||||
version "4.4.5"
|
||||
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1"
|
||||
integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.5.5"
|
||||
dom-helpers "^5.0.1"
|
||||
loose-envify "^1.4.0"
|
||||
prop-types "^15.6.2"
|
||||
|
||||
react-transition-state@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/react-transition-state/-/react-transition-state-2.1.1.tgz#1601a6177926b647041b7d598bf124321ab8d25b"
|
||||
integrity sha512-kQx5g1FVu9knoz1T1WkapjUgFz08qQ/g1OmuWGi3/AoEFfS0kStxrPlZx81urjCXdz2d+1DqLpU6TyLW/Ro04Q==
|
||||
|
||||
react@^18.2.0:
|
||||
version "18.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
|
||||
@ -2597,6 +2897,34 @@ readdirp@~3.6.0:
|
||||
dependencies:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
recharts-scale@^0.4.4:
|
||||
version "0.4.5"
|
||||
resolved "https://registry.yarnpkg.com/recharts-scale/-/recharts-scale-0.4.5.tgz#0969271f14e732e642fcc5bd4ab270d6e87dd1d9"
|
||||
integrity sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==
|
||||
dependencies:
|
||||
decimal.js-light "^2.4.1"
|
||||
|
||||
recharts-to-png@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/recharts-to-png/-/recharts-to-png-2.3.1.tgz#94d4edb8461ba4b16318edea77a34c421c16d7c1"
|
||||
integrity sha512-a+OaAi03oFJMa+Burf3vyH060iFTrb35W8bBYUatNjZVrrMKUcFM3VOI1ym078WIH7XfgYQb17K9p2spVA2FzQ==
|
||||
dependencies:
|
||||
html2canvas "^1.2.0"
|
||||
|
||||
recharts@^2.10.3, recharts@^2.12.5:
|
||||
version "2.12.5"
|
||||
resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.12.5.tgz#b335eb66173317dccb3e126fce1d7ac5b3cee1e9"
|
||||
integrity sha512-Cy+BkqrFIYTHJCyKHJEPvbHE2kVQEP6PKbOHJ8ztRGTAhvHuUnCwDaKVb13OwRFZ0QNUk1QvGTDdgWSMbuMtKw==
|
||||
dependencies:
|
||||
clsx "^2.0.0"
|
||||
eventemitter3 "^4.0.1"
|
||||
lodash "^4.17.21"
|
||||
react-is "^16.10.2"
|
||||
react-smooth "^4.0.0"
|
||||
recharts-scale "^0.4.4"
|
||||
tiny-invariant "^1.3.1"
|
||||
victory-vendor "^36.6.8"
|
||||
|
||||
reflect.getprototypeof@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz#aaccbf41aca3821b87bb71d9dcbc7ad0ba50a3f3"
|
||||
@ -2609,6 +2937,11 @@ reflect.getprototypeof@^1.0.4:
|
||||
globalthis "^1.0.3"
|
||||
which-builtin-type "^1.1.3"
|
||||
|
||||
regenerator-runtime@^0.14.0:
|
||||
version "0.14.1"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f"
|
||||
integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
|
||||
|
||||
regexp.prototype.flags@^1.5.0, regexp.prototype.flags@^1.5.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e"
|
||||
@ -2893,6 +3226,16 @@ synckit@^0.8.5:
|
||||
"@pkgr/utils" "^2.3.1"
|
||||
tslib "^2.5.0"
|
||||
|
||||
tabbable@^6.0.1:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97"
|
||||
integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==
|
||||
|
||||
tailwind-merge@^1.14.0:
|
||||
version "1.14.0"
|
||||
resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-1.14.0.tgz#e677f55d864edc6794562c63f5001f45093cdb8b"
|
||||
integrity sha512-3mFKyCo/MBcgyOTlrY8T7odzZFx+w+qKSMAmdFzRvqBfLlSigU6TZnlFHK0lkMwj9Bj8OYU+9yW9lmGuS0QEnQ==
|
||||
|
||||
tailwindcss@^3.3.1:
|
||||
version "3.3.5"
|
||||
resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.3.5.tgz#22a59e2fbe0ecb6660809d9cc5f3976b077be3b8"
|
||||
@ -3031,6 +3374,13 @@ text-path-case@^1.0.2:
|
||||
dependencies:
|
||||
text-dot-case "^1.0.2"
|
||||
|
||||
text-segmentation@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/text-segmentation/-/text-segmentation-1.0.3.tgz#52a388159efffe746b24a63ba311b6ac9f2d7943"
|
||||
integrity sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==
|
||||
dependencies:
|
||||
utrie "^1.0.2"
|
||||
|
||||
text-sentence-case@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/text-sentence-case/-/text-sentence-case-1.0.2.tgz#e692a9aea3c8dcb1fb12242838e0ca3e9a22a90f"
|
||||
@ -3085,6 +3435,11 @@ thenify-all@^1.0.0:
|
||||
dependencies:
|
||||
any-promise "^1.0.0"
|
||||
|
||||
tiny-invariant@^1.3.1:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127"
|
||||
integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==
|
||||
|
||||
titleize@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53"
|
||||
@ -3112,7 +3467,7 @@ ts-interface-checker@^0.1.9:
|
||||
resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699"
|
||||
integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==
|
||||
|
||||
tslib@^2.4.0, tslib@^2.5.0, tslib@^2.6.0:
|
||||
tslib@^2.0.0, tslib@^2.4.0, tslib@^2.5.0, tslib@^2.6.0:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
|
||||
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
||||
@ -3213,11 +3568,38 @@ util-deprecate@^1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
|
||||
|
||||
utrie@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/utrie/-/utrie-1.0.2.tgz#d42fe44de9bc0119c25de7f564a6ed1b2c87a645"
|
||||
integrity sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==
|
||||
dependencies:
|
||||
base64-arraybuffer "^1.0.2"
|
||||
|
||||
uuid@^9.0.0:
|
||||
version "9.0.1"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30"
|
||||
integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==
|
||||
|
||||
victory-vendor@^36.6.8:
|
||||
version "36.9.2"
|
||||
resolved "https://registry.yarnpkg.com/victory-vendor/-/victory-vendor-36.9.2.tgz#668b02a448fa4ea0f788dbf4228b7e64669ff801"
|
||||
integrity sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==
|
||||
dependencies:
|
||||
"@types/d3-array" "^3.0.3"
|
||||
"@types/d3-ease" "^3.0.0"
|
||||
"@types/d3-interpolate" "^3.0.1"
|
||||
"@types/d3-scale" "^4.0.2"
|
||||
"@types/d3-shape" "^3.1.0"
|
||||
"@types/d3-time" "^3.0.0"
|
||||
"@types/d3-timer" "^3.0.0"
|
||||
d3-array "^3.1.6"
|
||||
d3-ease "^3.0.1"
|
||||
d3-interpolate "^3.0.1"
|
||||
d3-scale "^4.0.2"
|
||||
d3-shape "^3.1.0"
|
||||
d3-time "^3.0.0"
|
||||
d3-timer "^3.0.1"
|
||||
|
||||
vite@^4.3.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.0.tgz#ec406295b4167ac3bc23e26f9c8ff559287cff26"
|
||||
|
@ -21,6 +21,19 @@ const chatHistory = {
|
||||
// We need a full conversation reply with prev being from
|
||||
// the USER and the last being from anyone other than the user.
|
||||
if (prev.from !== "USER" || last.from === "USER") return;
|
||||
|
||||
// If we have a post-reply flow we should save the chat using this special flow
|
||||
// so that post save cleanup and other unique properties can be run as opposed to regular chat.
|
||||
if (aibitat.hasOwnProperty("_replySpecialAttributes")) {
|
||||
await this._storeSpecial(aibitat, {
|
||||
prompt: prev.content,
|
||||
response: last.content,
|
||||
options: aibitat._replySpecialAttributes,
|
||||
});
|
||||
delete aibitat._replySpecialAttributes;
|
||||
return;
|
||||
}
|
||||
|
||||
await this._store(aibitat, {
|
||||
prompt: prev.content,
|
||||
response: last.content,
|
||||
@ -42,6 +55,28 @@ const chatHistory = {
|
||||
threadId: invocation?.thread_id || null,
|
||||
});
|
||||
},
|
||||
_storeSpecial: async function (
|
||||
aibitat,
|
||||
{ prompt, response, options = {} } = {}
|
||||
) {
|
||||
const invocation = aibitat.handlerProps.invocation;
|
||||
await WorkspaceChats.new({
|
||||
workspaceId: Number(invocation.workspace_id),
|
||||
prompt,
|
||||
response: {
|
||||
sources: options?.sources ?? [],
|
||||
// when we have a _storeSpecial called the options param can include a storedResponse() function
|
||||
// that will override the text property to store extra information in, depending on the special type of chat.
|
||||
text: options.hasOwnProperty("storedResponse")
|
||||
? options.storedResponse(response)
|
||||
: response,
|
||||
type: options?.saveAsType ?? "chat",
|
||||
},
|
||||
user: { id: invocation?.user_id || null },
|
||||
threadId: invocation?.thread_id || null,
|
||||
});
|
||||
options?.postSave();
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
@ -5,6 +5,7 @@ const { docSummarizer } = require("./summarize.js");
|
||||
const { saveFileInBrowser } = require("./save-file-browser.js");
|
||||
const { chatHistory } = require("./chat-history.js");
|
||||
const { memory } = require("./memory.js");
|
||||
const { rechart } = require("./rechart.js");
|
||||
|
||||
module.exports = {
|
||||
webScraping,
|
||||
@ -14,6 +15,7 @@ module.exports = {
|
||||
saveFileInBrowser,
|
||||
chatHistory,
|
||||
memory,
|
||||
rechart,
|
||||
|
||||
// Plugin name aliases so they can be pulled by slug as well.
|
||||
[webScraping.name]: webScraping,
|
||||
@ -23,4 +25,5 @@ module.exports = {
|
||||
[saveFileInBrowser.name]: saveFileInBrowser,
|
||||
[chatHistory.name]: chatHistory,
|
||||
[memory.name]: memory,
|
||||
[rechart.name]: rechart,
|
||||
};
|
||||
|
109
server/utils/agents/aibitat/plugins/rechart.js
Normal file
109
server/utils/agents/aibitat/plugins/rechart.js
Normal file
@ -0,0 +1,109 @@
|
||||
const { safeJsonParse } = require("../../../http");
|
||||
const { Deduplicator } = require("../utils/dedupe");
|
||||
|
||||
const rechart = {
|
||||
name: "create-chart",
|
||||
startupConfig: {
|
||||
params: {},
|
||||
},
|
||||
plugin: function () {
|
||||
return {
|
||||
name: this.name,
|
||||
setup(aibitat) {
|
||||
// Scrape a website and summarize the content based on objective if the content is too large.',
|
||||
aibitat.function({
|
||||
super: aibitat,
|
||||
name: this.name,
|
||||
tracker: new Deduplicator(),
|
||||
description:
|
||||
"Generates the JSON data required to generate a RechartJS chart to the user based on their prompt and available data.",
|
||||
parameters: {
|
||||
$schema: "http://json-schema.org/draft-07/schema#",
|
||||
type: "object",
|
||||
properties: {
|
||||
type: {
|
||||
type: "string",
|
||||
enum: [
|
||||
"area",
|
||||
"bar",
|
||||
"line",
|
||||
"composed",
|
||||
"scatter",
|
||||
"pie",
|
||||
"radar",
|
||||
"radialBar",
|
||||
"treemap",
|
||||
"funnel",
|
||||
],
|
||||
description: "The type of chart to be generated.",
|
||||
},
|
||||
title: {
|
||||
type: "string",
|
||||
description:
|
||||
"Title of the chart. There MUST always be a title. Do not leave it blank.",
|
||||
},
|
||||
dataset: {
|
||||
type: "string",
|
||||
description: `Valid JSON in which each element is an object for Recharts API for the 'type' of chart defined WITHOUT new line characters. Strictly using this FORMAT and naming:
|
||||
{ "name": "a", "value": 12 }].
|
||||
Make sure field "name" always stays named "name". Instead of naming value field value in JSON, name it based on user metric and make it the same across every item.
|
||||
Make sure the format use double quotes and property names are string literals. Provide JSON data only.`,
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
required: ["type", "title", "dataset"],
|
||||
handler: async function ({ type, dataset, title }) {
|
||||
try {
|
||||
if (!this.tracker.isUnique(this.name)) {
|
||||
this.super.handlerProps.log(
|
||||
`${this.name} has been run for this chat response already. It can only be called once per chat.`
|
||||
);
|
||||
return "The chart was generated and returned to the user. This function completed successfully. Do not call this function again.";
|
||||
}
|
||||
|
||||
const data = safeJsonParse(dataset, null);
|
||||
if (data === null) {
|
||||
this.super.introspect(
|
||||
`${this.caller}: ${this.name} provided invalid JSON data - so we cant make a ${type} chart.`
|
||||
);
|
||||
return "Invalid JSON provided. Please only provide valid RechartJS JSON to generate a chart.";
|
||||
}
|
||||
|
||||
this.super.introspect(`${this.caller}: Rendering ${type} chart.`);
|
||||
this.super.socket.send("rechartVisualize", {
|
||||
type,
|
||||
dataset,
|
||||
title,
|
||||
});
|
||||
|
||||
this.super._replySpecialAttributes = {
|
||||
saveAsType: "rechartVisualize",
|
||||
storedResponse: (additionalText = "") =>
|
||||
JSON.stringify({
|
||||
type,
|
||||
dataset,
|
||||
title,
|
||||
caption: additionalText,
|
||||
}),
|
||||
postSave: () => this.tracker.removeUniqueConstraint(this.name),
|
||||
};
|
||||
|
||||
this.tracker.markUnique(this.name);
|
||||
return "The chart was generated and returned to the user. This function completed successfully. Do not make another chart.";
|
||||
} catch (error) {
|
||||
this.super.handlerProps.log(
|
||||
`create-chart raised an error. ${error.message}`
|
||||
);
|
||||
return `Let the user know this action was not successful. An error was raised while generating the chart. ${error.message}`;
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
rechart,
|
||||
};
|
@ -9,10 +9,17 @@
|
||||
// ... do random # of times.
|
||||
// We want to block all the reruns of a plugin, so we can add this to prevent that behavior from
|
||||
// spamming the user (or other costly function) that have the exact same signatures.
|
||||
|
||||
// Track Run/isDuplicate prevents _exact_ data re-runs based on the SHA of their inputs
|
||||
// StartCooldown/isOnCooldown does prevention of _near-duplicate_ runs based on only the function name that is running.
|
||||
// isUnique/markUnique/removeUniqueConstraint prevents one-time functions from re-running. EG: charting.
|
||||
const crypto = require("crypto");
|
||||
const DEFAULT_COOLDOWN_MS = 5 * 1000;
|
||||
|
||||
class Deduplicator {
|
||||
#hashes = {};
|
||||
#cooldowns = {};
|
||||
#uniques = {};
|
||||
constructor() {}
|
||||
|
||||
trackRun(key, params = {}) {
|
||||
@ -30,6 +37,32 @@ class Deduplicator {
|
||||
.digest("hex");
|
||||
return this.#hashes.hasOwnProperty(newSig);
|
||||
}
|
||||
|
||||
startCooldown(
|
||||
key,
|
||||
parameters = {
|
||||
cooldownInMs: DEFAULT_COOLDOWN_MS,
|
||||
}
|
||||
) {
|
||||
this.#cooldowns[key] = Number(new Date()) + Number(parameters.cooldownInMs);
|
||||
}
|
||||
|
||||
isOnCooldown(key) {
|
||||
if (!this.#cooldowns.hasOwnProperty(key)) return false;
|
||||
return Number(new Date()) <= this.#cooldowns[key];
|
||||
}
|
||||
|
||||
isUnique(key) {
|
||||
return !this.#uniques.hasOwnProperty(key);
|
||||
}
|
||||
|
||||
removeUniqueConstraint(key) {
|
||||
delete this.#uniques[key];
|
||||
}
|
||||
|
||||
markUnique(key) {
|
||||
this.#uniques[key] = Number(new Date());
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.Deduplicator = Deduplicator;
|
||||
|
@ -123,6 +123,7 @@ function convertToChatHistory(history = []) {
|
||||
sentAt: moment(createdAt).unix(),
|
||||
},
|
||||
{
|
||||
type: data?.type || "chart",
|
||||
role: "assistant",
|
||||
content: data.text,
|
||||
sources: data.sources || [],
|
||||
|
Loading…
Reference in New Issue
Block a user